Quick Start
Prerequisites
- Register a WringCloud account and sign in to Open Platform App Management
- Create an app to obtain your
AppKeyandAppSecret - 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
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.
Browser SDK supporting both P2P direct transfer and secure relay
Including the SDK
// 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>
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.
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
| Parameter | Type | Required | Description |
|---|---|---|---|
appKey | string | Required | Your app key, obtained from Open Platform App Management |
appSecret | string | Required | Your app secret, obtained from Open Platform App Management |
serverDomain | string | Optional | Server domain, defaults to https://www.wringcloud.com |
debug | boolean | Optional | Enable debug logging, defaults to false |
P2P Direct Transfer
Transfer Flow
Sending Files
// 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
| Parameter | Type | Required | Description |
|---|---|---|---|
fileName | string | Required | File name |
fileSize | number | Required | File size (bytes) |
password | string | Optional | Transfer password |
maxReceiveCount | number | Optional | Max receive count |
sendFile Callbacks
| Callback | Parameters | Description |
|---|---|---|
onProgress | percent: number | Transfer progress percentage (0-100) |
onComplete | info: {fileName, fileSize} | Transfer completed |
onError | err: string | Transfer error |
onProcessing | info: {message} | Processing status (e.g. verifying the file) |
P2PSender Methods
| Method | Returns | Description |
|---|---|---|
getReceiveLink() | string | Get the receive link to share with the receiver |
sendFile(file, callbacks) | Promise | Send the file (automatic) |
cancel() | Promise | Cancel the transfer |
Receiving Files
The receiver accepts the file using the transferId and token from the link.
// 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
| Parameter | Type | Required | Description |
|---|---|---|---|
transferId | string | Required | Transfer ID, obtained from the receive link |
token | string | Required | Receive token, obtained from the receive link |
P2PReceiver Methods
| Method | Returns | Description |
|---|---|---|
getFileName() | string | Get the file name |
receiveFile(callbacks) | Promise | Receive the file; onComplete receives {blob, fileName, fileSize} |
Secure Relay
Transfer Flow
Sending Files
// 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
| Parameter | Type | Required | Description |
|---|---|---|---|
fileName | string | Required | File name |
fileSize | number | Required | File size (bytes) |
password | string | Optional | Transfer password |
maxReceiveCount | number | Optional | Max download count |
expireHours | number | Optional | Link validity (hours) |
RelaySender Methods
| Method | Returns | Description |
|---|---|---|
getDownloadLink() | string | Get the download link to share with the receiver |
sendFile(file, callbacks) | Promise | Upload the file; the SDK handles chunking automatically |
cancel() | Promise | Cancel the transfer |
Receiving Files
The receiver downloads the file using the transferId and token from the link.
// 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
| Parameter | Type | Required | Description |
|---|---|---|---|
transferId | string | Required | Transfer ID, obtained from the download link |
token | string | Required | Download token, obtained from the download link |
RelayReceiver Methods
| Method | Returns | Description |
|---|---|---|
getFileName() | string | Get the file name |
receiveFileAsBlob(callbacks) | Promise<Blob> | Download the file as a Blob |
Common API
Query Transfer Status
// 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
// 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.
import { downloadBlob } from 'iceshuttle-js'; // Trigger the browser download downloadBlob(blob, 'filename.txt');
Error Codes
| Error Code | Description |
|---|---|
| 200 | Success |
| 400 | Invalid parameters |
| 401 | Invalid signature or expired timestamp |
| 403 | Insufficient entitlements or free-plan user |
| 404 | Transfer task not found |
| 410 | Transfer expired or receive count exhausted |
| 413 | File size limit exceeded (single file ≤2GB per paid transfer, or the plan's remaining credit quota is insufficient) |
| 429 | Rate limited or credit quota exceeded |
| 500 | Server 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?
// 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.
Download the demo page source to run locally or integrate into your project
- Download
demo/index.htmlanddist/iceshuttle.esm.js - Keep the relative path relationship (the demo and dist directories at the same level)
- Open index.html directly in a browser to run it
Full Example Code
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()); }