Guide: DAR Integration
Building on Tradecraft.
INTEGRATION GUIDE - V1.1.13 A developer's reference for integrating the Canton-native AMM into your application : pool discovery, trading balances, orders, and withdrawals.
The Tradecraft Daml package is available on request. Contact us by email at info@tradecraft.fi.
Critical safety notice: Do not use the delegatedOrder parameter
delegatedOrder is intentionally undocumented. Incorrect use can lead to irrecoverable loss of funds, and it is highly unlikely to be useful for your integration.
By continuing to use Tradecraft, you confirm that any use of delegatedOrder is at your own risk and that you are solely responsible for any resulting losses.
1.0 - Overview
How Tradecraft works
Tradecraft is a decentralized exchange built natively on the Canton Network in Daml. As an integrator, you will work with a small set of templates and a single shared contract:
AMMRules : singleton
The protocol contract that exposes every order-creation choice. All choices on it are nonconsuming, so the same contract is reused across every interaction. You will need its disclosure once per pool.
TradingBalance : per user, per instrument
A vault-held balance of a single token, owned by the user. Tokens must be inside a TradingBalance before they can participate in a swap, deposit, or withdraw.
SwapOrder - DepositOrder - WithdrawOrder
The three order types. Each is created by exercising a choice on AMMRules and consumes the relevant TradingBalance(s) atomically when it fills.
The five-step flow
Discover available trading pairs.
Fund a TradingBalance with the user's tokens.
Submit a SwapOrder (or DepositOrder / WithdrawOrder).
Monitor the order until it fills.
Withdraw the resulting balance back to the user's wallet.
NOTE: Swap orders can optionally be configured for direct settlement, which delivers the swap output to a wallet - see Step 3 below.
2.0 - Network Reference
Endpoints & protocol parties
The following parameters identify the live AMMs on each network. Treat them as configuration that your application should read from a single place rather than hard-coding at call sites.
API base
Mainnet -
https://api.tradecraft.fi/v1Devnet -
https://tradecraft.validator.dev.canton.obsidian.systems/amm-http-api
Venue
Mainnet -
Tradecraft::122096fe076cc065af0cb38f94caa60e8ddfecbe8f0cfe10655ae7aa06fab99c66b7Devnet -
Tradecraft::122090f9041ae7a635c8471c7d496cf3158c294c154dd5468b19f8d37e949875203e
Vault
Mainnet -
cs-vault::1220b4cd6098eebafd4c88efd2b3986e86542bdc391060675432cd195ad26bcf013bDevnet -
decentralized-party::1220b1f5f3fe39721e02a886b36a5a57dc215f5d2de275d9823107bcd825b186689d
3.0 - The Integration Workflow
Step 1 - Discover trading pairs
Fetch the list of every active AMM pool. The response gives you the ammId you'll need for every subsequent order.
NOTE: Each pool's ammId is the only identifier you need to route an order to it. The venue and vault are the same across every pool on a given network.
Step 2 - Fund a Trading Balance
Before a user can trade, their tokens must sit inside a TradingBalance contract. This is a two-call sequence. Fetch the disclosure for the AMMRules contract, then exercise the deposit choice.
Step 2a - Fetch the AMMRules disclosure
The path segments are the two instruments of the pool you intend to trade against. The example below targets the CBTC/CC pool.
Step 2b - Exercise AMMRules_AddTradingBalance (~10.5 kB)
With the disclosure in hand, exercise the deposit choice. The user is the actor; their wallet's allocation context provides the tokens.
Choice Signature
TIP: Avoid UTXO Fragmentation. Pass every known TradingBalance contract ID for the given asset into existingBalances on every call. They will be consolidated atomically into a single new balance, keeping your contract set tidy and reducing downstream gas costs.
Step 3 - Submit orders
All three order types (SwapOrder, DepositOrder, and WithdrawOrder) are created by exercising a nonconsuming choice on the same AMMRules singleton. The resulting order contracts are themselves templates you can query for status.
Swap orders - exchanging two tokens (~5.67 kB)
Most integrations will spend the majority of their time here. The what field's two constructors describe the two natural shapes of a swap intent:
Long : Buy a fixed quantity of the instrument. Pay whatever the AMM quotes.
Short : Sell a fixed quantity of the instrument. Receive whatever the AMM quotes.
If you've integrated against Tradecraft's Pool Addresses before, that product is built on Short.
Choice Signature
Resulting Template (Queryable)
The SwapDirection Enum
Swap orders - direct settlement, skip the withdrawal step (~5.67 kB)
By default, a filled swap credits its output to a new TradingBalance, which you must then return to the user's wallet using AMMRules_WithdrawTradingBalance. Optionally setting requestTradingBalanceWithdrawal = Some party collapses the two steps into one. When the order is filled, the output is settled directly to the specified party's wallet and no output TradingBalance is created. The recipient is typically the actor themselves, but any party may be specified.
When a direct-settlement order is filled by the venue, the same transaction that archives the SwapOrder creates a PhysicalSettlement contract - an obligation to deliver the output, visible to the actor.
Resulting Template (Queryable)
NOTE: If the recipient has a transfer pre-approval for the output instrument, the tokens arrive in the recipient's wallet with no further action from you. If the recipient has no pre-approval, the tokens will appear as a transfer offer which the recipient must accept.
NOTE: Direct settlement is only available for output instruments on the venue's settlement whitelist. An order requesting direct settlement of an unsupported output instrument will not fill. It is cancelled with the reason "Withdrawal request not supported for this output instrument". Confirm whitelist coverage for your pairs with your Tradecraft contact, and exercise the flow on devnet before going live.
NOTE: Monitoring and detection of filled orders is unchanged. Watch for the SwapOrder's archival. The archiving transaction contains a PhysicalSettlement in place of the output TradingBalance.
Swap orders - using holdings as input, with direct settlement, in a single choice
The single-exercise variant. One call allocates the input amount from the actor's wallet holdings, funds the TradingBalance, and creates the SwapOrder atomically. On fill, the output settles directly to the actor's wallet. Step 2b and Step 5 drop out; only the Step 2a disclosure is still needed. Note that specifying requestTradingBalanceWithdrawal = Some party is not required.
Critical safety notice: A transfer pre-approval MUST be active for both tokens the user is swapping between BEFORE the order is submitted.
Without it, the swap still occurs where the input is consumed on fill, but NO funds are returned to the wallet. If the order fails or is cancelled, pre-approval is required to receive the input tokens back. In both scenarios, the transfer-offer fallback under direct settlement above does not apply here. Missing pre-approval = loss of funds.
We highly recommend you test this version of swap order creation on devnet, confirming that tokens are received in the destination wallet before going live.
Choice Signature
Result Type
NOTE: Only Short is currently supported. Long orders fail with "Only short orders are currently supported".
NOTE: Monitoring is identical to direct settlement : watch for the SwapOrder's archival; a PhysicalSettlement replaces the output TradingBalance.
NOTE: Orders from this choice populate delegatedOrder internally. This is expected. The critical safety notice at the top of this guide still stands. Never set it yourself.
Reminder : no pre-approval on the output token = the swap will execute but no funds will be returned.
Deposit orders - adding liquidity to a pool (~5.2 kB)
This choice deposit liquidity into a pool and mints LP tokens. Both amount1 and amount2 must already exist as funded TradingBalances for the actor.
Choice Signature
Resulting Template (Queryable)
NOTE: amount1 and amount2 must be aligned with the current ratio of the pool. Fetch the current price with GET /ratio/{tokenA}/{tokenB}, or let the API compute aligned amounts for you with GET /quoteLPDeposit/{tokenA}/{tokenB}.
Withdraw orders - removing liquidity from a pool (~5.2 kB)
This choice burns LP tokens, which must live in a TradingBalance, in exchange for the underlying pair.
Choice Signature
Resulting Template (Queryable)
NOTE: Every order template carries actor, venue, vault, and ammId - the same four identity fields. Parameterize these once in your client and reuse across all three constructors.
Step 4 - Monitor for filled orders
When an order is filled by the venue, the original order contract, the consumed input TradingBalance(s), and the new output TradingBalance(s) are produced in the same transaction. Detection is therefore as simple as watching for the order's archival.
Recommended Use PQS (Participant Query Store) to subscribe to the relevant template streams.
Without PQS
Query the participant's contracts endpoint directly for active SwapOrder contracts filtered by your actor. When the contract disappears, the fill has occurred; the new TradingBalance is created in the same transaction.
TIP: If you need to surface the fill price to the user, walk the transaction tree that archived the SwapOrder. The same tree contains the new TradingBalance, so you can compute the realized rate directly.
NOTE: Swap orders created with requestTradingBalanceWithdrawal set produce a PhysicalSettlement in the archiving transaction instead of an output TradingBalance. Order-archival detection works identically.
Step 5 - Withdraw funds
When the user is ready to take their tokens back to their wallet, return them using AMMRules_WithdrawTradingBalance. Similar to deposits, this is a two-call sequence.
TIP: If you anticipate that the output of a swap order is the only thing you'd be withdrawing, set requestTradingBalanceWithdrawal when creating the order instead. The output is settled directly to the user's wallet and never lands in a TradingBalance.
Step 5a - Fetch the vault holdings
The withdrawal choice needs a list of holding contract IDs from the vault. Request them for the specific token, amount, and recipient.
Step 5b - Exercise AMMRules_WithdrawTradingBalance (~14.2 kB)
The choice supports both full and partial withdrawals, and consolidates fragmented balances in a single transaction.
NOTE: If the recipient has a transfer pre-approval for the output instrument, the tokens arrive in the recipient's wallet with no further action from you. If the recipient has no pre-approval, the tokens will appear as a transfer offer which the recipient must accept.
4.0 - Type Reference
This is a consolidated list of every choice and template you'll touch as an integrator. Each lives on or is produced by the singleton AMMRules contract.
Choices on AMMRules
AMMRules_AddTradingBalance→ContractId TradingBalanceAMMRules_CreateSwapOrder→ContractId SwapOrderAMMRules_CreateDepositOrder→ContractId DepositOrderAMMRules_CreateWithdrawOrder→ContractId WithdrawOrderAMMRules_WithdrawTradingBalance→TransferInstructionResult
Templates Produced
TradingBalance: per user, per instrument, holds tokens for use in ordersSwapOrder: pending swap; archived on fillDepositOrder: pending LP deposit; archived on fillWithdrawOrder: pending LP redemption; archived on fillPhysicalSettlement: obligation to deliver a direct-settled swap output; created on fill whenrequestTradingBalanceWithdrawalis set
Enums
SwapDirection:Long(buy fixed amount) orShort(sell fixed amount)
Last updated
Was this helpful?
