SDK API Mode
The Stratos SDK supports two transport modes: iframe (default, for dock apps) and api (for bots, scripts, and server-side integrations).
Setup
bash
npm install @stratos-wallet/sdktypescript
import { StratosSDK } from '@stratos-wallet/sdk';
const sdk = new StratosSDK({
mode: 'api',
baseUrl: 'https://your-portal.example.com',
apiKey: 'cws_...',
apiSecret: '...',
});Authentication
API mode requires two credentials:
| Header | Purpose |
|---|---|
X-API-Key | Identity — cws_ prefixed, hash stored in DB |
X-API-Secret | Decryption — hex-encoded 32-byte secret, never stored on server |
Both are generated during the "Enable API Access" flow when adding a passkey.
Security: The server never sees your cleartext private keys. Keys are encrypted client-side with your API secret before being stored. The server decrypts them only when you provide the secret in each request.
Creating an API Key
- Open Settings in the wallet
- Click "Add Passkey"
- Check "Enable API Access (SDK signing)"
- Complete the passkey registration
- Save both the API Key and API Secret — they are shown once
Endpoints
Read Operations
typescript
// Get wallet addresses for all chains
const addresses = await sdk.getAddresses();
// Get Canton CC and token balances
const balance = await sdk.getBalance('CC');
// Get transaction history
const txs = await sdk.getTransactions();Transfers
typescript
// Canton CC transfer
await sdk.transfer({
to: 'recipient-party-id',
amount: '10.5',
symbol: 'CC',
chain: 'canton'
});
// Canton USDC transfer
await sdk.transfer({
to: 'recipient-party-id',
amount: '100',
symbol: 'USDC',
chain: 'canton'
});Transaction Signing
typescript
// Sign a message hash (secp256k1 chains: EVM, BTC, TRON)
const sig = await sdk.signMessage({
message: 'Hello World',
chain: 'evm'
});Canton Contract Operations
typescript
// Query contracts
const contracts = await sdk.cantonQuery({
templateId: 'package:Module:Template'
});
// Create a contract
const result = await sdk.cantonCreate({
templateId: 'package:Module:Template',
payload: { field1: 'value1' }
});
// Exercise a choice
const exerciseResult = await sdk.cantonExercise({
contractId: '#1:0',
templateId: 'package:Module:Template',
choice: 'Archive',
argument: {}
});REST API (curl)
If you're not using the SDK, you can call the endpoints directly:
bash
# Get addresses
curl -H "X-API-Key: cws_..." -H "X-API-Secret: ..." \
https://portal.example.com/api/sdk/addresses
# Transfer CC
curl -X POST \
-H "X-API-Key: cws_..." -H "X-API-Secret: ..." \
-H "Content-Type: application/json" \
-d '{"to":"party-id","amount":10,"symbol":"CC"}' \
https://portal.example.com/api/sdk/transfer
# Sign a message
curl -X POST \
-H "X-API-Key: cws_..." -H "X-API-Secret: ..." \
-H "Content-Type: application/json" \
-d '{"chainType":"evm","message":"Hello"}' \
https://portal.example.com/api/sdk/sign
# Canton query
curl -X POST \
-H "X-API-Key: cws_..." -H "X-API-Secret: ..." \
-H "Content-Type: application/json" \
-d '{"templateId":"pkg:Module:Template"}' \
https://portal.example.com/api/sdk/canton/queryEndpoint Reference
| Endpoint | Method | Description |
|---|---|---|
/api/sdk/addresses | GET | Wallet addresses (all chains) |
/api/sdk/balance | GET | Canton CC and token balances |
/api/sdk/transactions | GET | Transaction history |
/api/sdk/transfer | POST | Transfer tokens |
/api/sdk/sign | POST | Sign message or transaction |
/api/sdk/canton/query | POST | Query Daml contracts |
/api/sdk/canton/create | POST | Create Daml contract |
/api/sdk/canton/exercise | POST | Exercise Daml choice |
/api/sdk/keys | GET | List SDK API keys (session auth) |
/api/sdk/keys/:id | DELETE | Revoke SDK API key (session auth) |
Key Management
bash
# List your SDK keys (requires session auth, not API key)
curl -H "Authorization: Bearer SESSION_TOKEN" \
https://portal.example.com/api/sdk/keys
# Revoke a key
curl -X DELETE \
-H "Authorization: Bearer SESSION_TOKEN" \
https://portal.example.com/api/sdk/keys/KEY_IDScoping & Rate Limits
Each SDK API key can be scoped with:
- allowed_chains: restrict to specific chains (e.g.
["canton", "evm"]) - allowed_operations: restrict operation types (e.g.
["query"]for read-only) - spending_limits: per-chain daily spending caps
- rate_limit: requests per minute (default: 30)
Security Model
API Key (cws_xxx) → SHA-256 hash → lookup sdk_api_keys table
X-API-Secret (hex) → HKDF-SHA256 → AES-256-GCM key → decrypt wallet keys- Two credentials required: API key (identity) + API secret (decryption key)
- Server never stores cleartext keys: keys encrypted client-side before upload
- D1 database compromise insufficient: encrypted blobs need the API secret
- Immediate revocation: delete key → all encrypted copies cascade-deleted
