@temple-digital-group/temple-canton-js
v2.0.5
Published
JavaScript library for interacting with Temple Canton blockchain
Downloads
2,059
Readme
Temple Canton JS
JavaScript SDK for interacting with the Temple Canton blockchain exchange. Supports Amulet (CC), USDCx, and CBTC tokens on the Canton network.
Installation
npm install @temple-digital-group/temple-canton-jsConfiguration
Call initialize() before using any SDK functions. It sets up the config and optionally authenticates with the Temple REST API.
Wallet Adapter
For apps using Loop Wallet. Pass the Loop SDK instance as WALLET_ADAPTER — the SDK auto-detects server vs client mode.
- Server-side: uses
loop.executeTransaction()(signs locally with private key) - Client-side: uses
loop.provider.submitTransaction()(delegates signing to Loop Wallet via WebSocket)
import { initialize } from "@temple-digital-group/temple-canton-js";
initialize({
API_KEY: "your-api-key",
NETWORK: "mainnet",
WALLET_ADAPTER: loop, // Pass the Loop SDK instance
});You can also set or change the wallet adapter after init:
import { setWalletAdapter } from "@temple-digital-group/temple-canton-js";
setWalletAdapter(loop);| Key | Required | Description |
| ---------------- | -------- | --------------------------------------------------------------- |
| API_KEY | Yes | Temple REST API key |
| NETWORK | Yes | mainnet or testnet |
| WALLET_ADAPTER | Yes | Loop SDK instance — auto-detects server/client mode for signing |
Supported Instruments
| Asset | Type | Networks | | ----- | ----------- | ---------------- | | CC | Canton Coin | testnet, mainnet | | USDCx | Utility | testnet, mainnet | | CBTC | Utility | testnet, mainnet |
Symbol normalization: Use
CCfor Canton Coin in all SDK methods. The SDK handles the internal conversion toAmuletwhere required by the ledger. TheAmuletsymbol is deprecated — all API responses now returnCC.
Supported Trading Pairs
CC/USDCxCBTC/USDCx
v2 Trading Flow
The v2 flow covers the full trading lifecycle: onboarding, deposits, trading, and withdrawals.
1. Check onboarding → isUserOnboarded(party)
If NOT onboarded → onboardUser(party)
2. Deposit funds → deposit(amount, symbol)
3. Check balance → getTradingBalance()
4. Place orders → createOrderRequest({ symbol, side, quantity, price, ... })
5. Cancel orders → cancelOrder(orderId) or cancelAllOrders({ symbol })
6. Withdraw funds → withdrawFunds({ asset_id, amount })
7. Withdraw delegation → withdrawDelegation(delegationId, user)1. Onboarding
Check if a user has a delegation contract, and create one if not:
import { isUserOnboarded, onboardUser } from "@temple-digital-group/temple-canton-js";
const delegation = await isUserOnboarded(party);
if (!delegation) {
const result = await onboardUser({ partyId: party });
// result.delegation — the confirmed delegation contract
// result.warning — set if onboarding was submitted but not confirmed within 60s
}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.
2. Deposit Funds
The simplest way to deposit is the deposit() helper — pass the amount and symbol, and it handles everything:
import { deposit } from "@temple-digital-group/temple-canton-js";
const result = await deposit(100, "USDCx");
// or
const result = await deposit(10, "CC");deposit() requires the wallet adapter to be connected. It:
- Checks your CC balance to ensure at least 10 CC is reserved for transaction fees
- For utility deposits (USDCx, CBTC), verifies you have enough of the token and 10 CC for fees
- Selects the right UTXOs from your wallet
- Submits the deposit allocation
If you need more control, use prepareDepositHoldings + depositFunds directly:
import { prepareDepositHoldings, depositFunds } from "@temple-digital-group/temple-canton-js";
const depositOpts = await prepareDepositHoldings(100, "USDCx");
const result = await depositFunds(depositOpts);3. Trading Balance
import { getTradingBalance } from "@temple-digital-group/temple-canton-js";
const balances = await getTradingBalance();
// Returns { balances: [{ asset, unlocked, locked, in_flight, ... }] }Use this to check available funds before placing orders or withdrawals.
4. Place Orders
import { createOrderRequest } from "@temple-digital-group/temple-canton-js";
const result = await createOrderRequest({
symbol: "CC/USDCx",
side: "buy",
quantity: 10.5,
price: 1.25,
order_type: "limit",
});
// Post-only order (rejected if it would match immediately)
const postOnly = await createOrderRequest({
symbol: "CC/USDCx",
side: "buy",
quantity: 10.5,
price: 1.25,
order_type: "limit",
order_subtype: "post_only",
});5. Cancel Orders
import { cancelOrder, cancelAllOrders } from "@temple-digital-group/temple-canton-js";
// Cancel a specific order
await cancelOrder("ord_abc123");
// Cancel all orders for a symbol
await cancelAllOrders({ symbol: "CC/USDCx" });
// Cancel ALL orders
await cancelAllOrders();6. Withdraw Funds
Withdraws available (unlocked, non-in-flight) trading balance back to the user's wallet.
import { withdrawFunds } from "@temple-digital-group/temple-canton-js";
const result = await withdrawFunds({
asset_id: "USDCx",
amount: "250.50",
});7. Withdraw Delegation
Archives the user's delegation contract. The user must re-onboard to trade again.
import { withdrawDelegation } from "@temple-digital-group/temple-canton-js";
// Auto-fetches delegation from API if not passed
await withdrawDelegation();
// Or pass explicitly
await withdrawDelegation(delegationContractId, partyId);Get User Balances
import { getUserBalances } from "@temple-digital-group/temple-canton-js";
// Both params are optional — falls back to wallet adapter / config
const balances = await getUserBalances();
// Or pass explicitly
const balances = await getUserBalances(partyId);
const balances = await getUserBalances(partyId, walletProvider);Each entry in the returned array contains:
{
asset: 'USDCx',
total_balance: 170.5,
available_balance: 150.5,
locked_balance: 20.0,
dso: null,
registrar: '...',
operator: '...',
provider: '...',
merge_warning: true,
holdings: [...],
locked_holdings: [...],
utilityContext: { ... }
}Merge Holdings
import { mergeAmuletHoldingsForParty, mergeUtilityHoldingsForParty, getAmuletDisclosures, getUtxoCount } from "@temple-digital-group/temple-canton-js";
// Merge all Amulet or utility holdings
await mergeAmuletHoldingsForParty(partyId);
await mergeUtilityHoldingsForParty(partyId, "USDCx");
// Wallet Provider — merge up to 5 smallest USDCx UTXOs
const command = await mergeUtilityHoldingsForParty(partyId, "USDCx", true, walletProvider, 5);
const result = await walletProvider.submitTransaction(command);
// Wallet Provider — merge CC (requires disclosures)
const disclosures = await getAmuletDisclosures(partyId);
const cmd = await mergeAmuletHoldingsForParty(partyId, true, walletProvider, 5, disclosures);
const res = await walletProvider.submitTransaction(cmd);
// Check UTXO status after merge
const counts = await getUtxoCount(partyId, "USDCx", walletProvider);WebSocket — Real-Time Data
Subscribe to live market data and user events via WebSocket. Works in both Node.js and browsers.
The server has two types of data:
- Market data — public channels you explicitly subscribe to (orderbook, trades, ticker, candles, oracle)
- User data — automatically pushed after authentication, no subscribe needed (orders, trades, balances)
import {
subscribeOrderbook,
subscribeTrades,
subscribeTicker,
subscribeCandles,
subscribeUserOrders,
subscribeUserTrades,
subscribeUserBalances,
disconnectWebSocket,
} from "@temple-digital-group/temple-canton-js";
// Market data — sends a subscribe message to the server
const unsub = subscribeOrderbook("Amulet/USDCx", (data) => {
console.log("Orderbook update:", data);
});
subscribeTrades("Amulet/USDCx", (data) => console.log("Trade:", data));
subscribeTicker("CBTC/USDCx", (data) => console.log("Ticker:", data));
subscribeCandles("Amulet/USDCx", 60, (data) => console.log("1m candle:", data));
// User data — auto-delivered after auth, no subscribe message needed
subscribeUserOrders((data) => console.log("Order update:", data));
subscribeUserTrades((data) => console.log("Trade fill:", data));
subscribeUserBalances((data) => console.log("Balance update:", data));
// Unsubscribe from a specific channel
unsub();
// Disconnect everything
disconnectWebSocket();Market Data Channels
These require an explicit subscribe message. The SDK handles this automatically.
| Function | Channel | Example |
| ------------------------------------------- | -------------------------------- | ------------------------- |
| subscribeOrderbook(symbol, cb) | orderbook:{symbol} | orderbook:Amulet/USDCx |
| subscribeTrades(symbol, cb) | trades:{symbol} | trades:Amulet/USDCx |
| subscribeTicker(symbol, cb) | ticker:{symbol} | ticker:CBTC/USDCx |
| subscribeCandles(symbol, granularity, cb) | candles:{symbol}:{granularity} | candles:Amulet/USDCx:60|
| subscribeOracle(symbol, cb) | oracle:{symbol} | oracle:cc |
| subscribeOracleVolume(symbol, cb) | oracle_volume:{symbol} | oracle_volume:cc |
Candle granularity values: 60 (1m), 300 (5m), 900 (15m), 3600 (1h), 14400 (4h), 86400 (1d)
User Data Events
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).
| Function | Server Event | Description |
| -------------------------- | -------------- | -------------------------------------------------- |
| subscribeUserOrders(cb) | user_order | Order lifecycle updates (created, filled, cancelled)|
| subscribeUserTrades(cb) | user_trade | Trade fill confirmations |
| subscribeUserBalances(cb)| user_balance | Balance changes |
Advanced Usage
Use the TempleWebSocket class directly for full control:
import { TempleWebSocket } from "@temple-digital-group/temple-canton-js";
const ws = new TempleWebSocket();
ws.onConnect = () => console.log("Connected");
ws.onDisconnect = (code, reason) => console.log("Disconnected:", code, reason);
ws.onAuth = (success, userId) => console.log("Auth:", success, userId);
ws.onError = (err) => console.error("WS error:", err);
ws.autoReconnect = true; // default — reconnects with exponential backoff
ws.connect();
// Market data — sends subscribe to server
const unsub = ws.subscribe("orderbook:Amulet/USDCx", (data) => { ... });
// User data — no subscribe message, just local handler
const unsubOrder = ws.onUserEvent("user_order", (data) => { ... });API Reference
Functions marked with W support Loop Wallet via the wallet adapter.
Configuration
| Function | Description |
| --------------------------- | ----------------------------------------------------------------------------- |
| initialize(config) | Initialize the SDK, set config, and optionally authenticate with the REST API |
| setWalletAdapter(adapter) | Set or update the Loop SDK instance for all wallet-aware functions |
Instrument Catalog
| Function | Description |
| ---------------------------- | --------------------------------------- |
| getSupportedTradingPairs() | Get the list of supported trading pairs |
| getInstrumentCatalog() | Get the full instrument catalog |
Onboarding & Delegation
| Function | Provider | Description |
| ------------------------------------------ | -------- | ------------------------------------------------------ |
| isUserOnboarded(party) | W | Check if user has a delegation contract on ledger |
| onboardUser(party) | W | Create the delegation contract needed for trading |
| withdrawDelegation(delegationId?, user?) | W | Archive the delegation contract (user must re-onboard) |
Deposits & Withdrawals
| Function | Provider | Description |
| ----------------------------------------- | -------- | ----------------------------------------------------- |
| deposit(amount, symbol) | W | Deposit funds (validates balance, reserves 10 CC for fees) |
| prepareDepositHoldings(amount, assetId) | W | Resolve holdings for a deposit amount (low-level) |
| depositFunds(opts) | W | Submit deposit allocation (low-level) |
| withdrawFunds({ asset_id, amount }) | W | Withdraw available trading balance back to wallet |
| emergencyWithdrawFunds(opts) | W | Cancel all orders and withdraw everything immediately |
Holdings
| Function | Provider | Description |
| ----------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------- |
| getUserBalances(party?, provider?) | W | Get all balances grouped by asset (Amulet, locked, and utility) |
| getAmuletHoldingsForParty(party, returnCommand, provider) | W | Get Amulet holdings |
| getLockedAmuletHoldingsForParty(party, returnCommand, provider) | W | Get locked Amulet holdings |
| getUtilityHoldingsForParty(party, returnCommand, provider) | W | Get utility token holdings |
| getUtxoCount(party, assetId, provider) | W | Get UTXO summary: counts, largest unlocked amount, and total unlocked balance |
Holding Operations
| Function | Provider | Description |
| ------------------------------------------------------------------------------------------ | -------- | ------------------------------- |
| mergeAmuletHoldingsForParty(party, returnCommand, provider, maxUtxos, amuletDisclosures) | W | Merge Amulet holdings into one |
| mergeUtilityHoldingsForParty(party, utilityAsset, returnCommand, provider, maxUtxos) | W | Merge utility holdings into one |
Temple REST API
These functions call the Temple REST API. Pass
API_KEYininitialize()or callsetApiKey()to authenticate.
Auth
| Function | Description |
| ---------------- | ------------------------------------------- |
| setApiKey(key) | Set the API key for REST API authentication |
| getUserId() | Get the stored user ID |
Market Data
| Function | Description |
| ----------------------------------- | --------------------------------------------------------- |
| getTicker(symbol?) | Get ticker data for one or all trading pairs |
| getOrderBook(symbol, options?) | Get the order book (options: levels, precision) |
| getSymbolConfig(symbol) | Get symbol configuration (paused, decimals, min quantity) |
| getOpenInterest(symbol) | Get open interest for a trading pair |
| getRecentTrades(symbol, options?) | Get recent trades (options: limit, max 500) |
Trading
| Function | Description |
| ----------------------------------- | ------------------------------------------------------ |
| createOrderRequest(opts) | Place a buy/sell order via the trading backend |
| cancelOrder(orderId) | Cancel a specific order |
| cancelAllOrders(options?) | Cancel all orders (options: symbol filter) |
| getTradingBalance() | Get user's trading balance (unlocked/locked/in-flight) |
| getActiveOrders(options?) | Get active orders (options: symbol, limit) |
Withdrawals
| Function | Description |
| ------------------------------------------ | ------------------------------------------ |
| createWithdrawalRequest(assetId, amount) | Submit a withdrawal request to the backend |
| getWithdrawalRequestStatus(requestId) | Poll withdrawal status until ready |
Disclosures & Delegation
| Function | Description |
| ------------------------- | ---------------------------------------------------------------------------- |
| getDisclosures(partyId) | Get Amulet disclosure data (factory ID, choice context, disclosed contracts) |
| getDelegation() | Get the user's delegation contract from the API |
WebSocket
| Function | Description |
| ------------------------------------------- | -------------------------------------------------------------- |
| createWebSocket() | Get or create the shared WS instance (auto-connects) |
| disconnectWebSocket() | Disconnect and destroy the shared WS instance |
| subscribeOrderbook(symbol, cb) | Subscribe to orderbook updates |
| subscribeTrades(symbol, cb) | Subscribe to trade updates |
| subscribeTicker(symbol, cb) | Subscribe to ticker updates |
| subscribeCandles(symbol, granularity, cb) | Subscribe to candle updates |
| subscribeOracle(symbol, cb) | Subscribe to oracle price updates |
| subscribeOracleVolume(symbol, cb) | Subscribe to oracle volume updates |
| subscribeUserOrders(cb) | Listen to user order events (auto-pushed, no subscribe needed) |
| subscribeUserTrades(cb) | Listen to user trade events (auto-pushed, no subscribe needed) |
| subscribeUserBalances(cb) | Listen to user balance events (auto-pushed, no subscribe needed)|
