Quick Start

Prerequisites

  1. Register a WringCloud account and sign in to Open Platform App Management
  2. Create an app to obtain your AppKey and AppSecret
  3. Choose a transfer capability:
    • P2P Direct Transfer: peer-to-peer transfer without passing through servers, free under 2GB
    • Secure Relay: files are relayed and stored in the cloud, supporting offline transfer and multiple downloads; consumes your plan's credit quota
The two modes are used independently: P2P direct transfer and secure relay are two independent transfer modes; developers choose based on the scenario. The SDK does not fall back automatically — the corresponding API must be called separately for each mode.

Install the SDK

The WringCloud Open Platform provides the iceshuttle-js JavaScript SDK for browser environments, with signature authentication, WebRTC signaling, chunked upload/download and all other complex logic built in.

JS
iceshuttle-js

Browser SDK supporting both P2P direct transfer and secure relay

Try It Online

Including the SDK

JavaScript
// Option 1: local import (place the downloaded SDK file into your project)
import { IceShuttle, downloadBlob } from './sdk/iceshuttle.esm.js';

// Option 2: script tag from the official site (for projects without a build tool)
// Download: https://www.wringcloud.com/sdk/iceshuttle-js/dist/iceshuttle.min.js
<script src="./sdk/iceshuttle.min.js"></script>
<script>
  const { IceShuttle, downloadBlob } = window.IceShuttle;
</script>
File formats:
  • iceshuttle.min.js — minified, smallest size, for production (script tag)
  • iceshuttle.esm.js — ES Module format, readable, for development and debugging (import)
  • iceshuttle.umd.js — UMD format, works with both the script tag and import

Initialize the Client

Initialize the SDK client with your AppKey and AppSecret; the SDK handles signature authentication automatically.

JavaScript
import { IceShuttle } from 'iceshuttle-js';

const client = new IceShuttle({
  appKey: 'your-app-key',         // required: your app key
  appSecret: 'your-app-secret',   // required: your app secret
  serverDomain: 'https://www.wringcloud.com',  // optional: server domain
  debug: false                       // optional: enable debug logging
});

Initialization Parameters

ParameterTypeRequiredDescription
appKeystringRequiredYour app key, obtained from Open Platform App Management
appSecretstringRequiredYour app secret, obtained from Open Platform App Management
serverDomainstringOptionalServer domain, defaults to https://www.wringcloud.com
debugbooleanOptionalEnable debug logging, defaults to false

P2P Direct Transfer

P2P Direct Transfer: WebRTC-based peer-to-peer transfer with no server relay, free under 2GB. The sender must keep the page open; the receiver gets the files directly via the link — the same experience as the WringCloud homepage.

Transfer Flow

1
Create a Send Task
Call createP2PSender
2
Get the Receive Link
Share it with the receiver
3
Send the File
Call sendFile
4
Receiver Accepts
Receive the files via the link

Sending Files

JavaScript
// 1. Create a P2P send task
const sender = await client.createP2PSender({
  fileName: file.name,             // required: file name
  fileSize: file.size,             // required: file size (bytes)
  password: 'optional-password',            // optional: transfer password
  maxReceiveCount: 1              // optional: max receive count
});

// 2. Get the receive link and share it with the receiver
const receiveLink = sender.getReceiveLink();
console.log('Receive link:', receiveLink);

// 3. Send the file (the SDK handles the transfer automatically)
await sender.sendFile(file, {
  onProgress: (percent) => {
    console.log(`Transfer progress: ${percent.toFixed(1)}%`);
  },
  onComplete: (info) => {
    console.log('Transfer complete', info);
  },
  onError: (err) => {
    console.error('Transfer failed:', err);
  },
  onProcessing: (info) => {
    console.log(info.message); // e.g. "Verifying file..."
  }
});

// 4. Cancel the transfer (optional)
await sender.cancel();

createP2PSender Parameters

ParameterTypeRequiredDescription
fileNamestringRequiredFile name
fileSizenumberRequiredFile size (bytes)
passwordstringOptionalTransfer password
maxReceiveCountnumberOptionalMax receive count

sendFile Callbacks

CallbackParametersDescription
onProgresspercent: numberTransfer progress percentage (0-100)
onCompleteinfo: {fileName, fileSize}Transfer completed
onErrorerr: stringTransfer error
onProcessinginfo: {message}Processing status (e.g. verifying the file)

P2PSender Methods

MethodReturnsDescription
getReceiveLink()stringGet the receive link to share with the receiver
sendFile(file, callbacks)PromiseSend the file (automatic)
cancel()PromiseCancel the transfer

Receiving Files

The receiver accepts the file using the transferId and token from the link.

JavaScript
// Parse transferId and token from the receive link
const receiver = await client.createP2PReceiver(transferId, token);

// Get file info
console.log('File name:', receiver.getFileName());

// Receive the file
await receiver.receiveFile({
  onProgress: (percent) => {
    console.log(`Receive progress: ${percent.toFixed(1)}%`);
  },
  onComplete: ({ blob, fileName, fileSize }) => {
    // Trigger the browser download
    downloadBlob(blob, fileName);
  },
  onError: (err) => {
    console.error('Receive failed:', err);
  }
});

createP2PReceiver Parameters

ParameterTypeRequiredDescription
transferIdstringRequiredTransfer ID, obtained from the receive link
tokenstringRequiredReceive token, obtained from the receive link

P2PReceiver Methods

MethodReturnsDescription
getFileName()stringGet the file name
receiveFile(callbacks)PromiseReceive the file; onComplete receives {blob, fileName, fileSize}

Secure Relay

Secure Relay: files are relayed and stored via the WringCloud cloud, supporting offline transfer and multiple downloads; consumes your plan's credit quota. The sender can close the page as soon as the upload completes, and the receiver can download at any time.

Transfer Flow

1
Create a Relay Task
Call createRelaySender
2
Get the Download Link
Share it with the receiver
3
Upload the File
Call sendFile
4
Receiver Downloads
Download the file via the link

Sending Files

JavaScript
// 1. Create a secure relay task
const sender = await client.createRelaySender({
  fileName: file.name,             // required: file name
  fileSize: file.size,             // required: file size (bytes)
  password: 'optional-password',            // optional: transfer password
  maxReceiveCount: 5,             // optional: max download count
  expireHours: 168               // optional: link validity (hours)
});

// 2. Get the download link and share it with the receiver
const downloadLink = sender.getDownloadLink();
console.log('Download link:', downloadLink);

// 3. Upload the file (the SDK handles chunked upload automatically)
await sender.sendFile(file, {
  onProgress: (percent) => {
    console.log(`Upload progress: ${percent.toFixed(1)}%`);
  },
  onComplete: (info) => {
    console.log('Upload complete, waiting for the receiver to download');
  },
  onError: (err) => {
    console.error('Upload failed:', err);
  }
});

// 4. Cancel the transfer (optional)
await sender.cancel();

createRelaySender Parameters

ParameterTypeRequiredDescription
fileNamestringRequiredFile name
fileSizenumberRequiredFile size (bytes)
passwordstringOptionalTransfer password
maxReceiveCountnumberOptionalMax download count
expireHoursnumberOptionalLink validity (hours)

RelaySender Methods

MethodReturnsDescription
getDownloadLink()stringGet the download link to share with the receiver
sendFile(file, callbacks)PromiseUpload the file; the SDK handles chunking automatically
cancel()PromiseCancel the transfer

Receiving Files

The receiver downloads the file using the transferId and token from the link.

JavaScript
// Parse transferId and token from the download link
const receiver = await client.createRelayReceiver(transferId, token);

// Get file info
console.log('File name:', receiver.getFileName());

// Download the file as a Blob
const blob = await receiver.receiveFileAsBlob({
  onProgress: (percent) => {
    console.log(`Download progress: ${percent.toFixed(1)}%`);
  }
});

// Trigger the browser download
downloadBlob(blob, receiver.getFileName());

createRelayReceiver Parameters

ParameterTypeRequiredDescription
transferIdstringRequiredTransfer ID, obtained from the download link
tokenstringRequiredDownload token, obtained from the download link

RelayReceiver Methods

MethodReturnsDescription
getFileName()stringGet the file name
receiveFileAsBlob(callbacks)Promise<Blob>Download the file as a Blob

Common API

Query Transfer Status

JavaScript
// Query the P2P transfer status
const p2pStatus = await client.getP2PTransferStatus(transferId);

// Query the secure relay transfer status
const relayStatus = await client.getRelayTransferStatus(transferId);

Cancel a Transfer

JavaScript
// Cancel a P2P transfer
await client.cancelP2PTransfer(transferId);

// Cancel a secure relay transfer
await client.cancelRelayTransfer(transferId);

// or simply call sender.cancel()
await sender.cancel();

Download Helper

The SDK provides the downloadBlob utility to trigger browser file downloads.

JavaScript
import { downloadBlob } from 'iceshuttle-js';

// Trigger the browser download
downloadBlob(blob, 'filename.txt');

Error Codes

Error CodeDescription
200Success
400Invalid parameters
401Invalid signature or expired timestamp
403Insufficient entitlements or free-plan user
404Transfer task not found
410Transfer expired or receive count exhausted
413File size limit exceeded (single file ≤2GB per paid transfer, or the plan's remaining credit quota is insufficient)
429Rate limited or credit quota exceeded
500Server error

FAQ

P2P or secure relay — how to choose?

  • P2P Direct Transfer: sender and receiver online at the same time, files under 2GB, prioritizing speed and zero cost
  • Secure Relay: the receiver may be offline, multiple downloads needed, larger files, with plan credit pool entitlements

What if I lose my AppSecret?

On the App Management page, click "Reset Secret" to get a new AppSecret. The old secret becomes invalid immediately.

Does the SDK support automatic fallback?

The SDK does not fall back automatically. P2P direct transfer and secure relay are two independent transfer modes — call createP2PSender or createRelaySender respectively. Developers can implement their own fallback logic based on the business scenario.

Are there API rate limits?

100 requests per minute per app by default. For higher quotas, contact the platform.

How do I get transferId and token from the receive link?

JavaScript
// P2P receive link format: https://www.wringcloud.com/p2p/{transferId}?token={token}
// Secure relay download link format: https://www.wringcloud.com/r/{transferId}?token={token}

function parseLink(link) {
  const url = new URL(link);
  const transferId = url.pathname.split('/').pop();
  const token = url.searchParams.get('token');
  return { transferId, token };
}

Online Demo

We provide a complete demo page covering all the interaction logic for P2P direct transfer, secure relay, and file receiving — developers can customize their own UI based on this demo.

Demo
Live Demo

Full interactive UI — try P2P direct transfer and secure relay right away

Open Demo
DL
Demo Source

Download the demo page source to run locally or integrate into your project

Run the demo locally:
  1. Download demo/index.html and dist/iceshuttle.esm.js
  2. Keep the relative path relationship (the demo and dist directories at the same level)
  3. Open index.html directly in a browser to run it

Full Example Code

JavaScript
import { IceShuttle, downloadBlob } from 'iceshuttle-js';

// Initialize
const client = new IceShuttle({
  appKey: 'your-app-key',
  appSecret: 'your-app-secret'
});

// ===== P2P Direct Transfer =====
async function p2pSend(file) {
  const sender = await client.createP2PSender({
    fileName: file.name,
    fileSize: file.size
  });
  console.log('Receive link:', sender.getReceiveLink());
  await sender.sendFile(file, {
    onProgress: (p) => console.log(p + '%'),
    onComplete: () => console.log('Done')
  });
}

async function p2pReceive(transferId, token) {
  const receiver = await client.createP2PReceiver(transferId, token);
  await receiver.receiveFile({
    onProgress: (p) => console.log(p + '%'),
    onComplete: ({ blob, fileName }) => downloadBlob(blob, fileName)
  });
}

// ===== Secure Relay =====
async function relaySend(file) {
  const sender = await client.createRelaySender({
    fileName: file.name,
    fileSize: file.size
  });
  console.log('Download link:', sender.getDownloadLink());
  await sender.sendFile(file, {
    onProgress: (p) => console.log(p + '%'),
    onComplete: () => console.log('Upload complete')
  });
}

async function relayReceive(transferId, token) {
  const receiver = await client.createRelayReceiver(transferId, token);
  const blob = await receiver.receiveFileAsBlob({
    onProgress: (p) => console.log(p + '%')
  });
  downloadBlob(blob, receiver.getFileName());
}