@temple-digital-group/temple-canton-js 2.0.0-beta.1 → 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
@@ -22,7 +22,8 @@ For apps using Loop Wallet. Pass the Loop SDK instance as `WALLET_ADAPTER` — t
22
22
  ```javascript
23
23
  import { initialize } from "@temple-digital-group/temple-canton-js";
24
24
 
25
- await initialize({
25
+ initialize({
26
+ API_KEY: "your-api-key",
26
27
  NETWORK: "mainnet",
27
28
  WALLET_ADAPTER: loop, // Pass the Loop SDK instance
28
29
  });
@@ -38,19 +39,19 @@ setWalletAdapter(loop);
38
39
 
39
40
  | Key | Required | Description |
40
41
  | ---------------- | -------- | --------------------------------------------------------------- |
41
- | `NETWORK` | Yes | `mainnet`, `testnet`, or `localhost` |
42
+ | `API_KEY` | Yes | Temple REST API key |
43
+ | `NETWORK` | Yes | `mainnet` or `testnet` |
42
44
  | `WALLET_ADAPTER` | Yes | Loop SDK instance — auto-detects server/client mode for signing |
43
- | `API_KEY` | No | Temple REST API key for authenticated endpoints |
44
45
 
45
46
  ## Supported Instruments
46
47
 
47
- | Asset | Type | Networks |
48
- | ------ | ----------- | ---------------- |
49
- | CC | Canton Coin | testnet, mainnet |
50
- | USDCx | Utility | testnet, mainnet |
51
- | CBTC | Utility | testnet, mainnet |
48
+ | Asset | Type | Networks |
49
+ | ----- | ----------- | ---------------- |
50
+ | CC | Canton Coin | testnet, mainnet |
51
+ | USDCx | Utility | testnet, mainnet |
52
+ | CBTC | Utility | testnet, mainnet |
52
53
 
53
- > **Symbol normalization:** `CC` is automatically normalized to `Amulet` in all API methods that accept a symbol (e.g. `CC/USDCx` becomes `Amulet/USDCx`).
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`.
54
55
 
55
56
  ## Supported Trading Pairs
56
57
 
@@ -65,7 +66,7 @@ The v2 flow covers the full trading lifecycle: onboarding, deposits, trading, an
65
66
  1. Check onboarding → isUserOnboarded(party)
66
67
  If NOT onboarded → onboardUser(party)
67
68
 
68
- 2. Deposit funds → depositFunds({ sender, assetId, amount, holdingCids, ... })
69
+ 2. Deposit funds → deposit(amount, symbol)
69
70
 
70
71
  3. Check balance → getTradingBalance()
71
72
 
@@ -87,41 +88,40 @@ import { isUserOnboarded, onboardUser } from "@temple-digital-group/temple-canto
87
88
 
88
89
  const delegation = await isUserOnboarded(party);
89
90
  if (!delegation) {
90
- await onboardUser(party);
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
91
94
  }
92
95
  ```
93
96
 
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.
98
+
94
99
  ### 2. Deposit Funds
95
100
 
96
- Deposit funds into the user's trading balance. Use `prepareDepositHoldings` to resolve the holdings for the deposit amount.
101
+ The simplest way to deposit is the `deposit()` helper pass the amount and symbol, and it handles everything:
97
102
 
98
103
  ```javascript
99
- import { prepareDepositHoldings, depositFunds } from "@temple-digital-group/temple-canton-js";
100
-
101
- // Prepare holdings for the deposit
102
- const depositOpts = await prepareDepositHoldings(100, "USDCx");
104
+ import { deposit } from "@temple-digital-group/temple-canton-js";
103
105
 
104
- // Submit the deposit
105
- const result = await depositFunds(depositOpts);
106
+ const result = await deposit(100, "USDCx");
107
+ // or
108
+ const result = await deposit(10, "CC");
106
109
  ```
107
110
 
108
- `depositFunds` accepts:
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:
109
118
 
110
- | Option | Required | Description |
111
- | ---------------- | -------- | ------------------------------------------------------------- |
112
- | `sender` | Yes | Party allocating the assets |
113
- | `assetId` | Yes | Instrument symbol (`USDCx`, `Amulet`, `CBTC`) |
114
- | `amount` | Yes | Amount to allocate |
115
- | `holdingCids` | Yes | Holding contract IDs that fund the allocation |
116
- | `receiver` | No | Counterparty (defaults to sender) |
117
- | `settlementId` | No | Reference ID for the settlement |
118
- | `transferLegId` | No | Unique ID for this transfer leg |
119
- | `allocateBefore` | No | ISO timestamp; allocation deadline (default: +1h) |
120
- | `settleBefore` | No | ISO timestamp; settlement deadline (default: +2h) |
121
- | `disclosures` | No | Pre-fetched Amulet disclosures (for FE without API access) |
122
- | `userId` | No | User ID (falls back to wallet adapter / config) |
119
+ ```javascript
120
+ import { prepareDepositHoldings, depositFunds } from "@temple-digital-group/temple-canton-js";
123
121
 
124
- For Amulet deposits, the SDK fetches disclosures automatically. You can also pass them manually via `opts.disclosures`.
122
+ const depositOpts = await prepareDepositHoldings(100, "USDCx");
123
+ const result = await depositFunds(depositOpts);
124
+ ```
125
125
 
126
126
  ### 3. Trading Balance
127
127
 
@@ -132,18 +132,29 @@ const balances = await getTradingBalance();
132
132
  // Returns { balances: [{ asset, unlocked, locked, in_flight, ... }] }
133
133
  ```
134
134
 
135
+ Use this to check available funds before placing orders or withdrawals.
136
+
135
137
  ### 4. Place Orders
136
138
 
137
139
  ```javascript
138
140
  import { createOrderRequest } from "@temple-digital-group/temple-canton-js";
139
141
 
140
142
  const result = await createOrderRequest({
141
- symbol: "Amulet/USDCx",
143
+ symbol: "CC/USDCx",
142
144
  side: "buy",
143
145
  quantity: 10.5,
144
146
  price: 1.25,
145
147
  order_type: "limit",
146
- expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
148
+ });
149
+
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",
147
158
  });
148
159
  ```
149
160
 
@@ -153,10 +164,10 @@ const result = await createOrderRequest({
153
164
  import { cancelOrder, cancelAllOrders } from "@temple-digital-group/temple-canton-js";
154
165
 
155
166
  // Cancel a specific order
156
- await cancelOrder("order-id-123");
167
+ await cancelOrder("ord_abc123");
157
168
 
158
169
  // Cancel all orders for a symbol
159
- await cancelAllOrders({ symbol: "Amulet/USDCx" });
170
+ await cancelAllOrders({ symbol: "CC/USDCx" });
160
171
 
161
172
  // Cancel ALL orders
162
173
  await cancelAllOrders();
@@ -221,8 +232,6 @@ Each entry in the returned array contains:
221
232
  }
222
233
  ```
223
234
 
224
-
225
-
226
235
  ### Merge Holdings
227
236
 
228
237
  ```javascript
@@ -245,6 +254,94 @@ const res = await walletProvider.submitTransaction(cmd);
245
254
  const counts = await getUtxoCount(partyId, "USDCx", walletProvider);
246
255
  ```
247
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) => { ... });
343
+ ```
344
+
248
345
  ## API Reference
249
346
 
250
347
  > Functions marked with **W** support Loop Wallet via the wallet adapter.
@@ -265,36 +362,37 @@ const counts = await getUtxoCount(partyId, "USDCx", walletProvider);
265
362
 
266
363
  ### Onboarding & Delegation
267
364
 
268
- | Function | Provider | Description |
269
- | ------------------------------------- | -------- | ------------------------------------------------------ |
270
- | `isUserOnboarded(party)` | **W** | Check if user has a delegation contract on ledger |
271
- | `onboardUser(party)` | **W** | Create the delegation contract needed for trading |
272
- | `withdrawDelegation(delegationId?, user?)` | **W** | Archive the delegation contract (user must re-onboard) |
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) |
273
370
 
274
371
  ### Deposits & Withdrawals
275
372
 
276
- | Function | Provider | Description |
277
- | ---------------------------------------- | -------- | ------------------------------------------------------------ |
278
- | `prepareDepositHoldings(amount, assetId)` | **W** | Resolve holdings for a deposit amount |
279
- | `depositFunds(opts)` | **W** | Deposit funds into the user's trading balance |
280
- | `withdrawFunds({ asset_id, amount })` | **W** | Withdraw available trading balance back to wallet |
281
- | `emergencyWithdrawFunds(opts)` | **W** | Cancel all orders and withdraw everything immediately |
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 |
282
380
 
283
381
  ### Holdings
284
382
 
285
- | Function | Provider | Description |
286
- | ----------------------------------------------------------------- | -------- | -------------------------------------------------------------- |
287
- | `getUserBalances(party?, provider?)` | **W** | Get all balances grouped by asset (Amulet, locked, and utility) |
288
- | `getAmuletHoldingsForParty(party, returnCommand, provider)` | **W** | Get Amulet holdings |
289
- | `getLockedAmuletHoldingsForParty(party, returnCommand, provider)`| **W** | Get locked Amulet holdings |
290
- | `getUtilityHoldingsForParty(party, returnCommand, provider)` | **W** | Get utility token holdings |
291
- | `getUtxoCount(party, assetId, provider)` | **W** | Get UTXO summary: counts, largest unlocked amount, and total unlocked balance |
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 |
292
390
 
293
391
  ### Holding Operations
294
392
 
295
- | Function | Provider | Description |
296
- | ------------------------------------------------------------------------------------------ | -------- | ------------------------------ |
297
- | `mergeAmuletHoldingsForParty(party, returnCommand, provider, maxUtxos, amuletDisclosures)` | **W** | Merge Amulet holdings into one |
393
+ | Function | Provider | Description |
394
+ | ------------------------------------------------------------------------------------------ | -------- | ------------------------------- |
395
+ | `mergeAmuletHoldingsForParty(party, returnCommand, provider, maxUtxos, amuletDisclosures)` | **W** | Merge Amulet holdings into one |
298
396
  | `mergeUtilityHoldingsForParty(party, utilityAsset, returnCommand, provider, maxUtxos)` | **W** | Merge utility holdings into one |
299
397
 
300
398
  ### Temple REST API
@@ -303,10 +401,10 @@ const counts = await getUtxoCount(partyId, "USDCx", walletProvider);
303
401
 
304
402
  #### Auth
305
403
 
306
- | Function | Description |
307
- | ----------------------------------- | --------------------------------------------------- |
308
- | `setApiKey(key)` | Set the API key for REST API authentication |
309
- | `getUserId()` | Get the stored user ID |
404
+ | Function | Description |
405
+ | ---------------- | ------------------------------------------- |
406
+ | `setApiKey(key)` | Set the API key for REST API authentication |
407
+ | `getUserId()` | Get the stored user ID |
310
408
 
311
409
  #### Market Data
312
410
 
@@ -320,24 +418,40 @@ const counts = await getUtxoCount(partyId, "USDCx", walletProvider);
320
418
 
321
419
  #### Trading
322
420
 
323
- | Function | Description |
324
- | ------------------------------------------- | ---------------------------------------------- |
325
- | `createOrderRequest(opts)` | Place a buy/sell order via the trading backend |
326
- | `cancelOrder(orderId)` | Cancel a specific order |
327
- | `cancelAllOrders(options?)` | Cancel all orders (options: `symbol` filter) |
328
- | `getTradingBalance()` | Get user's trading balance (unlocked/locked/in-flight) |
329
- | `getActiveOrders(options?)` | Get active orders (options: `symbol`, `limit`) |
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`) |
330
428
 
331
429
  #### Withdrawals
332
430
 
333
- | Function | Description |
334
- | ------------------------------------------- | ------------------------------------------------------ |
335
- | `createWithdrawalRequest(assetId, amount)` | Submit a withdrawal request to the backend |
336
- | `getWithdrawalRequestStatus(requestId)` | Poll withdrawal status until ready |
431
+ | Function | Description |
432
+ | ------------------------------------------ | ------------------------------------------ |
433
+ | `createWithdrawalRequest(assetId, amount)` | Submit a withdrawal request to the backend |
434
+ | `getWithdrawalRequestStatus(requestId)` | Poll withdrawal status until ready |
337
435
 
338
436
  #### Disclosures & Delegation
339
437
 
340
- | Function | Description |
341
- | ------------------------- | ------------------------------------------------------------------------------- |
342
- | `getDisclosures(partyId)` | Get Amulet disclosure data (factory ID, choice context, disclosed contracts) |
343
- | `getDelegation()` | Get the user's delegation contract from the API |
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)|
@@ -1,13 +1,12 @@
1
1
  import type { ApiError, Ticker, OrderBook, OrderBookOptions, SymbolConfig, OpenInterest, Trade, RecentTradesOptions, ActiveOrder, ActiveOrdersOptions, CancelOrderResponse, CancelAllOrdersOptions, CancelAllOrdersResponse, CreateOrderRequestOpts, CreateOrderRequestResponse, DelegationResponse, WithdrawalResponse, WithdrawalStatusResponse, TradingBalanceResponse, AmuletDisclosure, DisclosuresResponse } from "./types.js";
2
2
  export type { ApiError, Ticker, OrderBook, OrderBookOptions, SymbolConfig, OpenInterest, Trade, RecentTradesOptions, ActiveOrder, ActiveOrdersOptions, CancelOrderResponse, CancelAllOrdersOptions, CancelAllOrdersResponse, CreateOrderRequestResponse, DelegationResponse, WithdrawalResponse, WithdrawalStatusResponse, TradingBalanceResponse, AmuletDisclosure, DisclosuresResponse, };
3
- export { setApiKey, getUserId } from "./tokenStore.js";
3
+ export { getUserId } from "./tokenStore.js";
4
4
  export { setWalletAdapter } from "../../src/config/index.js";
5
5
  /**
6
- * Initialize the Temple SDK — sets config and authenticates with the REST API via API key.
7
- *
8
- * @returns null (config-only init). Throws no errors.
6
+ * Initialize the Temple SDK.
7
+ * API_KEY is required. Throws if not provided.
9
8
  */
10
- export declare function initialize(cfg: Record<string, unknown>): Promise<null>;
9
+ export declare function initialize(cfg: Record<string, unknown>): void;
11
10
  /**
12
11
  * Get ticker data for one or all trading pairs.
13
12
  * @param symbol - Optional symbol filter (e.g., "Amulet/USDCx")
package/dist/api/index.js CHANGED
@@ -1,28 +1,25 @@
1
1
  import axios from "axios";
2
2
  import config, { initializeConfig, setWalletAdapter } from "../../src/config/index.js";
3
- import { getApiKey, setApiKey as setApiKeyFromConfig, getAuthHeader, setUserId, } from "./tokenStore.js";
4
- export { setApiKey, getUserId } from "./tokenStore.js";
3
+ import { getAuthHeader, setUserId, } from "./tokenStore.js";
4
+ export { getUserId } from "./tokenStore.js";
5
5
  export { setWalletAdapter } from "../../src/config/index.js";
6
6
  // ── Initialization ──
7
7
  /**
8
- * Initialize the Temple SDK — sets config and authenticates with the REST API via API key.
9
- *
10
- * @returns null (config-only init). Throws no errors.
8
+ * Initialize the Temple SDK.
9
+ * API_KEY is required. Throws if not provided.
11
10
  */
12
- export async function initialize(cfg) {
11
+ export function initialize(cfg) {
12
+ if (!cfg.API_KEY) {
13
+ throw new Error("initialize: API_KEY is required.");
14
+ }
13
15
  initializeConfig(cfg);
14
16
  if (cfg.WALLET_ADAPTER) {
15
17
  setWalletAdapter(cfg.WALLET_ADAPTER);
16
18
  }
17
- const apiKey = cfg.API_KEY;
18
- if (apiKey) {
19
- setApiKeyFromConfig(apiKey);
20
- }
21
19
  const userIdValue = cfg.USER_ID;
22
20
  if (userIdValue) {
23
21
  setUserId(userIdValue);
24
22
  }
25
- return null;
26
23
  }
27
24
  // ── Internal helpers ──
28
25
  function handleApiError(error, context) {
@@ -37,14 +34,9 @@ function handleApiError(error, context) {
37
34
  return { error: true, status, code, message };
38
35
  }
39
36
  function ensureAuthenticated() {
40
- // API key from config if not already set
41
- const configApiKey = config.API_KEY;
42
- if (!getApiKey() && configApiKey) {
43
- setApiKeyFromConfig(configApiKey);
44
- }
45
- if (getApiKey())
37
+ if (config.API_KEY)
46
38
  return null;
47
- return { error: true, status: 401, code: "NOT_AUTHENTICATED", message: "API key required. Pass API_KEY in initialize() or call setApiKey()." };
39
+ return { error: true, status: 401, code: "NOT_AUTHENTICATED", message: "API key required. Pass API_KEY in initialize()." };
48
40
  }
49
41
  async function authenticatedGet(path, params) {
50
42
  const authError = ensureAuthenticated();
@@ -204,12 +196,14 @@ export async function getDelegation() {
204
196
  * @param opts - Order parameters: symbol, side, quantity, price, order_type, expires_at
205
197
  */
206
198
  export async function createOrderRequest(opts) {
207
- const { symbol: rawSymbol, side, quantity, price, order_type = "limit", expires_at } = opts || {};
199
+ const { symbol: rawSymbol, side, quantity, price, order_type = "limit", order_subtype, expires_at } = opts || {};
208
200
  if (!rawSymbol || !side || quantity == null || price == null) {
209
201
  return { error: true, status: null, code: "INVALID_PARAMS", message: "symbol, side, quantity, and price are required." };
210
202
  }
211
203
  const symbol = normalizeSymbol(rawSymbol);
212
204
  const body = { symbol, side, quantity: Number(quantity), price: Number(price), order_type };
205
+ if (order_subtype)
206
+ body.order_subtype = order_subtype;
213
207
  if (expires_at)
214
208
  body.expires_at = expires_at;
215
209
  return authenticatedPost("/api/trading/orders", body);
@@ -8,15 +8,7 @@ export declare function getUserId(): string | null;
8
8
  */
9
9
  export declare function setUserId(id: string): void;
10
10
  /**
11
- * Set an API key for authentication.
12
- */
13
- export declare function setApiKey(key: string): void;
14
- /**
15
- * Get the stored API key, or null if not set.
16
- */
17
- export declare function getApiKey(): string | null;
18
- /**
19
- * Get the authorization header using the API key.
20
- * Returns null if no API key is set.
11
+ * Get the authorization header using the API key from config.
12
+ * Returns null if no API key is configured.
21
13
  */
22
14
  export declare function getAuthHeader(): AuthHeaders | null;
@@ -1,4 +1,4 @@
1
- let apiKey = null;
1
+ import config from "../../src/config/index.js";
2
2
  let userId = null;
3
3
  /**
4
4
  * Get the stored user ID, or null if not set.
@@ -13,24 +13,13 @@ export function setUserId(id) {
13
13
  userId = id;
14
14
  }
15
15
  /**
16
- * Set an API key for authentication.
17
- */
18
- export function setApiKey(key) {
19
- apiKey = key;
20
- }
21
- /**
22
- * Get the stored API key, or null if not set.
23
- */
24
- export function getApiKey() {
25
- return apiKey;
26
- }
27
- /**
28
- * Get the authorization header using the API key.
29
- * Returns null if no API key is set.
16
+ * Get the authorization header using the API key from config.
17
+ * Returns null if no API key is configured.
30
18
  */
31
19
  export function getAuthHeader() {
20
+ const apiKey = config.API_KEY;
32
21
  if (apiKey) {
33
- return { Authorization: `Bearer ${apiKey}` };
22
+ return { "X-API-Key": apiKey };
34
23
  }
35
24
  return null;
36
25
  }
@@ -96,6 +96,7 @@ export interface CreateOrderRequestOpts {
96
96
  quantity: number;
97
97
  price: number;
98
98
  order_type?: string;
99
+ order_subtype?: "post_only";
99
100
  expires_at?: string;
100
101
  }
101
102
  export interface CreateOrderRequestResponse {
@@ -145,5 +146,5 @@ export interface ApiError {
145
146
  message: string;
146
147
  }
147
148
  export interface AuthHeaders {
148
- Authorization: string;
149
+ "X-API-Key": string;
149
150
  }
@@ -0,0 +1,52 @@
1
+ export interface DepositFundsOpts {
2
+ sender: string;
3
+ receiver?: string;
4
+ assetId: string;
5
+ amount: string | number;
6
+ holdingCids?: string[];
7
+ settlementId?: string;
8
+ transferLegId?: string;
9
+ allocateBefore?: string;
10
+ settleBefore?: string;
11
+ disclosures?: Record<string, unknown>;
12
+ userId?: string;
13
+ }
14
+ export interface PreparedDeposit {
15
+ sender: string;
16
+ receiver: string;
17
+ assetId: string;
18
+ amount: string;
19
+ holdingCids: string[];
20
+ }
21
+ /**
22
+ * Prepare holdings for a deposit by selecting UTXOs from the wallet provider.
23
+ *
24
+ * Queries the provider for holdings, filters and sorts them, then greedily
25
+ * selects until the requested amount is covered.
26
+ */
27
+ export declare function prepareDepositHoldings(amount: number | string, symbol: string): Promise<PreparedDeposit | {
28
+ error: string;
29
+ data?: Record<string, unknown>;
30
+ }>;
31
+ /**
32
+ * High-level deposit helper.
33
+ *
34
+ * Wraps `prepareDepositHoldings` and `depositFunds` into a single call.
35
+ * Validates the user has sufficient balance and reserves 10 CC for transaction fees.
36
+ *
37
+ * Requires:
38
+ * - Wallet adapter (for reading balances and submitting)
39
+ * - API connection (for disclosures on Amulet deposits)
40
+ */
41
+ export declare function deposit(amount: number | string, symbol: string): Promise<Record<string, unknown>>;
42
+ /**
43
+ * Create a CIP-56 Allocation.
44
+ * Fetches the AllocationFactory, then exercises AllocationFactory_Allocate
45
+ * to lock holdings for a settlement leg.
46
+ *
47
+ * Three resolution paths:
48
+ * 1. Localhost: resolve factory and context from ledger directly
49
+ * 2. Amulet via disclosures (FE/proxy path — no Scan API access)
50
+ * 3. Remote: Scan API / Registry API
51
+ */
52
+ export declare function depositFunds(opts: DepositFundsOpts, returnCommand?: boolean): Promise<Record<string, unknown>>;