TypeScript SDK
The official TypeScript SDK provides typed methods for all OpenTusk API operations. Zero external dependencies — uses native fetch. The SDK also powers the MCP server under the hood — every MCP tool call maps to an SDK method.
Installation
Section titled “Installation”npm install @opentusk/sdkInitialization
Section titled “Initialization”import { OpenTuskClient } from '@opentusk/sdk';
const opentusk = new OpenTuskClient({ apiKey: 'otk_your_key',});For local development, override the base URL:
const opentusk = new OpenTuskClient({ apiKey: 'otk_your_key', baseUrl: 'http://localhost:8000',});Configuration options
Section titled “Configuration options”const opentusk = new OpenTuskClient({ apiKey: 'otk_...', baseUrl: 'http://localhost:8000', // Override API URL headers: { 'X-Custom': 'value' }, // Extra headers on every request fetch: customFetchFn, // Custom fetch implementation});Namespaces
Section titled “Namespaces”| Namespace | Description |
|---|---|
opentusk.vaults | Create, list, update, delete vaults |
opentusk.files | Upload, download, list, delete files |
opentusk.webhooks | Manage webhook endpoints and deliveries |
opentusk.public | Access public vaults and files (no auth) |
opentusk.account | Get account info |
opentusk.apiKeys | Create, list, revoke API keys |
opentusk.trash | List, restore, delete, empty trash |
opentusk.sharedVaults | Shared vault membership and Sui address linking |
opentusk.folders | Create, list, get contents, update, delete folders |
Vaults
Section titled “Vaults”// Createconst vault = await opentusk.vaults.create({ name: 'My Vault', visibility: 'public',});
// List allconst vaults = await opentusk.vaults.list();
// Updateawait opentusk.vaults.update(vault.id, { name: 'Renamed' });
// Delete (force moves files to trash first)await opentusk.vaults.delete(vault.id, { force: true });Shared vaults
Section titled “Shared vaults”// Link your Sui address to your account (required once)await opentusk.sharedVaults.linkSuiAddress('0x1234...abcd');
// Create a shared vaultconst vault = await opentusk.vaults.create({ name: 'Team Vault', visibility: 'shared',});
// Grant access to another user by their Sui addressconst { member } = await opentusk.sharedVaults.addMember(vault.id, { suiAddress: '0x5678...efgh',});
// List all membersconst { members } = await opentusk.sharedVaults.listMembers(vault.id);
// Revoke accessawait opentusk.sharedVaults.removeMember(vault.id, member.id);
// List shared vaults you've been granted access toconst { vaults } = await opentusk.sharedVaults.list();
// Unlink your Sui addressawait opentusk.sharedVaults.unlinkSuiAddress();File upload
Section titled “File upload”One-liner
Section titled “One-liner”import { readFile } from 'fs/promises';
const data = await readFile('./photo.jpg');const file = await opentusk.files.upload({ name: 'photo.jpg', mimeType: 'image/jpeg', vaultId: vault.id, data,});Manual 3-step
Section titled “Manual 3-step”// 1. Get presigned URLconst { fileId, uploadUrl } = await opentusk.files.requestUpload({ name: 'doc.pdf', mimeType: 'application/pdf', sizeBytes: buffer.byteLength, vaultId: vault.id,});
// 2. PUT to presigned URLawait fetch(uploadUrl, { method: 'PUT', body: buffer, headers: { 'Content-Type': 'application/pdf' },});
// 3. Confirmconst file = await opentusk.files.confirmUpload(fileId);Pay-per-upload (any plan)
Section titled “Pay-per-upload (any plan)”Pass paymentType: 'ppu' to bill this single upload in WAL on Sui, independent of the account’s subscription. The SDK returns a PaymentRequired (HTTP 402) on the first call; sign a WAL transfer, then retry with quoteId + txDigest. See Upload & lifecycle — 402 payment flow for the full pattern.
const result = await opentusk.files.requestUpload({ name: 'doc.pdf', mimeType: 'application/pdf', sizeBytes: buffer.byteLength, vaultId: vault.id, paymentType: 'ppu', // opt this upload into PPU (any plan) epochs: 30, // optional; defaults to plan's ppuMinEpochs});Download
Section titled “Download”const { downloadUrl, encryption } = await opentusk.files.getDownloadUrl(file.id);
const response = await fetch(downloadUrl);const bytes = await response.arrayBuffer();// If encrypted, decrypt client-side using encryption.wrappedKey and encryption.ivPolling for Walrus sync
Section titled “Polling for Walrus sync”Wait for a file to reach a specific status:
// Promise-based — resolves when status is reachedconst synced = await opentusk.files.waitForStatus(file.id, ['synced'], { interval: 3000, // poll every 3s (default: 2s) timeout: 120000, // give up after 2min (default: 60s)});Or use the async iterator for progress updates:
for await (const status of opentusk.files.pollStatus(file.id, ['synced'])) { console.log(`Current status: ${status.status}`);}Folders
Section titled “Folders”// Createconst folder = await opentusk.folders.create({ vaultId: vault.id, name: 'Documents',});
// Listconst folders = await opentusk.folders.list({ vaultId: vault.id });
// Get contents (files + subfolders)const contents = await opentusk.folders.getContents(folder.id);
// Renameawait opentusk.folders.update(folder.id, { name: 'Renamed' });
// Deleteawait opentusk.folders.delete(folder.id);Webhooks
Section titled “Webhooks”// Createconst webhook = await opentusk.webhooks.create({ url: 'https://example.com/webhook', events: ['file.synced', 'file.error'],});console.log(webhook.secret); // Save this — only shown once
// Testawait opentusk.webhooks.test(webhook.id);
// List deliveriesconst deliveries = await opentusk.webhooks.listDeliveries(webhook.id, { limit: 10,});// List trashed itemsconst items = await opentusk.trash.list();
// Restoreawait opentusk.trash.restore(itemId);
// Permanently delete oneawait opentusk.trash.delete(itemId);
// Empty all trashawait opentusk.trash.empty();Public access
Section titled “Public access”Public methods don’t require authentication:
// Build public URLs (synchronous, no API call)const fileUrl = opentusk.public.getFileUrl(fileId);const blobUrl = opentusk.public.getBlobUrl(walrusBlobId);
// List files in a public vaultconst { vault, files } = await opentusk.public.listVaultFiles(userId, 'my-vault');Error handling
Section titled “Error handling”import { OpenTuskError, OpenTuskTimeoutError } from '@opentusk/sdk';
try { await opentusk.vaults.get('non-existent');} catch (err) { if (err instanceof OpenTuskError) { console.error(err.statusCode, err.message); } if (err instanceof OpenTuskTimeoutError) { console.error('Polling timed out'); }} MCP tools Every MCP tool maps to an SDK method.
Upload & file lifecycle How the 3-step upload process works.