@temple-digital-group/temple-canton-js 1.0.40 → 2.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Temple Canton JS
2
2
 
3
- JavaScript SDK for interacting with the Temple Canton blockchain exchange. Supports CC, USDCx, and CBTC tokens on the Canton network.
3
+ JavaScript SDK for interacting with the Temple Canton blockchain exchange. Supports Amulet (CC), USDCx, and CBTC tokens on the Canton network.
4
4
 
5
5
  ## Installation
6
6
 
@@ -12,73 +12,6 @@ npm install @temple-digital-group/temple-canton-js
12
12
 
13
13
  Call `initialize()` before using any SDK functions. It sets up the config and optionally authenticates with the Temple REST API.
14
14
 
15
- ### Custom Validator
16
-
17
- For apps connecting to your own validator (browser or server-side):
18
-
19
- ```javascript
20
- import { initialize } from "@temple-digital-group/temple-canton-js";
21
-
22
- await initialize({
23
- NETWORK: "mainnet",
24
- VALIDATOR_API_URL: "https://your-validator-url",
25
- VALIDATOR_SCAN_API_URL: "https://your-scan-api-url",
26
- VALIDATOR_USER_PARTY_ID: "your-user-party-id",
27
- AUTH0_TOKEN_URL: "https://your-auth0-domain/oauth/token",
28
- AUTH0_USER_ID: "your-auth0-user-id",
29
- AUTH0_CLIENT_ID: "your-client-id",
30
- AUTH0_CLIENT_SECRET: "your-client-secret",
31
- AUTH0_AUDIENCE: "your-audience",
32
- });
33
- ```
34
-
35
- ### Custom Validator + REST API
36
-
37
- To also authenticate with the Temple REST API at init time, pass `API_EMAIL`/`API_PASSWORD`:
38
-
39
- ```javascript
40
- import { initialize } from "@temple-digital-group/temple-canton-js";
41
-
42
- await initialize({
43
- NETWORK: "mainnet",
44
- VALIDATOR_API_URL: "https://your-validator-url",
45
- VALIDATOR_SCAN_API_URL: "https://your-scan-api-url",
46
- VALIDATOR_USER_PARTY_ID: "your-user-party-id",
47
- AUTH0_TOKEN_URL: "https://your-auth0-domain/oauth/token",
48
- AUTH0_USER_ID: "your-auth0-user-id",
49
- AUTH0_CLIENT_ID: "your-client-id",
50
- AUTH0_CLIENT_SECRET: "your-client-secret",
51
- AUTH0_AUDIENCE: "your-audience",
52
- API_EMAIL: "user@example.com", // REST API login (optional)
53
- API_PASSWORD: "password",
54
- });
55
- ```
56
-
57
- | Key | Required | Description |
58
- | ------------------------- | -------- | ---------------------------------------------------- |
59
- | `NETWORK` | Yes | `mainnet`, `testnet`, or `localhost` |
60
- | `VALIDATOR_API_URL` | Yes | Base URL of the Canton validator ledger API |
61
- | `VALIDATOR_SCAN_API_URL` | Yes | Base URL of the Canton Scan API |
62
- | `VALIDATOR_USER_PARTY_ID` | Yes | The user's party ID on the network |
63
- | `JWT_TOKEN` | Yes\* | Pre-authenticated JWT token for ledger API calls |
64
- | `AUTH0_TOKEN_URL` | Yes\* | Auth0 OAuth token endpoint |
65
- | `AUTH0_CLIENT_ID` | Yes\* | Auth0 application client ID |
66
- | `AUTH0_CLIENT_SECRET` | Yes\* | Auth0 application client secret |
67
- | `AUTH0_AUDIENCE` | Yes\* | Auth0 API audience identifier |
68
- | `AUTH0_USER_ID` | Yes\* | Auth0 user ID for the service account |
69
- | `API_EMAIL` | No | Temple REST API email (triggers login at init) |
70
- | `API_PASSWORD` | No | Temple REST API password (required with `API_EMAIL`) |
71
-
72
- \* Provide either `JWT_TOKEN` (browser) or the `AUTH0_*` fields (server-side). The SDK fetches and caches JWT tokens automatically when Auth0 credentials are provided.
73
-
74
- To update the JWT token later without re-initializing:
75
-
76
- ```javascript
77
- import { setJWTToken } from "@temple-digital-group/temple-canton-js";
78
-
79
- setJWTToken(newToken);
80
- ```
81
-
82
15
  ### Wallet Adapter
83
16
 
84
17
  For apps using Loop Wallet. Pass the Loop SDK instance as `WALLET_ADAPTER` — the SDK auto-detects server vs client mode.
@@ -87,18 +20,13 @@ For apps using Loop Wallet. Pass the Loop SDK instance as `WALLET_ADAPTER` — t
87
20
  - **Client-side:** uses `loop.provider.submitTransaction()` (delegates signing to Loop Wallet via WebSocket)
88
21
 
89
22
  ```javascript
90
- import { initialize, createOrderProposal } from "@temple-digital-group/temple-canton-js";
23
+ import { initialize } from "@temple-digital-group/temple-canton-js";
91
24
 
92
- await initialize({
25
+ initialize({
26
+ API_KEY: "your-api-key",
93
27
  NETWORK: "mainnet",
94
28
  WALLET_ADAPTER: loop, // Pass the Loop SDK instance
95
29
  });
96
-
97
- // Auto-submit: SDK handles signing and submission
98
- const result = await createOrderProposal(orderArgs);
99
-
100
- // Or get the raw command back for manual submission
101
- const command = await createOrderProposal(orderArgs, true);
102
30
  ```
103
31
 
104
32
  You can also set or change the wallet adapter after init:
@@ -111,12 +39,9 @@ setWalletAdapter(loop);
111
39
 
112
40
  | Key | Required | Description |
113
41
  | ---------------- | -------- | --------------------------------------------------------------- |
114
- | `NETWORK` | Yes | `mainnet`, `testnet`, or `localhost` |
115
- | `WALLET_ADAPTER` | No | Loop SDK instance — auto-detects server/client mode for signing |
116
-
117
- > You can optionally pass `API_EMAIL`/`API_PASSWORD` to any `initialize()` call to also authenticate with the REST API at init time.
118
-
119
- > **Legacy:** `initializeConfig()` is still available as a sync-only alternative (no REST API auth). `initialize()` is the recommended approach.
42
+ | `API_KEY` | Yes | Temple REST API key |
43
+ | `NETWORK` | Yes | `mainnet` or `testnet` |
44
+ | `WALLET_ADAPTER` | Yes | Loop SDK instance — auto-detects server/client mode for signing |
120
45
 
121
46
  ## Supported Instruments
122
47
 
@@ -126,128 +51,184 @@ setWalletAdapter(loop);
126
51
  | USDCx | Utility | testnet, mainnet |
127
52
  | CBTC | Utility | testnet, mainnet |
128
53
 
54
+ > **Symbol normalization:** Use `CC` for Canton Coin in all SDK methods. The SDK handles the internal conversion to `Amulet` where required by the ledger. The `Amulet` symbol is deprecated — all API responses now return `CC`.
55
+
129
56
  ## Supported Trading Pairs
130
57
 
131
58
  - `CC/USDCx`
132
59
  - `CBTC/USDCx`
133
60
 
134
- ## Usage
61
+ ## v2 Trading Flow
135
62
 
136
- ### Get User Balances
63
+ The v2 flow covers the full trading lifecycle: onboarding, deposits, trading, and withdrawals.
137
64
 
138
- ```javascript
139
- import { getUserBalances } from "@temple-digital-group/temple-canton-js";
65
+ ```
66
+ 1. Check onboarding → isUserOnboarded(party)
67
+ If NOT onboarded → onboardUser(party)
140
68
 
141
- // Both params are optional — falls back to wallet adapter / config
142
- const balances = await getUserBalances();
69
+ 2. Deposit funds → deposit(amount, symbol)
143
70
 
144
- // Or pass explicitly
145
- const balances = await getUserBalances(partyId);
146
- const balances = await getUserBalances(partyId, walletProvider);
71
+ 3. Check balance → getTradingBalance()
72
+
73
+ 4. Place orders → createOrderRequest({ symbol, side, quantity, price, ... })
74
+
75
+ 5. Cancel orders → cancelOrder(orderId) or cancelAllOrders({ symbol })
76
+
77
+ 6. Withdraw funds → withdrawFunds({ asset_id, amount })
78
+
79
+ 7. Withdraw delegation → withdrawDelegation(delegationId, user)
147
80
  ```
148
81
 
149
- Each entry in the returned array contains:
82
+ ### 1. Onboarding
83
+
84
+ Check if a user has a delegation contract, and create one if not:
150
85
 
151
86
  ```javascript
152
- {
153
- asset: 'USDCx', // Catalog symbol
154
- total_balance: 170.5, // Unlocked + locked combined
155
- available_balance: 150.5, // Unlocked balance (usable for orders)
156
- locked_balance: 20.0, // Locked balance
157
- dso: null, // DSO party (CC only)
158
- registrar: '...', // Registrar party (utility tokens)
159
- operator: '...', // Operator party
160
- provider: '...', // Provider party
161
- merge_warning: true, // true if multiple unlocked holdings exist
162
- holdings: [...], // Unlocked holding contracts
163
- locked_holdings: [...], // Locked holding contracts
164
- utilityContext: { ... } // CIP-56 context (null when using wallet provider)
87
+ import { isUserOnboarded, onboardUser } from "@temple-digital-group/temple-canton-js";
88
+
89
+ const delegation = await isUserOnboarded(party);
90
+ if (!delegation) {
91
+ const result = await onboardUser({ partyId: party });
92
+ // result.delegation the confirmed delegation contract
93
+ // result.warning — set if onboarding was submitted but not confirmed within 60s
165
94
  }
166
95
  ```
167
96
 
168
- > **Note:** `utilityContext` is only resolved when using a custom validator (ledger API access). When using a wallet provider, it will be `null`.
97
+ `onboardUser` submits the onboarding request and then polls `isUserOnboarded` every 5 seconds for up to 60 seconds. It returns once the delegation is confirmed, or with a `warning` field if the timeout is reached.
169
98
 
170
- ### Create an Order
99
+ ### 2. Deposit Funds
100
+
101
+ The simplest way to deposit is the `deposit()` helper — pass the amount and symbol, and it handles everything:
171
102
 
172
103
  ```javascript
173
- import { createOrderProposal } from "@temple-digital-group/temple-canton-js";
104
+ import { deposit } from "@temple-digital-group/temple-canton-js";
174
105
 
175
- const result = await createOrderProposal({
176
- party: partyId,
177
- symbol: "CC/USDCx",
178
- side: "Buy",
179
- quantity: "100",
180
- pricePerUnit: "1.5",
181
- expiration: new Date(Date.now() + 3600000).toISOString(),
182
- userId: auth0UserId, // Optional if authenticated via REST API — auto-resolved from login
183
- orderType: "limit",
184
- });
106
+ const result = await deposit(100, "USDCx");
107
+ // or
108
+ const result = await deposit(10, "CC");
185
109
  ```
186
110
 
187
- #### Handling Stale Holdings (Wallet Provider)
111
+ `deposit()` requires the wallet adapter to be connected. It:
112
+ 1. Checks your CC balance to ensure at least 10 CC is reserved for transaction fees
113
+ 2. For utility deposits (USDCx, CBTC), verifies you have enough of the token **and** 10 CC for fees
114
+ 3. Selects the right UTXOs from your wallet
115
+ 4. Submits the deposit allocation
116
+
117
+ If you need more control, use `prepareDepositHoldings` + `depositFunds` directly:
188
118
 
189
- When a holding is used in an order, the contract is archived on-ledger and a new one is created. If the wallet provider hasn't caught up yet, it may still return the old (archived) holding, causing the next order to fail.
119
+ ```javascript
120
+ import { prepareDepositHoldings, depositFunds } from "@temple-digital-group/temple-canton-js";
190
121
 
191
- **Auto-submit (`returnCommand = false`):** The SDK handles this automatically. If a stale holding error is detected, it waits for the provider to sync and retries up to 3 times.
122
+ const depositOpts = await prepareDepositHoldings(100, "USDCx");
123
+ const result = await depositFunds(depositOpts);
124
+ ```
192
125
 
193
- **Manual submit (`returnCommand = true`):** You are responsible for handling stale holdings. `createOrderProposal` returns a `holdingContractId` — the contract ID of the holding that was selected. You can poll until it disappears from the provider's active contracts:
126
+ ### 3. Trading Balance
194
127
 
195
128
  ```javascript
196
- import { createOrderProposal, getAmuletHoldingsForParty } from "@temple-digital-group/temple-canton-js";
129
+ import { getTradingBalance } from "@temple-digital-group/temple-canton-js";
197
130
 
198
- const { command, holdingContractId } = await createOrderProposal(orderArgs, true);
199
- const result = await walletProvider.submitTransaction(command);
131
+ const balances = await getTradingBalance();
132
+ // Returns { balances: [{ asset, unlocked, locked, in_flight, ... }] }
133
+ ```
200
134
 
201
- // Poll until the provider catches up before creating next order
202
- async function waitForProviderSync(contractId, party, provider, interval = 500, maxAttempts = 20) {
203
- for (let i = 0; i < maxAttempts; i++) {
204
- const holdings = await getAmuletHoldingsForParty(party, false, provider);
205
- const stillActive = holdings?.some((h) => h.contractEntry?.JsActiveContract?.createdEvent?.contractId === contractId);
206
- if (!stillActive) return true; // Provider caught up
207
- await new Promise((r) => setTimeout(r, interval));
208
- }
209
- return false; // Timed out
210
- }
135
+ Use this to check available funds before placing orders or withdrawals.
211
136
 
212
- await waitForProviderSync(holdingContractId, party, walletProvider);
213
- // Safe to create next order
214
- ```
137
+ ### 4. Place Orders
215
138
 
216
- > `holdingContractId` is included in success responses, error responses, and `returnCommand` responses.
139
+ ```javascript
140
+ import { createOrderRequest } from "@temple-digital-group/temple-canton-js";
141
+
142
+ const result = await createOrderRequest({
143
+ symbol: "CC/USDCx",
144
+ side: "buy",
145
+ quantity: 10.5,
146
+ price: 1.25,
147
+ order_type: "limit",
148
+ });
217
149
 
218
- ### Get Orders and Proposals
150
+ // Post-only order (rejected if it would match immediately)
151
+ const postOnly = await createOrderRequest({
152
+ symbol: "CC/USDCx",
153
+ side: "buy",
154
+ quantity: 10.5,
155
+ price: 1.25,
156
+ order_type: "limit",
157
+ order_subtype: "post_only",
158
+ });
159
+ ```
160
+
161
+ ### 5. Cancel Orders
219
162
 
220
163
  ```javascript
221
- import { getOrdersForParty, getOrderProposalsForParty } from "@temple-digital-group/temple-canton-js";
164
+ import { cancelOrder, cancelAllOrders } from "@temple-digital-group/temple-canton-js";
165
+
166
+ // Cancel a specific order
167
+ await cancelOrder("ord_abc123");
222
168
 
223
- const orders = await getOrdersForParty(partyId);
224
- const proposals = await getOrderProposalsForParty(partyId);
169
+ // Cancel all orders for a symbol
170
+ await cancelAllOrders({ symbol: "CC/USDCx" });
171
+
172
+ // Cancel ALL orders
173
+ await cancelAllOrders();
225
174
  ```
226
175
 
227
- ### REST API (Optional) — Market Data and Orders
176
+ ### 6. Withdraw Funds
228
177
 
229
- The REST API functions are optional. If you pass `API_EMAIL`/`API_PASSWORD` in `initialize()`, the SDK authenticates at init time. You can also call `login()` directly.
178
+ Withdraws available (unlocked, non-in-flight) trading balance back to the user's wallet.
230
179
 
231
180
  ```javascript
232
- import { initialize, getTicker, getOrderBook, getActiveOrders, cancelOrder } from "@temple-digital-group/temple-canton-js";
181
+ import { withdrawFunds } from "@temple-digital-group/temple-canton-js";
233
182
 
234
- await initialize({
235
- NETWORK: "mainnet",
236
- API_EMAIL: "user@example.com",
237
- API_PASSWORD: "password",
183
+ const result = await withdrawFunds({
184
+ asset_id: "USDCx",
185
+ amount: "250.50",
238
186
  });
187
+ ```
188
+
189
+ ### 7. Withdraw Delegation
190
+
191
+ Archives the user's delegation contract. The user must re-onboard to trade again.
192
+
193
+ ```javascript
194
+ import { withdrawDelegation } from "@temple-digital-group/temple-canton-js";
195
+
196
+ // Auto-fetches delegation from API if not passed
197
+ await withdrawDelegation();
198
+
199
+ // Or pass explicitly
200
+ await withdrawDelegation(delegationContractId, partyId);
201
+ ```
239
202
 
240
- // Market data
241
- const ticker = await getTicker("CC/USDCx");
242
- const book = await getOrderBook("CC/USDCx", { levels: 10 });
203
+ ### Get User Balances
243
204
 
244
- // Orders
245
- const orders = await getActiveOrders({ symbol: "CC/USDCx" });
246
- const result = await cancelOrder("order-id-123");
205
+ ```javascript
206
+ import { getUserBalances } from "@temple-digital-group/temple-canton-js";
247
207
 
248
- // All functions return { error: true, status, code, message } on failure
249
- if (result.error) {
250
- console.log(`Failed: ${result.message}`);
208
+ // Both params are optional falls back to wallet adapter / config
209
+ const balances = await getUserBalances();
210
+
211
+ // Or pass explicitly
212
+ const balances = await getUserBalances(partyId);
213
+ const balances = await getUserBalances(partyId, walletProvider);
214
+ ```
215
+
216
+ Each entry in the returned array contains:
217
+
218
+ ```javascript
219
+ {
220
+ asset: 'USDCx',
221
+ total_balance: 170.5,
222
+ available_balance: 150.5,
223
+ locked_balance: 20.0,
224
+ dso: null,
225
+ registrar: '...',
226
+ operator: '...',
227
+ provider: '...',
228
+ merge_warning: true,
229
+ holdings: [...],
230
+ locked_holdings: [...],
231
+ utilityContext: { ... }
251
232
  }
252
233
  ```
253
234
 
@@ -256,7 +237,7 @@ if (result.error) {
256
237
  ```javascript
257
238
  import { mergeAmuletHoldingsForParty, mergeUtilityHoldingsForParty, getAmuletDisclosures, getUtxoCount } from "@temple-digital-group/temple-canton-js";
258
239
 
259
- // Custom Validator (server-side)
240
+ // Merge all Amulet or utility holdings
260
241
  await mergeAmuletHoldingsForParty(partyId);
261
242
  await mergeUtilityHoldingsForParty(partyId, "USDCx");
262
243
 
@@ -269,24 +250,107 @@ const disclosures = await getAmuletDisclosures(partyId);
269
250
  const cmd = await mergeAmuletHoldingsForParty(partyId, true, walletProvider, 5, disclosures);
270
251
  const res = await walletProvider.submitTransaction(cmd);
271
252
 
272
- // Check UTXO status after merge — confirm the order amount is now covered
253
+ // Check UTXO status after merge
273
254
  const counts = await getUtxoCount(partyId, "USDCx", walletProvider);
274
- // { total: 5, unlocked: 1, locked: 4, largestUnlocked: 27.26, unlockedBalance: 27.26 }
275
- if (counts.largestUnlocked >= requiredAmount) {
276
- // Safe to retry createOrderProposal
277
- }
255
+ ```
256
+
257
+ ## WebSocket Real-Time Data
258
+
259
+ Subscribe to live market data and user events via WebSocket. Works in both Node.js and browsers.
260
+
261
+ The server has two types of data:
262
+
263
+ - **Market data** — public channels you explicitly subscribe to (orderbook, trades, ticker, candles, oracle)
264
+ - **User data** — automatically pushed after authentication, no subscribe needed (orders, trades, balances)
265
+
266
+ ```javascript
267
+ import {
268
+ subscribeOrderbook,
269
+ subscribeTrades,
270
+ subscribeTicker,
271
+ subscribeCandles,
272
+ subscribeUserOrders,
273
+ subscribeUserTrades,
274
+ subscribeUserBalances,
275
+ disconnectWebSocket,
276
+ } from "@temple-digital-group/temple-canton-js";
277
+
278
+ // Market data — sends a subscribe message to the server
279
+ const unsub = subscribeOrderbook("Amulet/USDCx", (data) => {
280
+ console.log("Orderbook update:", data);
281
+ });
282
+ subscribeTrades("Amulet/USDCx", (data) => console.log("Trade:", data));
283
+ subscribeTicker("CBTC/USDCx", (data) => console.log("Ticker:", data));
284
+ subscribeCandles("Amulet/USDCx", 60, (data) => console.log("1m candle:", data));
285
+
286
+ // User data — auto-delivered after auth, no subscribe message needed
287
+ subscribeUserOrders((data) => console.log("Order update:", data));
288
+ subscribeUserTrades((data) => console.log("Trade fill:", data));
289
+ subscribeUserBalances((data) => console.log("Balance update:", data));
290
+
291
+ // Unsubscribe from a specific channel
292
+ unsub();
293
+
294
+ // Disconnect everything
295
+ disconnectWebSocket();
296
+ ```
297
+
298
+ ### Market Data Channels
299
+
300
+ These require an explicit subscribe message. The SDK handles this automatically.
301
+
302
+ | Function | Channel | Example |
303
+ | ------------------------------------------- | -------------------------------- | ------------------------- |
304
+ | `subscribeOrderbook(symbol, cb)` | `orderbook:{symbol}` | `orderbook:Amulet/USDCx` |
305
+ | `subscribeTrades(symbol, cb)` | `trades:{symbol}` | `trades:Amulet/USDCx` |
306
+ | `subscribeTicker(symbol, cb)` | `ticker:{symbol}` | `ticker:CBTC/USDCx` |
307
+ | `subscribeCandles(symbol, granularity, cb)` | `candles:{symbol}:{granularity}` | `candles:Amulet/USDCx:60`|
308
+ | `subscribeOracle(symbol, cb)` | `oracle:{symbol}` | `oracle:cc` |
309
+ | `subscribeOracleVolume(symbol, cb)` | `oracle_volume:{symbol}` | `oracle_volume:cc` |
310
+
311
+ **Candle granularity values:** `60` (1m), `300` (5m), `900` (15m), `3600` (1h), `14400` (4h), `86400` (1d)
312
+
313
+ ### User Data Events
314
+
315
+ Pushed automatically by the server after authentication. No subscribe message is sent — you just register a local handler. Requires `API_KEY` (Node.js) or cookie auth (browser).
316
+
317
+ | Function | Server Event | Description |
318
+ | -------------------------- | -------------- | -------------------------------------------------- |
319
+ | `subscribeUserOrders(cb)` | `user_order` | Order lifecycle updates (created, filled, cancelled)|
320
+ | `subscribeUserTrades(cb)` | `user_trade` | Trade fill confirmations |
321
+ | `subscribeUserBalances(cb)`| `user_balance` | Balance changes |
322
+
323
+ ### Advanced Usage
324
+
325
+ Use the `TempleWebSocket` class directly for full control:
326
+
327
+ ```javascript
328
+ import { TempleWebSocket } from "@temple-digital-group/temple-canton-js";
329
+
330
+ const ws = new TempleWebSocket();
331
+ ws.onConnect = () => console.log("Connected");
332
+ ws.onDisconnect = (code, reason) => console.log("Disconnected:", code, reason);
333
+ ws.onAuth = (success, userId) => console.log("Auth:", success, userId);
334
+ ws.onError = (err) => console.error("WS error:", err);
335
+ ws.autoReconnect = true; // default — reconnects with exponential backoff
336
+ ws.connect();
337
+
338
+ // Market data — sends subscribe to server
339
+ const unsub = ws.subscribe("orderbook:Amulet/USDCx", (data) => { ... });
340
+
341
+ // User data — no subscribe message, just local handler
342
+ const unsubOrder = ws.onUserEvent("user_order", (data) => { ... });
278
343
  ```
279
344
 
280
345
  ## API Reference
281
346
 
282
- > Functions marked with **W** support Loop Wallet via the wallet adapter. All other functions require a custom validator (ledger access via `VALIDATOR_API_URL` and `JWT_TOKEN`).
347
+ > Functions marked with **W** support Loop Wallet via the wallet adapter.
283
348
 
284
349
  ### Configuration
285
350
 
286
351
  | Function | Description |
287
352
  | --------------------------- | ----------------------------------------------------------------------------- |
288
353
  | `initialize(config)` | Initialize the SDK, set config, and optionally authenticate with the REST API |
289
- | `setJWTToken(token)` | Update the JWT token without re-initializing the config |
290
354
  | `setWalletAdapter(adapter)` | Set or update the Loop SDK instance for all wallet-aware functions |
291
355
 
292
356
  ### Instrument Catalog
@@ -296,45 +360,51 @@ if (counts.largestUnlocked >= requiredAmount) {
296
360
  | `getSupportedTradingPairs()` | Get the list of supported trading pairs |
297
361
  | `getInstrumentCatalog()` | Get the full instrument catalog |
298
362
 
299
- ### Holdings
363
+ ### Onboarding & Delegation
364
+
365
+ | Function | Provider | Description |
366
+ | ------------------------------------------ | -------- | ------------------------------------------------------ |
367
+ | `isUserOnboarded(party)` | **W** | Check if user has a delegation contract on ledger |
368
+ | `onboardUser(party)` | **W** | Create the delegation contract needed for trading |
369
+ | `withdrawDelegation(delegationId?, user?)` | **W** | Archive the delegation contract (user must re-onboard) |
300
370
 
301
- | Function | Provider | Description |
302
- | ----------------------------------------------------------------- | -------- | -------------------------------------------------------------- |
303
- | `getUserBalances(party?, provider?)` | **W** | Get all balances grouped by asset (CC, locked CC, and utility) |
304
- | `getAmuletHoldingsForParty(party, returnCommand, provider)` | **W** | Get CC holdings |
305
- | `getLockedAmuletHoldingsForParty(party, returnCommand, provider)`| **W** | Get locked CC holdings |
306
- | `getUtilityHoldingsForParty(party, returnCommand, provider)` | **W** | Get utility token holdings |
307
- | `getUtxoCount(party, assetId, provider)` | **W** | Get UTXO summary: counts, largest unlocked amount, and total unlocked balance |
371
+ ### Deposits & Withdrawals
308
372
 
309
- ### Orders
373
+ | Function | Provider | Description |
374
+ | ----------------------------------------- | -------- | ----------------------------------------------------- |
375
+ | `deposit(amount, symbol)` | **W** | Deposit funds (validates balance, reserves 10 CC for fees) |
376
+ | `prepareDepositHoldings(amount, assetId)` | **W** | Resolve holdings for a deposit amount (low-level) |
377
+ | `depositFunds(opts)` | **W** | Submit deposit allocation (low-level) |
378
+ | `withdrawFunds({ asset_id, amount })` | **W** | Withdraw available trading balance back to wallet |
379
+ | `emergencyWithdrawFunds(opts)` | **W** | Cancel all orders and withdraw everything immediately |
380
+
381
+ ### Holdings
310
382
 
311
- | Function | Provider | Description |
312
- | ------------------------------------- | -------- | --------------------------- |
313
- | `createOrderProposal(orderArguments)` | **W** | Create an order proposal |
314
- | `getOrderProposalsForParty(party)` | | Get pending order proposals |
315
- | `getOrdersForParty(party)` | | Get active orders |
383
+ | Function | Provider | Description |
384
+ | ----------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------- |
385
+ | `getUserBalances(party?, provider?)` | **W** | Get all balances grouped by asset (Amulet, locked, and utility) |
386
+ | `getAmuletHoldingsForParty(party, returnCommand, provider)` | **W** | Get Amulet holdings |
387
+ | `getLockedAmuletHoldingsForParty(party, returnCommand, provider)` | **W** | Get locked Amulet holdings |
388
+ | `getUtilityHoldingsForParty(party, returnCommand, provider)` | **W** | Get utility token holdings |
389
+ | `getUtxoCount(party, assetId, provider)` | **W** | Get UTXO summary: counts, largest unlocked amount, and total unlocked balance |
316
390
 
317
391
  ### Holding Operations
318
392
 
319
- | Function | Provider | Description |
320
- | ------------------------------------------------------------------------------------------ | -------- | --------------------------- |
321
- | `mergeAmuletHoldingsForParty(party, returnCommand, provider, maxUtxos, amuletDisclosures)` | **W** | Merge CC holdings into one |
393
+ | Function | Provider | Description |
394
+ | ------------------------------------------------------------------------------------------ | -------- | ------------------------------- |
395
+ | `mergeAmuletHoldingsForParty(party, returnCommand, provider, maxUtxos, amuletDisclosures)` | **W** | Merge Amulet holdings into one |
322
396
  | `mergeUtilityHoldingsForParty(party, utilityAsset, returnCommand, provider, maxUtxos)` | **W** | Merge utility holdings into one |
323
- | `splitAmuletHoldingForParty(party, outputQuantity)` | | Split a CC holding |
324
- | `unlockLockedAmulets(party)` | | Unlock locked CC holdings |
325
397
 
326
- ### Temple REST API (Optional)
398
+ ### Temple REST API
327
399
 
328
- > These functions call the Temple public REST API and are entirely optional. Pass `API_EMAIL`/`API_PASSWORD` in `initialize()`, or call `login()` directly — tokens are stored and auto-refreshed.
400
+ > These functions call the Temple REST API. Pass `API_KEY` in `initialize()` or call `setApiKey()` to authenticate.
329
401
 
330
402
  #### Auth
331
403
 
332
- | Function | Description |
333
- | ----------------------------------- | --------------------------------------------------- |
334
- | `login(email, password)` | Login and store access/refresh tokens and user profile |
335
- | `refreshAccessToken(refreshToken?)` | Refresh the access token (auto-called when expired) |
336
- | `logout()` | Clear stored tokens |
337
- | `getUserId()` | Get the stored user ID from login (used automatically by `createOrderProposal`) |
404
+ | Function | Description |
405
+ | ---------------- | ------------------------------------------- |
406
+ | `setApiKey(key)` | Set the API key for REST API authentication |
407
+ | `getUserId()` | Get the stored user ID |
338
408
 
339
409
  #### Market Data
340
410
 
@@ -346,16 +416,42 @@ if (counts.largestUnlocked >= requiredAmount) {
346
416
  | `getOpenInterest(symbol)` | Get open interest for a trading pair |
347
417
  | `getRecentTrades(symbol, options?)` | Get recent trades (options: `limit`, max 500) |
348
418
 
349
- #### Orders
350
-
351
- | Function | Description |
352
- | --------------------------- | ---------------------------------------------- |
353
- | `getActiveOrders(options?)` | Get active orders (options: `symbol`, `limit`) |
354
- | `cancelOrder(orderId)` | Cancel a specific order |
355
- | `cancelAllOrders(options?)` | Cancel all orders (options: `symbol` filter) |
356
-
357
- #### Disclosures
358
-
359
- | Function | Description |
360
- | ------------------------- | ------------------------------------------------------------------------------- |
361
- | `getDisclosures(partyId)` | Get CC disclosure data (amulet rules, open mining rounds, external party rules) |
419
+ #### Trading
420
+
421
+ | Function | Description |
422
+ | ----------------------------------- | ------------------------------------------------------ |
423
+ | `createOrderRequest(opts)` | Place a buy/sell order via the trading backend |
424
+ | `cancelOrder(orderId)` | Cancel a specific order |
425
+ | `cancelAllOrders(options?)` | Cancel all orders (options: `symbol` filter) |
426
+ | `getTradingBalance()` | Get user's trading balance (unlocked/locked/in-flight) |
427
+ | `getActiveOrders(options?)` | Get active orders (options: `symbol`, `limit`) |
428
+
429
+ #### Withdrawals
430
+
431
+ | Function | Description |
432
+ | ------------------------------------------ | ------------------------------------------ |
433
+ | `createWithdrawalRequest(assetId, amount)` | Submit a withdrawal request to the backend |
434
+ | `getWithdrawalRequestStatus(requestId)` | Poll withdrawal status until ready |
435
+
436
+ #### Disclosures & Delegation
437
+
438
+ | Function | Description |
439
+ | ------------------------- | ---------------------------------------------------------------------------- |
440
+ | `getDisclosures(partyId)` | Get Amulet disclosure data (factory ID, choice context, disclosed contracts) |
441
+ | `getDelegation()` | Get the user's delegation contract from the API |
442
+
443
+ ### WebSocket
444
+
445
+ | Function | Description |
446
+ | ------------------------------------------- | -------------------------------------------------------------- |
447
+ | `createWebSocket()` | Get or create the shared WS instance (auto-connects) |
448
+ | `disconnectWebSocket()` | Disconnect and destroy the shared WS instance |
449
+ | `subscribeOrderbook(symbol, cb)` | Subscribe to orderbook updates |
450
+ | `subscribeTrades(symbol, cb)` | Subscribe to trade updates |
451
+ | `subscribeTicker(symbol, cb)` | Subscribe to ticker updates |
452
+ | `subscribeCandles(symbol, granularity, cb)` | Subscribe to candle updates |
453
+ | `subscribeOracle(symbol, cb)` | Subscribe to oracle price updates |
454
+ | `subscribeOracleVolume(symbol, cb)` | Subscribe to oracle volume updates |
455
+ | `subscribeUserOrders(cb)` | Listen to user order events (auto-pushed, no subscribe needed) |
456
+ | `subscribeUserTrades(cb)` | Listen to user trade events (auto-pushed, no subscribe needed) |
457
+ | `subscribeUserBalances(cb)` | Listen to user balance events (auto-pushed, no subscribe needed)|