# Tradecraft Documentation Home

Welcome to your team’s developer platform

<h2 align="center">Pool and trade on Canton.</h2>

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h4><i class="fa-sailboat">:sailboat:</i></h4></td><td><strong>Use the Exchange</strong></td><td>Trade and provide liquidity from your wallet.</td><td><a href="/spaces/dF47DwfCAGYAD1QW2BrD">/spaces/dF47DwfCAGYAD1QW2BrD</a></td><td></td></tr><tr><td><h4><i class="fa-layer-plus">:layer-plus:</i></h4></td><td><strong>Build</strong></td><td>Enable trading and liquidity operations in your apps.</td><td><a href="/spaces/u22wPaJ4JRf27sENGE1r">/spaces/u22wPaJ4JRf27sENGE1r</a></td><td></td></tr><tr><td><h4><i class="fa-money-bill-wave">:money-bill-wave:</i></h4></td><td><strong>Fees and Pricing</strong></td><td>Fees and incentive programs that keep pools deep and supply matched to demand.</td><td><a href="/spaces/zWHYx1iK1OUGL0Uup8qS">/spaces/zWHYx1iK1OUGL0Uup8qS</a></td><td></td></tr><tr><td><h4><i class="fa-comment-question">:comment-question:</i></h4></td><td><strong>Support</strong></td><td>Contact us for support with trading or liquidity.</td><td><a href="/spaces/QYXWXTLPO5lsYynVPkMu">/spaces/QYXWXTLPO5lsYynVPkMu</a></td><td></td></tr><tr><td><h4><i class="fa-shield-check">:shield-check:</i></h4></td><td><strong>Security</strong></td><td>View our external audit reports and security disclosures.</td><td><a href="/spaces/GRH8rEyP66QFKo6jaOG1/pages/kUmL61QtRIkqj4gzdfMI">/spaces/GRH8rEyP66QFKo6jaOG1/pages/kUmL61QtRIkqj4gzdfMI</a></td><td></td></tr></tbody></table>

<h2 align="center">Join a growing community</h2>

<p align="center">News, support, partnerships.</p>

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><h4><i class="fa-x-twitter">:x-twitter:</i></h4></td><td><strong>X.com</strong></td><td>Follow us on X for the latest news.</td><td><a href="https://x.com/TradecraftFi">x.com/TradecraftFi</a></td><td></td></tr><tr><td><h4><i class="fa-envelope">:envelope:</i></h4></td><td><strong>Partnerships</strong></td><td>Token issuers, liquidity providers, wallet builders.</td><td>Email <a href="mailto:partnerships@tradecraft.fi">partnerships@tradecraft.fi</a></td><td></td></tr></tbody></table>


# Get Started

Trade and provide liquidity. Most wallets supported.

Canton ecosystem wallets are not dApp enabled (yet), but we have a solution – Pool Addresses.

{% stepper %}
{% step %}

### <i class="fa-wallet">:wallet:</i> Use a supported wallet.

Interact from any wallet that supports CIP-56 tokens. Check [Wallet Support](/using-tradecraft/wallet-support) (up next).
{% endstep %}

{% step %}

### <i class="fa-paste">:paste:</i> Get the Address.

Browse [Pools & Pool Addresses](/using-tradecraft/pools-and-pool-addresses) and select the pool and Address to manage liquidity or trade.
{% endstep %}

{% step %}

### <i class="fa-arrow-right-arrow-left">:arrow-right-arrow-left:</i> Send & receive.

Offer tokens to the Pool Address, receive your return tokens back to your wallet. Learn more – [What are Pool Addresses?](/using-tradecraft/what-are-pool-addresses)
{% endstep %}
{% endstepper %}


# Wallet Support

Tradecraft can be used from any wallet - however, some wallets do not have full support for the CIP-56 token specification. You will want to check with your wallet before trading for a token that your wallet may not show. In particular, depositing liquidity to a Tradecraft pool will return Tradecraft LP (Liquidity Provider) tokens. Your wallet will need to have general support for CIP-56 tokens in order to show these in your balance.

The list below is not exhaustive.

<table><thead><tr><th width="106.44921875">Wallet</th><th>CIP-56 Token Support</th><th>Website</th><th>Notes</th></tr></thead><tbody><tr><td>Walley</td><td><i class="fa-check">:check:</i> <mark style="color:$success;">Full Support</mark></td><td><a href="https://walley.cc/">walley.cc</a></td><td></td></tr><tr><td>Loop</td><td><i class="fa-check">:check:</i> <mark style="color:$success;">Full Support</mark></td><td><a href="https://cantonloop.com/">cantonloop.com</a></td><td></td></tr><tr><td>Console</td><td><i class="fa-check">:check:</i> <mark style="color:$success;">Full Support</mark></td><td><a href="https://consolewallet.io/">consolewallet.io</a></td><td></td></tr><tr><td>Bron</td><td><i class="fa-check">:check:</i> <mark style="color:$success;">Full Support</mark></td><td><a href="https://bron.org/">bron.org</a></td><td></td></tr><tr><td>Dfns</td><td><i class="fa-check">:check:</i> <mark style="color:$success;">Full Support</mark></td><td><a href="https://www.dfns.co/">www.dfns.co</a></td><td></td></tr><tr><td>Send</td><td><i class="fa-check">:check:</i> <mark style="color:$success;">Full Support</mark></td><td><a href="https://cantonwallet.com/">cantonwallet.com</a></td><td></td></tr><tr><td>HandlPay</td><td> <i class="fa-circle-half-stroke">:circle-half-stroke:</i> Partial Support</td><td><a href="https://handlpay.com/">handlpay.com</a></td><td>Tokens must be whitelisted by HandlPay Wallet before they will appear in the wallet. Check their website for a list of supported tokens.<br><br>Tradecraft LP tokens will not appear in the wallet – do not add liquidity using HandlPay wallet.</td></tr><tr><td>Cansai</td><td> <i class="fa-circle-half-stroke">:circle-half-stroke:</i> Partial Support</td><td><a href="https://cansai.app/">cansai.app</a></td><td></td></tr></tbody></table>


# Pools & Pool Addresses

Pool Addresses for trading and managing liquidity.

[Guide: How to Trade](/using-tradecraft/guide-how-to-trade) [Guide: How to Provide Liquidity](/using-tradecraft/guide-how-to-provide-liquidity) [Guide: How to Remove Liquidity](/using-tradecraft/guide-how-to-remove-liquidity)

### CC/USDCx <mark style="color:$success;">• LIVE</mark>

<i class="fa-arrow-right-arrow-left">:arrow-right-arrow-left:</i> **Swapping Address:**

```
tc-swp_CC-USDCx::122096fe076cc065af0cb38f94caa60e8ddfecbe8f0cfe10655ae7aa06fab99c66b7
```

<i class="fa-inbox-in">:inbox-in:</i> <i class="fa-inbox-out">:inbox-out:</i> **Add/Remove Liquidity Address:**

```
tc-liq_CC-USDCx::122096fe076cc065af0cb38f94caa60e8ddfecbe8f0cfe10655ae7aa06fab99c66b7
```

### CBTC/CC <mark style="color:$success;">• LIVE</mark>

<i class="fa-arrow-right-arrow-left">:arrow-right-arrow-left:</i> **Swapping Address:**

```
tc-swp_CBTC-CC::122096fe076cc065af0cb38f94caa60e8ddfecbe8f0cfe10655ae7aa06fab99c66b7
```

<i class="fa-inbox-in">:inbox-in:</i> <i class="fa-inbox-out">:inbox-out:</i> **Add/Remove Liquidity Address:**

```
tc-liq_CBTC-CC::122096fe076cc065af0cb38f94caa60e8ddfecbe8f0cfe10655ae7aa06fab99c66b7
```


# What are Pool Addresses?

Pool Addresses provide a way to interact with the Tradecraft exchange from your wallet without running a Validator Node and without browser extension wallets that are able to connect to web applications (as none yet exist for the Canton ecosystem).

For each Tradecraft pool we've set up Party IDs that monitor incoming transfer offers and perform specific actions when received. Each action results in a transfer offer back to the user – a swapped asset (trade), LP tokens (add liquidity), or both assets in a pool (remove liquidity).

With Canton Network's transfer proposal feature, assets are safe in your wallet until Tradecraft atomically swaps them, guaranteeing a successful transaction with returned output.

This allows Tradecraft to be used from any wallet that supports CIP-56 tokens (see [Wallet Support](/using-tradecraft/wallet-support)).


# Guide: How to Trade

{% stepper %}
{% step %}

### Use a supported wallet.

See [Wallet Support](/using-tradecraft/wallet-support) for a full list.
{% endstep %}

{% step %}

### Get a price estimate.

Visit [tradecraft.fi](https://tradecraft.fi) and use the trading interface to get an estimate\* for your trade, selecting the two tokens you'd like to trade, and entering the amount you'd like to trade:

<figure><img src="/files/1o84PIyXFIZioJ7nGbGG" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
**\*Important**

Amounts shown are not a guaranteed promise of return. Factors like protocol use and market movements, among others, may result in receiving a different number of tokens than the shown estimate.
{% endhint %}
{% endstep %}

{% step %}

### Send & receive.

Click "Next" to see the Trading Address used for this trade:

<figure><img src="/files/yy1Olhb0v51UAaEbR2Cx" alt=""><figcaption></figcaption></figure>

Any trade between the two tokens you selected in the trading interface can be completed by sending either of the tokens to the displayed Trading Address. For example, the same Tradecraft Pool Address can be used to trade from CC to CBTC, or from CBTC to CC.

From your supported wallet, send a transfer offer of the tokens you'd like to trade to the Trading Address.

Trades are executed on-chain at the current price of the pool, and therefore may be subject to slippage. If you'd like to specify a minimum number of tokens to receive back for the trade, include that number as the first text in the memo field of your transfer. It is a good idea to account for slippage in the minimum you specify, so your trade does not get rejected. For further details, read [Guide: Specifying Minimums](/using-tradecraft/guide-specifying-minimums).

In a minute or two you should receive a return offer of the other token. In most wallets you will need to manually accept the incoming transfer, unless the incoming token is CC.
{% endstep %}
{% endstepper %}

Questions? Check out our [Frequently Asked Questions](/using-tradecraft/frequently-asked-questions) page.


# Guide: Specifying Minimums

Guarantee every trade results in an expected minimum amount of tokens back.

When making a trade with Pool Addresses you may specify a minimum number of tokens to receive in return for your trade. If the minimum cannot be met, the tokens you attempt to trade will be returned.

### **Short Instructions**

1. Generate a fresh quote for a trade using the interface at [tradecraft.fi](https://tradecraft.fi).
2. Copy the number of tokens quoted for the trade and multiply it by a factor of your choosing to account for slippage. For example, multiply by `0.97` to account for 3% slippage. That will be the minimum number of tokens you expect back.
3. When preparing the transfer of tokens to the Tradecraft Pool Address, enter the minimum number in the memo field. Then send the transfer.
4. Your trade will either execute and you'll receive at least the minimum number of tokens — or more if the current price allows — or it will fail because the order cannot be completed at that price, and your tokens will be returned.

### **Step by Step Example**

{% stepper %}
{% step %}

### Generate a fresh trade quote.

Using the interface at [tradecraft.fi](https://tradecraft.fi), see what the current expected return amount is for your desired trade:

<figure><img src="/files/yCfIjRXiIySuH8FAq1y6" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

### Calculate your desired minimum.

Slippage is a term used to describe what can happen between the time you generate a quote and the time your order gets processed on-chain. In that time orders from other traders can be executed, affecting the balance of tokens in the pool and moving the price. Accounting for slippage reduces the chance of your trade being rejected due to price drift.

Commonly used slippage tolerances range from 5% to 0.25% depending on the TVL of the pool. Token balance (and therefore token price) in pools with smaller TVL is affected more by a trade than it is in pools with large TVL.

The formula to calculate the minimum is:\
\
`quote x (1 - slippage/100) = minimum`

For this example, we'll use 3% slippage tolerance:

`14.2742668747 x (1 - 3/100) = minimum`

Simplified, this equation is:

`14.2742668747 x 0.97 = 13.8460388685`&#x20;
{% endstep %}

{% step %}

### Send tokens, with minimum in memo field.

While following the instructions on the quote interface to send tokens to execute your trade, enter the minimum you'd like to receive in the memo field of the transfer.

{% tabs %}
{% tab title="Console Wallet" %}

<div><figure><img src="/files/TDeUeANxNlBo1sGv2u7w" alt=""><figcaption></figcaption></figure> <figure><img src="/files/GmcshLQLXAlInx7v0i12" alt=""><figcaption></figcaption></figure> <figure><img src="/files/05ra1QCABc2Z24nPQL0P" alt=""><figcaption></figcaption></figure></div>
{% endtab %}

{% tab title="Loop Wallet" %}

<div><figure><img src="/files/pCOiu7Qc5QgxgPu43pi8" alt=""><figcaption></figcaption></figure> <figure><img src="/files/iJLHQosSiDbLS5FW5NzU" alt=""><figcaption></figcaption></figure></div>
{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

### Done!

Your trade will be executed at the best possible price available, at or above the minimum specified. If the minimum cannot be met, your tokens will be returned to you instead.
{% endstep %}
{% endstepper %}

### Additional Details

* For a minimum to be honored it must be the first text in the memo field, and have no more than 10 decimal places.
* Minimums may be specified as whole numbers, or decimal numbers.
* You may put additional notes in the memo field after the minimum, separated by a space. For example, `5.25 my extra notes` is a valid memo.


# Guide: How to Provide Liquidity

Provide liquidity to earn a portion of fees from trading activity.

Providing liquidity to Tradecraft pools allows you to earn a portion of trading fees that are generated from all trading activity on that pool.

You can check current pool APRs (based on activity from the last 24 hours) at [tradecraft.fi/pools](https://tradecraft.fi/pools).

{% stepper %}
{% step %}

### Use a supported wallet.

See [Wallet Support](/using-tradecraft/wallet-support) for a full list.
{% endstep %}

{% step %}

### Decide token amounts to pool.

When providing liquidity to a pool, you'll need to deposit both assets in roughly the same amount (in USD value) to the pool.

Visit [tradecraft.fi/pools](https://tradecraft.fi/pools) and click "Add Liquidity" ("+" on mobile) for the pool you'd like to provide liquidity to. You'll see the interface below:

<figure><img src="/files/HaxgZwYZZ6FtXeseVqkC" alt=""><figcaption></figcaption></figure>

Enter an amount of either token to pool and the interface will show you how much of the other token you will need to match that contribution, and also an estimate\* of how many Liquidity Provider (LP) tokens you will receive as a receipt to represent your share of the pools assets.

If you only have one of the two tokens in your wallet, you can use Tradecraft to trade some of your holdings for the token you're missing ([Guide: How to Trade](/using-tradecraft/guide-how-to-trade)).

Adjust the amounts of the two tokens to be deposited until they match the total amount you'd like to contribute.

{% hint style="warning" %}
**\*Important**

Amounts shown are not a guaranteed promise of return. Factors like protocol use and market movements, among others, may result in receiving a different number of tokens than the shown estimate.
{% endhint %}
{% endstep %}

{% step %}

### Send & receive.

From your wallet, offer a transfer of both tokens to the Liquidity Address shown in the interface.

{% hint style="info" %}
**Excess Tokens**

If you send too many or too few of either token, Tradecraft will accept the amounts available in the correct ratio, and automatically return the rest to you along with the LP tokens.
{% endhint %}

In less than a minute you should receive a return offer of LP tokens, named "TC `SYMBOL`/`SYMBOL` LP".  In most wallets you will need to manually accept the incoming transfer.

The LP tokens represent your share of the liquidity pool. To remove your liquidity, send the LP tokens back to the same Liquidity Address. This will initiate the return of your share of the pool's underlying tokens. Again, remember to accept the incoming transfer offer of the two tokens.
{% endstep %}
{% endstepper %}

Questions? Check out our [Frequently Asked Questions](/using-tradecraft/frequently-asked-questions) page.


# Guide: How to Remove Liquidity

{% stepper %}
{% step %}

### Use a supported wallet.

See [Wallet Support](/using-tradecraft/wallet-support) for a full list.
{% endstep %}

{% step %}

### Get the correct Pool Address.

Go to [Pools & Pool Addresses](/using-tradecraft/pools-and-pool-addresses) and copy the "Add/Remove Liquidity" address listed for the pool you'd like to use.
{% endstep %}

{% step %}

### Get returned tokens quote (optional).

Go to the [Liquidity](/api/routes/liquidity) page and click "Test it" for the "Get LP withdrawal quote" API.

Enter the pool's two token symbols in the space for `tokenA` and `tokenB`.

Enter the number of LP tokens you'd like to exchange in `lpTokenAmount` and press "Send".

The output will show you how many of each of the pool's tokens are *currently expected\** in return for the LP tokens.

{% hint style="info" %}
**\*Imporant**

Quoted amounts are not a guaranteed promise of return. Factors like protocol use, among others, may result in receiving a different number of tokens than quoted.
{% endhint %}
{% endstep %}

{% step %}

### Send LP tokens to the Pool Address & receive asset tokens.

From your wallet, send the LP tokens to the Pool Address from step 2.&#x20;

In less than a minute you should receive transfer offers for both of the pool's tokens. Remember to approve the incoming transfers.
{% endstep %}
{% endstepper %}

Questions? Check out our [Frequently Asked Questions](/using-tradecraft/frequently-asked-questions) page.


# Frequently Asked Questions

### Having trouble? We offer white glove support.

Email <info@tradecraft.fi> to connect.

### Sending tokens sounds scary, how am I protected?

The most important question.

The Canton Network is not like most networks where transfers are irrevocable. Instead, when transferring assets on Canton you are really creating a transfer *proposal*.&#x20;

Transfer proposals lock funds so they are ready for transfer, but until the recipient accepts the transfer the tokens stay in your wallet. Our&#x20;

Transfer proposals automatically expire after a configurable period of time (set by your wallet) and the funds returned to your *available* balance, having never left your wallet. Additionally, if your wallet allows, you may revoke transfer proposals at any time before the recipient has accepted.&#x20;

If you "send" (transfer proposal) tokens to a Magic Address and do not promptly get the expected return, you can revoke the offer (if supported by your wallet) or wait for it to automatically expire.

<details>

<summary>What happens if I make a transfer, but your system is down?</summary>

We take extra precautions via monitoring and redundancy to ensure our systems are always online, however, unexpected events can still occur.

If our system is down or taking too long to execute, and if your wallet supports it, you may revoke the transfer proposals to cancel the operation. Alternatively, wait for the transfer proposal to expire automatically.

</details>

<details>

<summary>I sent an asset/token to the wrong address</summary>

If you send tokens to a Pool Address for a pool that does not use that token, Tradecraft will automatically reject your transfer proposal and the funds should once more appear in your available balance.

</details>

<details>

<summary>Adding Liquidity: I sent one asset before deciding not to pool, how do I get my asset back?</summary>

You may revoke the transfer proposal for the first asset you sent, or wait for it to expire automatically.

</details>

<details>

<summary>Adding Liquidity: What happens if I send the wrong amount of either token?</summary>

If you send too much or too little of either token to the Pool Address, Tradecraft will calculate the remainder of either token and send it back to you, after adding both tokens in the correct ratio to the pool.

You'll need to send both tokens before Tradecraft can calculate any remaining amount to be returned, and pool the rest.

</details>


# Integration

Build apps that surface trading and LP features, or use Tradecraft liquidity as a building block for more complex products.

Tradecraft is a permissionless decentralized exchange, open for integration by wallets and other dApps.

{% hint style="warning" %}

## Dependencies

Both of the integration options below require the DA Utility package version 0.12.5 (and/or up to 0.12.9). If you do not have these installed when making trades you will be unable to receive the returning tokens. Additionally you may be automatically put on a temporary blacklist to prevent further trades from being initiated. If you think you may have been blacklisted, [contact us](https://docs.tradecraft.fi/support/get-help).
{% endhint %}

We offer two integration options, with the tradeoffs shown below:

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th></th></tr></thead><tbody><tr><td><h3>Pool Addresses</h3></td><td>Interact using standard Daml <em>TransferOffers</em> and <em>Preapprovals</em>.</td><td><p><i class="fa-check" style="color:$warning;">:check:</i> Trade.</p><p><i class="fa-check" style="color:$warning;">:check:</i> Deposit and withdraw liquidity.</p><p><i class="fa-x" style="color:$danger;">:x:</i> More expensive.</p><p><i class="fa-x" style="color:$danger;">:x:</i> Slower transactions.</p><p><i class="fa-x" style="color:$danger;">:x:</i> Lower TPS capacity.</p><p><i class="fa-x" style="color:$danger;">:x:</i> No flash accounting features.</p><p><i class="fa-x" style="color:$danger;">:x:</i> No built-in leg matching.</p><p><i class="fa-x" style="color:$danger;">:x:</i> No transaction failure insight.</p><p><i class="fa-check" style="color:$warning;">:check:</i> Usable with basic transfer API access (no validator node required).</p></td><td><a href="/spaces/dF47DwfCAGYAD1QW2BrD/pages/jW5Hj6Wfe7wUYd73yrGN">Documentation</a></td></tr><tr><td><h3>Daml Package</h3></td><td>Interact using custom choices from our Tradecraft Daml package.</td><td><p><i class="fa-check" style="color:$warning;">:check:</i> Trade.</p><p><i class="fa-check" style="color:$warning;">:check:</i> Deposit and withdraw liquidity.</p><p><i class="fa-check" style="color:$warning;">:check:</i> Cheaper transactions.</p><p><i class="fa-check" style="color:$warning;">:check:</i> Faster transactions.</p><p><i class="fa-check" style="color:$warning;">:check:</i> Higher TPS capacity.</p><p><i class="fa-check" style="color:$warning;">:check:</i> Flexible flash accounting features.</p><p><i class="fa-check" style="color:$warning;">:check:</i> Leg matching built in.</p><p><i class="fa-check" style="color:$warning;">:check:</i> Transaction failure insight.</p><p><i class="fa-x" style="color:$danger;">:x:</i> Requires a validator node to use.</p></td><td><a href="/pages/acpJhBHDIZ7LWgwDsPv9">Documentation</a></td></tr></tbody></table>

Aside from the above documentation, other helpful documentation includes:

[Guide: Building a Trading Interface](/integrations/integrate-tradecraft/guide-building-a-trading-interface)

[Tradecraft API](/api)


# Guide: DAR Integration

## Building on *Tradecraft*.

**INTEGRATION GUIDE - V1.1.19**\
A developer's reference for integrating the Canton-native AMM into your application. The Tradecraft Daml package is available on request. Contact us by email at <info@tradecraft.fi>.

***

## 1.0 - Overview

### How Tradecraft works

Tradecraft is a decentralized exchange protocol 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.

**`SwapOrder` - `DepositOrder` - `WithdrawOrder`**\
The three order types. Each is created by exercising a choice on AMMRules and consumes the relevant holdings atomically when it fills.

**`TradingBalance`** : *per user, per instrument*\
Vault-held collateral of a single token, owned by the user. Tokens must be inside a TradingBalance before they can be used as collateral for swap order queueing.

#### The high-level workflow

1. **Discover** available trading pairs.
2. **Submit** a SwapOrder, DepositOrder, or WithdrawOrder.
3. **Monitor** the order until it fills.

## 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 Documentation**

* All Environments - `https://docs.tradecraft.fi/api`

**API base**

* Mainnet - `https://api.tradecraft.fi/v1`&#x20;
* Testnet - `https://tradecraft.validator.test.canton.obsidian.systems/amm-http-api`
* Devnet - `https://tradecraft.validator.dev.canton.obsidian.systems/amm-http-api`

**Venue**

* Mainnet - `Tradecraft::122096fe076cc065af0cb38f94caa60e8ddfecbe8f0cfe10655ae7aa06fab99c66b7`
* Testnet - `Tradecraft::122087bab51ae50157a06730e296081f8c941d64ec96f9a2e186e159bae25a553d04`
* Devnet - `Tradecraft::122090f9041ae7a635c8471c7d496cf3158c294c154dd5468b19f8d37e949875203e`

**Vault**

* Mainnet - `cs-vault::1220b4cd6098eebafd4c88efd2b3986e86542bdc391060675432cd195ad26bcf013b`
* Testnet - `tradecraft-vault::1220369596a3a24a39f0f383600508971774e4c63e68fcc01313a0707ed70130be8e`
* Devnet - `decentralized-party::1220b1f5f3fe39721e02a886b36a5a57dc215f5d2de275d9823107bcd825b186689d`

## 3.0 - The Integration Workflow

### 3.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.

```shell
$ curl https://api.tradecraft.fi/v1/pools | jq
```

{% hint style="info" %}
**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.
{% endhint %}

### 3.2 - 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.

{% hint style="info" %}
**NOTE:** There is now an [API endpoint for token allocation factory](https://docs.tradecraft.fi/api/routes/tokens#get-allocation-factory-token), which may be required for some of the steps described below. See <https://docs.tradecraft.fi/api> for more information.
{% endhint %}

#### 3.2.1 - Swap orders: *exchanging two tokens via a pool*

Most integrations will spend the majority of their time here. This call allocates the input amount from the actor's wallet holdings and creates the `SwapOrder` atomically. On fill, the input is consumed and the output settles to the actor's wallet.

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`.

{% hint style="danger" %}

#### **Critical safety notice:&#x20;*****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, missing pre-approval = **loss of funds**.
{% endhint %}

We highly recommend you test this version of swap order creation on testnet, confirming that tokens are received in the destination wallet before going live.

**Choice Signature**

<pre class="language-daml"><code class="lang-daml"><strong>nonconsuming choice AMMRules_CreateSwapOrderFromHoldingsV2 : AMMRules_CreateSwapOrderFromHoldingsV2_Result
</strong><strong>  with
</strong>    actor : Party
      -- ^ The user performing the swap
    ammId : Text
      -- ^ Identifies which AMM pool this order is for, as returned by /pools
    what : SwapDirection
      -- ^ Direction and amount of swap. Short only - see NOTE below.
    minOut : Optional Decimal
      -- ^ Minimum output amount (slippage protection)
    holdingCids : [ContractId Holding]
      -- ^ The actor's wallet holdings of the input instrument. Holdings in
      --   excess of the swap amount are returned to the actor as change.
    allocationContext : (ContractId AllocationFactory, ExtraArgs)
      -- ^ The input instrument's AllocationFactory and its ExtraArgs, used to
      --   allocate the input amount from the holdings to the vault
</code></pre>

**Result Type**

```daml
data AMMRules_CreateSwapOrderFromHoldingsV2_Result = AMMRules_CreateSwapOrderFromHoldingsV2_Result
  with
    swapOrderCid : ContractId V2.SwapOrder
      -- ^ The pending order (the same queryable SwapOrder template shown above)
    changeCids : [ContractId Holding]
      -- ^ Wallet change : input holdings in excess of the swap amount
```

{% hint style="info" %}
**NOTE:** Only `Short` is currently supported. `Long` orders fail with `"Only short orders are currently supported"`.
{% endhint %}

{% hint style="warning" %}
**Reminder : no pre-approval on the output token = the swap will execute but no funds will be returned.**
{% endhint %}

#### 3.2.2 - Deposit orders: *adding liquidity to a pool* (\~5.2 kB)

This choice deposits liquidity into a pool and mints LP tokens, into a TradingBalance. Both `amount1` and `amount2` must already exist as funded TradingBalances for the actor.

**Choice Signature**

```daml
nonconsuming choice AMMRules_CreateDepositOrder : ContractId DepositOrder
  with
    actor : Party
    ammId : Text
    amount1 : Decimal
    amount2 : Decimal
    minOut : Optional Decimal
    changeAmounts : Optional [InstrumentAmount]
```

**Resulting Template (Queryable)**

```daml
template DepositOrder
  with
    actor : Party
      -- ^ The party requesting the deposit
    venue : Party
    vault : Party
    ammId : Text
      -- ^ Identifies which AMM pool this deposit is for
    amount1 : Decimal
      -- ^ Amount of instrument1 to deposit (must be pre-funded in TradingBalance)
    amount2 : Decimal
      -- ^ Amount of instrument2 to deposit (must be pre-funded in TradingBalance)
    createdAt : Time
    minOut : Optional Decimal
```

{% hint style="warning" %}
**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}`.
{% endhint %}

#### 3.2.3 - Withdraw orders: *removing liquidity from a pool* (\~5.2 kB)

This choice removes liquidity from a pool, and puts the withdrawn tokens into a TradingBalance. The LP tokens must already exist as a funded TradingBalance for the actor.

**Choice Signature**

```daml
nonconsuming choice AMMRules_CreateWithdrawOrder : ContractId WithdrawOrder
  with
    actor : Party
    ammId : Text
    lpTokenAmount : Decimal
    minAmount1 : Optional Decimal
    minAmount2 : Optional Decimal
```

**Resulting Template (Queryable)**

```daml
template WithdrawOrder
  with
    actor : Party
      -- ^ The party requesting the withdrawal
    venue : Party
    vault : Party
    ammId : Text
      -- ^ Identifies which AMM pool this withdrawal is for
    lpTokenAmount : Decimal
      -- ^ Amount of LP tokens to burn (from TradingBalance)
    minAmount1 : Optional Decimal
      -- ^ Minimum amount of instrument1 to receive
    minAmount2 : Optional Decimal
      -- ^ Minimum amount of instrument2 to receive
    createdAt : Time
```

{% hint style="info" %}
**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.
{% endhint %}

### 3.3 - Monitor for filled orders

When an order is filled by the venue, the original order contract, the consumed input(s), and the new output(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.

### 3.4  - Add TradingBalance (Optional): *providing collateral for swap order queuing*

Before a user can submit queued trades, they must have collateral inside a `TradingBalance` contract. This is a two-call sequence. Fetch the disclosure for the AMMRules contract, then exercise the deposit choice.

#### 3.4.1 - 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.

```shell
$ curl https://api.tradecraft.fi/v1/disclosures/CBTC/CC | jq ".amm_rules"
```

#### 3.4.2 - Exercise `AMMRules_AddTradingBalance` (\~10.5 kB)

With the disclosure in hand, exercise the add choice. The user is the actor; their wallet's allocation context provides the tokens.

**Choice Signature**

```daml
nonconsuming choice AMMRules_AddTradingBalance : ContractId TradingBalance
  with
    actor : Party
      -- ^ The user depositing tokens
    allocationContext : (ContractId Allocation, ExtraArgs)
      -- ^ Allocation of tokens the actor is transferring to the vault
    existingBalances : [ContractId TradingBalance]
      -- ^ Existing balances to consolidate with this one
  controller actor
```

{% hint style="info" %}
**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.
{% endhint %}

### 3.5  - Withdraw TradingBalance (Optional): *removing collateral*

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.

#### 3.5.1 - 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.

```shell
$ curl -s -X POST \
    https://api.tradecraft.fi/v1/vault-holdings \
    -H 'Content-Type: application/json' \
    -d '{
      "token": "CC",
      "amount": 1.0,
      "vault": "cs-vault::1220b4cd6098eebafd4c88efd2b3986e86542bdc391060675432cd195ad26bcf013b",
      "receiver": "YourParty::YourNode"
    }' | jq
```

#### 3.5.2 - Exercise `AMMRules_WithdrawTradingBalance` (\~14.2 kB)

The choice supports both full and partial withdrawals, and consolidates fragmented balances in a single transaction.

```daml
nonconsuming choice AMMRules_WithdrawTradingBalance : TransferInstructionResult
  with
    actor : Party
    tradingBalanceCids : [ContractId TradingBalance]
      -- ^ TradingBalances to withdraw from. All will be archived;
      --   they must share the same actor and instrument.
      --   Multi-input is supported : fragmented balances are consolidated.
    amount : Optional Decimal
      -- ^ None = withdraw the full consolidated balance.
      --   Some x = partial withdrawal; remainder stays in a new TradingBalance.
    recipient : Party
      -- ^ Who to send the tokens to
    instrumentTransferInfo : InstrumentTransferInfo
      -- ^ Transfer infrastructure (TransferFactory, expectedAdmin, etc.)
    holdingCids : [ContractId Holding]
      -- ^ The holdings returned by /vault-holdings
```

{% hint style="info" %}
**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.
{% endhint %}

## 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_CreateSwapOrderFromHoldingsV2` → `AMMRules_CreateSwapOrderFromHoldingsV2_Result`&#x20;
  * contains `ContractId V2.SwapOrder` + `[ContractId Holding]`
* `AMMRules_CreateDepositOrder` → `ContractId DepositOrder`
* `AMMRules_CreateWithdrawOrder` → `ContractId WithdrawOrder`
* `AMMRules_AddTradingBalance` → `ContractId TradingBalance`
* `AMMRules_WithdrawTradingBalance` → `TransferInstructionResult`

**Templates Produced**

* `SwapOrder` : pending swap; archived on fill
* `DepositOrder` : pending LP deposit; archived on fill
* `WithdrawOrder` : pending LP redemption; archived on fill
* `TradingBalance` : per user, per instrument, holds tokens to enable order queueing

**Enums**

* `SwapDirection` : `Long` (buy fixed amount) or `Short` (sell fixed amount)


# Guide: Building a Trading Interface

## Token Support

If your wallet fully supports CIP-56 tokens you can freely integrate all Tradecraft pools for trading, along with add and remove liquidity options (which return CIP-56 compliant Tradecraft LP tokens).

If your wallet supports only a whitelist of Canton tokens you will need to manually limit your interface to only allow trading of your wallet's supported tokens.

## Pools API

To build a trading interface that supports all pools listed on Tradecraft, start by using the [Pools](/api/routes/pools#get-pools) API to fetch a list of all pools. Note that multi-hop trades are not yet supported.&#x20;

To get a list of tradable token pairs for a given token, run a reduce function on the list of pools and construct a mapping of each unique token to a list of other tokens. Every time a token appears in a pool entry, add its paired token to its list of tradable tokens. With the two pools we have online now, your output would look like this:

```javascript
const tradableTokens = {
    'CC': ['USDCx', 'CBTC'],
    'USDCx': ['CC'],
    'CBTC': ['CC']
}
```

Now you can create a widget with token drop-downs similar to a standard swap widget that looks something like the below image. Each entry in `tradableTokens` can be added to the first drop-down, and the second drop-down can be populated with the array value for that token.

<figure><img src="/files/1o84PIyXFIZioJ7nGbGG" alt=""><figcaption></figcaption></figure>

## Quote API

{% hint style="warning" %}
**Important**

While the API is currently named "quote", these quotes should be presented to users as *estimates*. Since the on-chain portion of a trade is only initiated after the user sends funds and after Tradecraft gets to their order and begins execution, the price returned from the quote API may not be the price the user receives, unless a limit is specified for the trade.
{% endhint %}

There are two API's for getting trade quotes–one to specify amount in, and one to specify amount out. Use either or both as your interface requires. For example in the widget above, the API for amount in would be used when the user types in the first input, showing response in the second, and when the user types in the second input, the response would be shown in the first input. Both APIs can be found on the [Quotes](/api/routes/quotes) API page.

## Initiating a Trade

There are two options for executing trades, both introduced on the [Integration](/integrations) page.&#x20;

For the Daml package integration option, see [Guide: DAR Integration](/integrations/integrate-tradecraft/guide-dar-integration).

For Pool Addresses, see [Pool Addresses](https://docs.tradecraft.fi/using-tradecraft/).


# Tradecraft API

Discover pools, pricing and liquidity programmatically.

The Tradecraft API is open for public use.

Contact <info@tradecraft.fi> for support.


# Changelog

## v0.0.16 Initial Release

### Available Data

* API health check
* List of pools and pool holdings
* Token details
* Current pool asset prices
* Fee rates
* Trade quotes
* Add and withdraw liquidity quotes


# Health

Health check endpoints.

## Health check

> Returns the health status of the API server.

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Health","description":"Health check endpoints."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/health":{"get":{"summary":"Health check","description":"Returns the health status of the API server.","operationId":"getHealth","tags":["Health"],"responses":{"200":{"description":"Server is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"}}}}}}}}}}}
```


# Pools

Liquidity Pool information and listing.

## List all liquidity pools

> Returns information about all available liquidity pools.

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Pools","description":"Liquidity Pool information and listing."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/pools":{"get":{"summary":"List all liquidity pools","description":"Returns information about all available liquidity pools.","operationId":"listPools","tags":["Pools"],"responses":{"200":{"description":"List of liquidity pools","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListPoolsResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"ListPoolsResponse":{"type":"object","required":["pools"],"properties":{"pools":{"type":"array","items":{"$ref":"#/components/schemas/PoolInfo"},"description":"Array of pool information objects."}}},"PoolInfo":{"type":"object","required":["token1","token2","lp_token_name","token1_holdings","token2_holdings","total_lp_tokens","lp_fee_percent","operator_fee_percent"],"properties":{"token1":{"type":"string","description":"The symbol/code of the first token in the pool."},"token2":{"type":"string","description":"The symbol/code of the second token in the pool."},"lp_token_name":{"type":"string","description":"The liquidity pool token name/identifier."},"token1_holdings":{"type":"number","format":"double","description":"Amount of token1 held in the pool."},"token2_holdings":{"type":"number","format":"double","description":"Amount of token2 held in the pool."},"total_lp_tokens":{"type":"number","format":"double","description":"Total supply of LP tokens for this pool."},"lp_fee_percent":{"type":"number","format":"double","description":"Liquidity provider fee as a percentage (e.g., 0.3 means 0.3%)."},"operator_fee_percent":{"type":"number","format":"double","description":"Operator fee as a percentage (e.g., 0.1 means 0.1%)."},"yield24h":{"type":"number","format":"double","nullable":true,"description":"24-hour annualized yield (APY) for the pool. Null if unavailable."}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## Get a liquidity pool's ID

> Returns the liquidity pool identifier for a token pair.

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Pools","description":"Liquidity Pool information and listing."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/ammid/{tokenA}/{tokenB}":{"get":{"summary":"Get a liquidity pool's ID","description":"Returns the liquidity pool identifier for a token pair.","operationId":"getAmmId","tags":["Pools"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"}],"responses":{"200":{"description":"Liquidity pool ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AmmIdResponse"}}}},"400":{"description":"Liquidity pool not found or invalid token names given","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"AmmIdResponse":{"type":"object","required":["amm_id"],"properties":{"amm_id":{"type":"string","description":"The AMM pool identifier"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## Get liquidity pool state

> Returns detailed information about the liquidity pool state including holdings, supply, and the constant product K.

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Pools","description":"Liquidity Pool information and listing."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/inspect/{tokenA}/{tokenB}":{"get":{"summary":"Get liquidity pool state","description":"Returns detailed information about the liquidity pool state including holdings, supply, and the constant product K.","operationId":"inspectAmm","tags":["Pools"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"}],"responses":{"200":{"description":"Pool state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AmmInspectResponse"}}}},"400":{"description":"Pool not found or token unknown","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"AmmInspectResponse":{"type":"object","description":"Detailed AMM pool state (V4 contract format).","required":["total_lp_token_supply","token_a_id","token_a_holdings","token_b_id","token_b_holdings","k","unclaimed_operator_fees","updated_at"],"properties":{"total_lp_token_supply":{"type":"number","format":"double","description":"Total supply of LP tokens."},"token_a_id":{"type":"string","description":"Identifier for token A."},"token_a_holdings":{"type":"number","format":"double","description":"Amount of token A in the pool."},"token_b_id":{"type":"string","description":"Identifier for token B."},"token_b_holdings":{"type":"number","format":"double","description":"Amount of token B in the pool."},"k":{"type":"number","format":"double","description":"The constant product (token_a_holdings * token_b_holdings)."},"unclaimed_operator_fees":{"type":"number","format":"double","description":"Accumulated operator fees awaiting claim (V4)."},"updated_at":{"type":"string","format":"date-time","description":"Timestamp of the last pool operation (V4)."}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## Get pool disclosures

> Returns disclosed contract blobs for the pool's AMM, AMMFees, AMMRules, LP instrument config,\
> allocation factory, and featured app right contracts. These disclosures are required by clients\
> to submit transactions (swaps, deposits, withdrawals) against the pool.<br>

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Pools","description":"Liquidity Pool information and listing."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/disclosures/{tokenA}/{tokenB}":{"get":{"summary":"Get pool disclosures","description":"Returns disclosed contract blobs for the pool's AMM, AMMFees, AMMRules, LP instrument config,\nallocation factory, and featured app right contracts. These disclosures are required by clients\nto submit transactions (swaps, deposits, withdrawals) against the pool.\n","operationId":"getPoolDisclosures","tags":["Pools"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"}],"responses":{"200":{"description":"Pool disclosures","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoolDisclosuresResponse"}}}},"404":{"description":"Pool not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"PoolDisclosuresResponse":{"type":"object","description":"Disclosed contracts needed to submit transactions against this pool.\nIncludes the AMM, fees, rules, LP instrument config, allocation factory,\nand optionally the featured app right contract.\n","required":["amm","amm_fees","instrument_config","allocation_factory","amm_data","amm_fees_data"],"properties":{"amm":{"$ref":"#/components/schemas/DisclosedContract"},"amm_fees":{"$ref":"#/components/schemas/DisclosedContract"},"amm_rules":{"$ref":"#/components/schemas/DisclosedContract"},"instrument_config":{"$ref":"#/components/schemas/DisclosedContract"},"allocation_factory":{"$ref":"#/components/schemas/DisclosedContract"},"featured_app_right":{"$ref":"#/components/schemas/DisclosedContract"},"amm_data":{"type":"object","description":"Parsed V4 AMM contract data"},"amm_fees_data":{"type":"object","description":"Parsed V4 AMMFees contract data"},"amm_rules_data":{"type":"object","description":"Parsed AMMRules contract data (if present)"},"featured_app_right_id":{"type":"string","nullable":true,"description":"Contract ID of the FeaturedAppRight (if present)"}}},"DisclosedContract":{"type":"object","description":"A disclosed contract blob from the Canton ledger, required for submitting transactions.","required":["templateId","contractId","createdEventBlob","synchronizerId"],"properties":{"templateId":{"type":"string","description":"Fully qualified template identifier (packageId:moduleName:entityName)"},"contractId":{"type":"string","description":"The contract ID on the ledger"},"createdEventBlob":{"type":"string","format":"byte","description":"Base64-encoded created event blob"},"synchronizerId":{"type":"string","description":"The synchronizer (domain) ID where this contract lives"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```


# Tokens

Token and instrument information.

## Get Token A information

> Returns token information for the first token in the liquidity pool. Note that this is not always the first token in the pool name.

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Tokens","description":"Token and instrument information."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/tokenA/{tokenA}/{tokenB}":{"get":{"summary":"Get Token A information","description":"Returns token information for the first token in the liquidity pool. Note that this is not always the first token in the pool name.","operationId":"getTokenA","tags":["Tokens"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"}],"responses":{"200":{"description":"Token A information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"400":{"description":"AMM not found or token unknown","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"TokenResponse":{"type":"object","description":"Token information response.","required":["instrument_id","instrument_info"],"properties":{"instrument_id":{"$ref":"#/components/schemas/InstrumentId"},"instrument_info":{"$ref":"#/components/schemas/InstrumentInfo"}}},"InstrumentId":{"type":"object","description":"Unique identifier for a financial instrument.","required":["admin","id"],"properties":{"admin":{"type":"string","description":"The party administering the instrument"},"id":{"type":"string","description":"The instrument identifier"}}},"InstrumentInfo":{"type":"object","description":"Extended information about a financial instrument.","required":["instrument_id","registry_url"],"properties":{"instrument_id":{"$ref":"#/components/schemas/InstrumentId"},"registry_url":{"type":"string","format":"uri","description":"URL of the token registry"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## Get Token B information

> Returns token information for the second token in the pool. Note that this is not always the second token in the pool name.

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Tokens","description":"Token and instrument information."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/tokenB/{tokenA}/{tokenB}":{"get":{"summary":"Get Token B information","description":"Returns token information for the second token in the pool. Note that this is not always the second token in the pool name.","operationId":"getTokenB","tags":["Tokens"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"}],"responses":{"200":{"description":"Token B information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"400":{"description":"AMM not found or token unknown","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"TokenResponse":{"type":"object","description":"Token information response.","required":["instrument_id","instrument_info"],"properties":{"instrument_id":{"$ref":"#/components/schemas/InstrumentId"},"instrument_info":{"$ref":"#/components/schemas/InstrumentInfo"}}},"InstrumentId":{"type":"object","description":"Unique identifier for a financial instrument.","required":["admin","id"],"properties":{"admin":{"type":"string","description":"The party administering the instrument"},"id":{"type":"string","description":"The instrument identifier"}}},"InstrumentInfo":{"type":"object","description":"Extended information about a financial instrument.","required":["instrument_id","registry_url"],"properties":{"instrument_id":{"$ref":"#/components/schemas/InstrumentId"},"registry_url":{"type":"string","format":"uri","description":"URL of the token registry"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## Get LP Token information

> Returns instrument information for the liquidity provider token of the pool.

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Tokens","description":"Token and instrument information."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/lpToken/{tokenA}/{tokenB}":{"get":{"summary":"Get LP Token information","description":"Returns instrument information for the liquidity provider token of the pool.","operationId":"getLpToken","tags":["Tokens"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"}],"responses":{"200":{"description":"LP Token information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"400":{"description":"LP token not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"TokenResponse":{"type":"object","description":"Token information response.","required":["instrument_id","instrument_info"],"properties":{"instrument_id":{"$ref":"#/components/schemas/InstrumentId"},"instrument_info":{"$ref":"#/components/schemas/InstrumentInfo"}}},"InstrumentId":{"type":"object","description":"Unique identifier for a financial instrument.","required":["admin","id"],"properties":{"admin":{"type":"string","description":"The party administering the instrument"},"id":{"type":"string","description":"The instrument identifier"}}},"InstrumentInfo":{"type":"object","description":"Extended information about a financial instrument.","required":["instrument_id","registry_url"],"properties":{"instrument_id":{"$ref":"#/components/schemas/InstrumentId"},"registry_url":{"type":"string","format":"uri","description":"URL of the token registry"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## List the physically settled tokens

> Returns the token symbols the venue settles into a holding.\
> Swap output in any other token goes to a trading balance.<br>

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Tokens","description":"Token and instrument information."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/physicalSettlementWhitelist":{"get":{"summary":"List the physically settled tokens","description":"Returns the token symbols the venue settles into a holding.\nSwap output in any other token goes to a trading balance.\n","operationId":"getPhysicalSettlementWhitelist","tags":["Tokens"],"responses":{"200":{"description":"The physically settled tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PhysicalSettlementWhitelistResponse"}}}}}}}},"components":{"schemas":{"PhysicalSettlementWhitelistResponse":{"type":"object","required":["physical_settlement_whitelist"],"properties":{"physical_settlement_whitelist":{"type":"array","description":"Token symbols the venue settles into a holding.\nSwap output in any other token goes to the actor's trading balance.\n","items":{"type":"string"}}}}}}}
```

## Get a token's allocation factory context

> Returns the registry's allocation-factory contract for a token and the choice context\
> for exercising AllocationFactory\_Allocate on it. Cached, refreshed every 24 hours.\
> CC/Amulet is not served. Read it from the Splice Scan API per submission.<br>

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Tokens","description":"Token and instrument information."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/allocation-factory/{token}":{"get":{"summary":"Get a token's allocation factory context","description":"Returns the registry's allocation-factory contract for a token and the choice context\nfor exercising AllocationFactory_Allocate on it. Cached, refreshed every 24 hours.\nCC/Amulet is not served. Read it from the Splice Scan API per submission.\n","operationId":"getAllocationFactoryContext","tags":["Tokens"],"parameters":[{"$ref":"#/components/parameters/token"}],"responses":{"200":{"description":"Allocation factory context","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AllocationFactoryResponse"}}}},"400":{"description":"The token is missing, malformed, unknown, or is CC/Amulet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"No context is available for this token right now.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"token":{"name":"token","in":"path","required":true,"description":"The name/symbol of the token (URL encoded).","schema":{"type":"string"}}},"schemas":{"AllocationFactoryResponse":{"type":"object","description":"The registry's allocation-factory contract and the context for exercising it.","required":["factoryId","choiceContext","cachedAt"],"properties":{"factoryId":{"type":"string","description":"Contract ID to exercise AllocationFactory_Allocate on"},"choiceContext":{"type":"object","description":"The registry's choice-context envelope, not a Daml ChoiceContext.","required":["disclosedContracts","choiceContextData"],"properties":{"disclosedContracts":{"type":"array","description":"Disclosures for the submission, not for ExtraArgs","items":{"$ref":"#/components/schemas/DisclosedContract"}},"choiceContextData":{"type":"object","description":"The Daml ChoiceContext to pass as ExtraArgs.context"}}},"cachedAt":{"type":"string","format":"date-time","description":"When this context was last fetched from the registry"}}},"DisclosedContract":{"type":"object","description":"A disclosed contract blob from the Canton ledger, required for submitting transactions.","required":["templateId","contractId","createdEventBlob","synchronizerId"],"properties":{"templateId":{"type":"string","description":"Fully qualified template identifier (packageId:moduleName:entityName)"},"contractId":{"type":"string","description":"The contract ID on the ledger"},"createdEventBlob":{"type":"string","format":"byte","description":"Base64-encoded created event blob"},"synchronizerId":{"type":"string","description":"The synchronizer (domain) ID where this contract lives"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```


# Prices

Price and ratio queries.

## Get price ratio

> Returns the current price ratio of token B in terms of token A. Note that token A and token B do not always correlate to the first and second tokens in the pool name.

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Prices","description":"Price and ratio queries."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/ratio/{tokenA}/{tokenB}":{"get":{"summary":"Get price ratio","description":"Returns the current price ratio of token B in terms of token A. Note that token A and token B do not always correlate to the first and second tokens in the pool name.","operationId":"getRatio","tags":["Prices"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"}],"responses":{"200":{"description":"Price ratio","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RatioResponse"}}}},"400":{"description":"AMM not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"RatioResponse":{"type":"object","required":["price_of_b_in_a"],"properties":{"price_of_b_in_a":{"type":"number","format":"double","description":"The price of token B expressed in token A (tokenB_holdings / tokenA_holdings)."}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```


# Fees

Fee information.

## Get fee amounts

> Returns the liquidity provider fee and operator fee percentages for the pool.

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Fees","description":"Fee information."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/feeAmount/{tokenA}/{tokenB}":{"get":{"summary":"Get fee amounts","description":"Returns the liquidity provider fee and operator fee percentages for the pool.","operationId":"getFeeAmount","tags":["Fees"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"}],"responses":{"200":{"description":"Fee amounts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeeAmountResponse"}}}},"400":{"description":"Liquidity pool fees contract not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"FeeAmountResponse":{"type":"object","required":["fee_amount","operator_fee_amount"],"properties":{"fee_amount":{"type":"number","format":"double","description":"Liquidity provider fee percentage."},"operator_fee_amount":{"type":"number","format":"double","description":"Operator fee percentage."}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## Get the Trade Discount Cap

> Returns the Trade Discount Cap in USD. Trades whose USD size is at or\
> below this value qualify for the reduced swap fee. Integrations\
> can poll this endpoint to dynamically size their trades so they always\
> qualify for the fee rebate. See <https://docs.tradecraft.fi/fees-and-pricing>.<br>

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Fees","description":"Fee information."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/tradeDiscountCap":{"get":{"summary":"Get the Trade Discount Cap","description":"Returns the Trade Discount Cap in USD. Trades whose USD size is at or\nbelow this value qualify for the reduced swap fee. Integrations\ncan poll this endpoint to dynamically size their trades so they always\nqualify for the fee rebate. See https://docs.tradecraft.fi/fees-and-pricing.\n","operationId":"getTradeDiscountCap","tags":["Fees"],"responses":{"200":{"description":"The Trade Discount Cap","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TradeDiscountCapResponse"}}}},"404":{"description":"Trade Discount Cap is not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"TradeDiscountCapResponse":{"type":"object","required":["trade_discount_cap_usd"],"properties":{"trade_discount_cap_usd":{"type":"number","format":"double","description":"Maximum trade size, in USD, that still qualifies for the\nfee discount. Trades at or below this size receive the reduced swap fee.\n"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```


# Quotes

Trade quote calculations.

## Get trade quote for fixed input

> Calculate how much of token B the user will receive when providing a fixed amount of token A.\
> Uses the constant product formula with double-sided fees.\
> &#x20;Note that token A and token B do not always correlate to the first and second tokens in the pool name.<br>

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Quotes","description":"Trade quote calculations."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/quoteForFixedInput/{tokenA}/{tokenB}":{"get":{"summary":"Get trade quote for fixed input","description":"Calculate how much of token B the user will receive when providing a fixed amount of token A.\nUses the constant product formula with double-sided fees.\n Note that token A and token B do not always correlate to the first and second tokens in the pool name.\n","operationId":"getQuoteTradeFixedInput","tags":["Quotes"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"},{"name":"givingAmount","in":"query","required":true,"description":"The amount of token A the user is giving","schema":{"type":"number","format":"double","minimum":0,"exclusiveMinimum":true}}],"responses":{"200":{"description":"Trade quote","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteTradeFixedInputResponse"}}}},"400":{"description":"Invalid parameters or AMM not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"QuoteTradeFixedInputResponse":{"type":"object","required":["user_gets"],"properties":{"user_gets":{"type":"number","format":"double","description":"The amount of output token the user will receive."}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## Get trade quote for fixed output

> Calculate how much of token A the user must provide to receive a fixed amount of token B.\
> Uses the constant product formula with double-sided fees.\
> &#x20;Note that token A and token B do not always correlate to the first and second tokens in the pool name.<br>

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Quotes","description":"Trade quote calculations."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/quoteForFixedOutput/{tokenA}/{tokenB}":{"get":{"summary":"Get trade quote for fixed output","description":"Calculate how much of token A the user must provide to receive a fixed amount of token B.\nUses the constant product formula with double-sided fees.\n Note that token A and token B do not always correlate to the first and second tokens in the pool name.\n","operationId":"getQuoteTradeFixedOutput","tags":["Quotes"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"},{"name":"gettingAmount","in":"query","required":true,"description":"The amount of token B the user wants to receive","schema":{"type":"number","format":"double","minimum":0,"exclusiveMinimum":true}}],"responses":{"200":{"description":"Trade quote","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteTradeFixedOutputResponse"}}}},"400":{"description":"Invalid parameters or AMM not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"QuoteTradeFixedOutputResponse":{"type":"object","required":["user_gives"],"properties":{"user_gives":{"type":"number","format":"double","description":"The amount of input token the user must provide."}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```


# Liquidity

Liquidity provider operations.

## Get liquidity withdrawal quote

> Calculate how much of each token the user will receive when redeeming LP tokens.

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Liquidity","description":"Liquidity provider operations."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/quoteLPWithdrawal/{tokenA}/{tokenB}":{"get":{"summary":"Get liquidity withdrawal quote","description":"Calculate how much of each token the user will receive when redeeming LP tokens.","operationId":"getQuoteLiquidityWithdrawal","tags":["Liquidity"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"},{"name":"lpTokenAmount","in":"query","required":true,"description":"The amount of LP tokens to redeem","schema":{"type":"number","format":"double","minimum":0,"exclusiveMinimum":true}}],"responses":{"200":{"description":"Liquidity withdrawal quote","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteLPWithdrawalResponse"}}}},"400":{"description":"Invalid parameters or liquidity pool not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"QuoteLPWithdrawalResponse":{"type":"object","required":["amount_instrument_1","amount_instrument_2"],"properties":{"amount_instrument_1":{"type":"number","format":"double","description":"Amount of instrument 1 to receive."},"amount_instrument_2":{"type":"number","format":"double","description":"Amount of instrument 2 to receive."}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## Get liquidity deposit quote

> Calculate the maximum LP tokens that can be minted given the provided amounts of both instruments.\
> Returns the optimal deposit amounts maintaining the pool ratio.<br>

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Liquidity","description":"Liquidity provider operations."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/quoteLPDeposit/{tokenA}/{tokenB}":{"get":{"summary":"Get liquidity deposit quote","description":"Calculate the maximum LP tokens that can be minted given the provided amounts of both instruments.\nReturns the optimal deposit amounts maintaining the pool ratio.\n","operationId":"getQuoteLiquidityDeposit","tags":["Liquidity"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"},{"name":"instrument1Amount","in":"query","required":true,"description":"The amount of instrument 1 available for deposit","schema":{"type":"number","format":"double","minimum":0}},{"name":"instrument2Amount","in":"query","required":true,"description":"The available amount of instrument 2 available for deposit","schema":{"type":"number","format":"double","minimum":0}}],"responses":{"200":{"description":"Liquidity deposit quote","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteLPDepositResponse"}}}},"400":{"description":"Invalid parameters or liquidity pool not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"QuoteLPDepositResponse":{"type":"object","required":["lp_tokens_to_mint","instrument_1_to_deposit","instrument_2_to_deposit"],"properties":{"lp_tokens_to_mint":{"type":"number","format":"double","description":"Amount of LP tokens that will be minted."},"instrument_1_to_deposit":{"type":"number","format":"double","description":"Amount of instrument 1 required for deposit."},"instrument_2_to_deposit":{"type":"number","format":"double","description":"Amount of instrument 2 required for deposit."}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## Get pool yield/APY

> Returns annualized percentage yield (APY) calculations for the pool across multiple time periods.\
> APY is calculated based on the growth of value per LP token (k / lpSupply) over time.\
> Requires Apollo DB connection for historical data; returns empty yield data if unavailable.<br>

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Liquidity","description":"Liquidity provider operations."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/yield/{tokenA}/{tokenB}":{"get":{"summary":"Get pool yield/APY","description":"Returns annualized percentage yield (APY) calculations for the pool across multiple time periods.\nAPY is calculated based on the growth of value per LP token (k / lpSupply) over time.\nRequires Apollo DB connection for historical data; returns empty yield data if unavailable.\n","operationId":"getPoolYield","tags":["Liquidity"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"}],"responses":{"200":{"description":"Pool yield data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoolYieldResponse"}}}},"400":{"description":"AMM not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"PoolYieldResponse":{"type":"object","required":["pool_id","yield"],"properties":{"pool_id":{"type":"string","description":"The AMM pool identifier"},"yield":{"type":"object","additionalProperties":{"type":"number","format":"double"},"description":"Map of time period labels to annualized percentage yield (APY) values.\nKeys are time periods (1h, 4h, 12h, 1d, 2d, 3d, 7d, 14d, 30d).\nValues are APY as decimals (e.g., 0.05 = 5% APY).\nA value of 0 indicates insufficient data for that period.\n"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## Get historical yield/APY over time

> Returns an array of timestamped APY data points for the pool.\
> Each data point represents the annualized yield during that time interval,\
> calculated based on the growth of value per LP token (sqrt(k) / lpSupply).\
> Timestamps are aligned to interval boundaries (e.g., top of minute, top of hour, midnight).\
> \
> Available windows:\
> \- hour: 60 data points at 1-minute intervals\
> \- day: 288 data points at 5-minute intervals\
> \- week: 168 data points at 1-hour intervals\
> \
> Requires Apollo DB connection for historical data.<br>

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Liquidity","description":"Liquidity provider operations."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/yield_history/{tokenA}/{tokenB}":{"get":{"summary":"Get historical yield/APY over time","description":"Returns an array of timestamped APY data points for the pool.\nEach data point represents the annualized yield during that time interval,\ncalculated based on the growth of value per LP token (sqrt(k) / lpSupply).\nTimestamps are aligned to interval boundaries (e.g., top of minute, top of hour, midnight).\n\nAvailable windows:\n- hour: 60 data points at 1-minute intervals\n- day: 288 data points at 5-minute intervals\n- week: 168 data points at 1-hour intervals\n\nRequires Apollo DB connection for historical data.\n","operationId":"getPoolYieldHistory","tags":["Liquidity"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"},{"name":"window","in":"query","required":true,"description":"The time window for the yield history","schema":{"type":"string","enum":["hour","day","week"]}}],"responses":{"200":{"description":"Historical yield data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoolYieldHistoryResponse"}}}},"400":{"description":"AMM not found or invalid window","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"PoolYieldHistoryResponse":{"type":"object","required":["pool_id","window","history"],"properties":{"pool_id":{"type":"string","description":"The AMM pool identifier"},"window":{"type":"string","description":"The requested time window","enum":["hour","day","week"]},"history":{"type":"array","description":"Array of timestamped APY data points, ordered from oldest to newest","items":{"$ref":"#/components/schemas/YieldHistoryDataPoint"}}}},"YieldHistoryDataPoint":{"type":"object","required":["timestamp","apy"],"properties":{"timestamp":{"type":"string","format":"date-time","description":"The start of the time interval (RFC3339 format)"},"apy":{"type":"number","format":"double","description":"Annualized percentage yield during this interval (e.g., 0.05 = 5% APY)"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## Get pool trading volume in USD

> Returns USD-denominated trading volume for the pool across multiple time periods.\
> Volume is calculated by tracking changes in AMM reserves between consecutive states.\
> Each swap is converted to USD at the exchange rate that was active at the time of that swap.\
> USD conversion is performed using:\
> \- Stablecoins (SBC, USDCx): 1:1 with USD\
> \- CC (Canton Coin): Historical exchange rate from OpenMiningRound contracts via Scan ACS API\
> Returns an error if neither token can be converted to USD.<br>

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Liquidity","description":"Liquidity provider operations."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/volume/{tokenA}/{tokenB}":{"get":{"summary":"Get pool trading volume in USD","description":"Returns USD-denominated trading volume for the pool across multiple time periods.\nVolume is calculated by tracking changes in AMM reserves between consecutive states.\nEach swap is converted to USD at the exchange rate that was active at the time of that swap.\nUSD conversion is performed using:\n- Stablecoins (SBC, USDCx): 1:1 with USD\n- CC (Canton Coin): Historical exchange rate from OpenMiningRound contracts via Scan ACS API\nReturns an error if neither token can be converted to USD.\n","operationId":"getPoolVolume","tags":["Liquidity"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"}],"responses":{"200":{"description":"Pool volume data in USD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoolVolumeResponse"}}}},"400":{"description":"AMM not found or cannot calculate USD volume","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"PoolVolumeResponse":{"type":"object","required":["pool_id","volume_usd"],"properties":{"pool_id":{"type":"string","description":"The AMM pool identifier"},"volume_usd":{"type":"object","additionalProperties":{"type":"number","format":"double"},"description":"Map of time period labels to USD-denominated trading volume.\nKeys are time periods (1h, 4h, 12h, 1d, 2d, 3d, 7d, 14d, 30d).\nValues are the total swap volume in USD for that period.\nUSD conversion uses stablecoin rates (1:1) or CC exchange rate from Scan API.\n"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## Get historical trading volume over time

> Returns an array of timestamped volume data points for the pool.\
> Each data point represents the USD-denominated trading volume during that time interval.\
> Timestamps are aligned to interval boundaries (e.g., top of minute, top of hour, midnight).\
> \
> Available windows:\
> \- hour: 60 data points at 1-minute intervals\
> \- day: 288 data points at 5-minute intervals\
> \- week: 168 data points at 1-hour intervals\
> \
> Volume calculation uses the same methodology as /volume endpoint.<br>

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"tags":[{"name":"Liquidity","description":"Liquidity provider operations."}],"servers":[{"url":"https://api.tradecraft.fi/v1","description":"Mainnet"}],"paths":{"/volume_history/{tokenA}/{tokenB}":{"get":{"summary":"Get historical trading volume over time","description":"Returns an array of timestamped volume data points for the pool.\nEach data point represents the USD-denominated trading volume during that time interval.\nTimestamps are aligned to interval boundaries (e.g., top of minute, top of hour, midnight).\n\nAvailable windows:\n- hour: 60 data points at 1-minute intervals\n- day: 288 data points at 5-minute intervals\n- week: 168 data points at 1-hour intervals\n\nVolume calculation uses the same methodology as /volume endpoint.\n","operationId":"getPoolVolumeHistory","tags":["Liquidity"],"parameters":[{"$ref":"#/components/parameters/tokenA"},{"$ref":"#/components/parameters/tokenB"},{"name":"window","in":"query","required":true,"description":"The time window for the volume history","schema":{"type":"string","enum":["hour","day","week"]}}],"responses":{"200":{"description":"Historical volume data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoolVolumeHistoryResponse"}}}},"400":{"description":"AMM not found, invalid window, or cannot calculate USD volume","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"parameters":{"tokenA":{"name":"tokenA","in":"path","required":true,"description":"The name/symbol of the first token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}},"tokenB":{"name":"tokenB","in":"path","required":true,"description":"The name/symbol of the second token (URL encoded).","schema":{"type":"string","enum":["CC","USDCx","CBTC","cETH","HANDL","EDELx","SBC"]}}},"schemas":{"PoolVolumeHistoryResponse":{"type":"object","required":["pool_id","window","history"],"properties":{"pool_id":{"type":"string","description":"The AMM pool identifier"},"window":{"type":"string","description":"The requested time window","enum":["hour","day","week"]},"history":{"type":"array","description":"Array of timestamped volume data points, ordered from oldest to newest","items":{"$ref":"#/components/schemas/VolumeHistoryDataPoint"}}}},"VolumeHistoryDataPoint":{"type":"object","required":["timestamp","volume_usd"],"properties":{"timestamp":{"type":"string","format":"date-time","description":"The start of the time interval (RFC3339 format)"},"volume_usd":{"type":"number","format":"double","description":"Trading volume in USD during this interval"}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```


# Models

## The Error object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}
```

## The InstrumentId object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"InstrumentId":{"type":"object","description":"Unique identifier for a financial instrument.","required":["admin","id"],"properties":{"admin":{"type":"string","description":"The party administering the instrument"},"id":{"type":"string","description":"The instrument identifier"}}}}}}
```

## The InstrumentInfo object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"InstrumentInfo":{"type":"object","description":"Extended information about a financial instrument.","required":["instrument_id","registry_url"],"properties":{"instrument_id":{"$ref":"#/components/schemas/InstrumentId"},"registry_url":{"type":"string","format":"uri","description":"URL of the token registry"}}},"InstrumentId":{"type":"object","description":"Unique identifier for a financial instrument.","required":["admin","id"],"properties":{"admin":{"type":"string","description":"The party administering the instrument"},"id":{"type":"string","description":"The instrument identifier"}}}}}}
```

## The TokenResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"TokenResponse":{"type":"object","description":"Token information response.","required":["instrument_id","instrument_info"],"properties":{"instrument_id":{"$ref":"#/components/schemas/InstrumentId"},"instrument_info":{"$ref":"#/components/schemas/InstrumentInfo"}}},"InstrumentId":{"type":"object","description":"Unique identifier for a financial instrument.","required":["admin","id"],"properties":{"admin":{"type":"string","description":"The party administering the instrument"},"id":{"type":"string","description":"The instrument identifier"}}},"InstrumentInfo":{"type":"object","description":"Extended information about a financial instrument.","required":["instrument_id","registry_url"],"properties":{"instrument_id":{"$ref":"#/components/schemas/InstrumentId"},"registry_url":{"type":"string","format":"uri","description":"URL of the token registry"}}}}}}
```

## The AmmIdResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"AmmIdResponse":{"type":"object","required":["amm_id"],"properties":{"amm_id":{"type":"string","description":"The AMM pool identifier"}}}}}}
```

## The AmmInspectResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"AmmInspectResponse":{"type":"object","description":"Detailed AMM pool state (V4 contract format).","required":["total_lp_token_supply","token_a_id","token_a_holdings","token_b_id","token_b_holdings","k","unclaimed_operator_fees","updated_at"],"properties":{"total_lp_token_supply":{"type":"number","format":"double","description":"Total supply of LP tokens."},"token_a_id":{"type":"string","description":"Identifier for token A."},"token_a_holdings":{"type":"number","format":"double","description":"Amount of token A in the pool."},"token_b_id":{"type":"string","description":"Identifier for token B."},"token_b_holdings":{"type":"number","format":"double","description":"Amount of token B in the pool."},"k":{"type":"number","format":"double","description":"The constant product (token_a_holdings * token_b_holdings)."},"unclaimed_operator_fees":{"type":"number","format":"double","description":"Accumulated operator fees awaiting claim (V4)."},"updated_at":{"type":"string","format":"date-time","description":"Timestamp of the last pool operation (V4)."}}}}}}
```

## The PoolInfo object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"PoolInfo":{"type":"object","required":["token1","token2","lp_token_name","token1_holdings","token2_holdings","total_lp_tokens","lp_fee_percent","operator_fee_percent"],"properties":{"token1":{"type":"string","description":"The symbol/code of the first token in the pool."},"token2":{"type":"string","description":"The symbol/code of the second token in the pool."},"lp_token_name":{"type":"string","description":"The liquidity pool token name/identifier."},"token1_holdings":{"type":"number","format":"double","description":"Amount of token1 held in the pool."},"token2_holdings":{"type":"number","format":"double","description":"Amount of token2 held in the pool."},"total_lp_tokens":{"type":"number","format":"double","description":"Total supply of LP tokens for this pool."},"lp_fee_percent":{"type":"number","format":"double","description":"Liquidity provider fee as a percentage (e.g., 0.3 means 0.3%)."},"operator_fee_percent":{"type":"number","format":"double","description":"Operator fee as a percentage (e.g., 0.1 means 0.1%)."},"yield24h":{"type":"number","format":"double","nullable":true,"description":"24-hour annualized yield (APY) for the pool. Null if unavailable."}}}}}}
```

## The ListPoolsResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"ListPoolsResponse":{"type":"object","required":["pools"],"properties":{"pools":{"type":"array","items":{"$ref":"#/components/schemas/PoolInfo"},"description":"Array of pool information objects."}}},"PoolInfo":{"type":"object","required":["token1","token2","lp_token_name","token1_holdings","token2_holdings","total_lp_tokens","lp_fee_percent","operator_fee_percent"],"properties":{"token1":{"type":"string","description":"The symbol/code of the first token in the pool."},"token2":{"type":"string","description":"The symbol/code of the second token in the pool."},"lp_token_name":{"type":"string","description":"The liquidity pool token name/identifier."},"token1_holdings":{"type":"number","format":"double","description":"Amount of token1 held in the pool."},"token2_holdings":{"type":"number","format":"double","description":"Amount of token2 held in the pool."},"total_lp_tokens":{"type":"number","format":"double","description":"Total supply of LP tokens for this pool."},"lp_fee_percent":{"type":"number","format":"double","description":"Liquidity provider fee as a percentage (e.g., 0.3 means 0.3%)."},"operator_fee_percent":{"type":"number","format":"double","description":"Operator fee as a percentage (e.g., 0.1 means 0.1%)."},"yield24h":{"type":"number","format":"double","nullable":true,"description":"24-hour annualized yield (APY) for the pool. Null if unavailable."}}}}}}
```

## The RatioResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"RatioResponse":{"type":"object","required":["price_of_b_in_a"],"properties":{"price_of_b_in_a":{"type":"number","format":"double","description":"The price of token B expressed in token A (tokenB_holdings / tokenA_holdings)."}}}}}}
```

## The FeeAmountResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"FeeAmountResponse":{"type":"object","required":["fee_amount","operator_fee_amount"],"properties":{"fee_amount":{"type":"number","format":"double","description":"Liquidity provider fee percentage."},"operator_fee_amount":{"type":"number","format":"double","description":"Operator fee percentage."}}}}}}
```

## The TradeDiscountCapResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"TradeDiscountCapResponse":{"type":"object","required":["trade_discount_cap_usd"],"properties":{"trade_discount_cap_usd":{"type":"number","format":"double","description":"Maximum trade size, in USD, that still qualifies for the\nfee discount. Trades at or below this size receive the reduced swap fee.\n"}}}}}}
```

## The PhysicalSettlementWhitelistResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"PhysicalSettlementWhitelistResponse":{"type":"object","required":["physical_settlement_whitelist"],"properties":{"physical_settlement_whitelist":{"type":"array","description":"Token symbols the venue settles into a holding.\nSwap output in any other token goes to the actor's trading balance.\n","items":{"type":"string"}}}}}}}
```

## The QuoteTradeFixedInputResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"QuoteTradeFixedInputResponse":{"type":"object","required":["user_gets"],"properties":{"user_gets":{"type":"number","format":"double","description":"The amount of output token the user will receive."}}}}}}
```

## The QuoteTradeFixedOutputResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"QuoteTradeFixedOutputResponse":{"type":"object","required":["user_gives"],"properties":{"user_gives":{"type":"number","format":"double","description":"The amount of input token the user must provide."}}}}}}
```

## The QuoteLPWithdrawalResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"QuoteLPWithdrawalResponse":{"type":"object","required":["amount_instrument_1","amount_instrument_2"],"properties":{"amount_instrument_1":{"type":"number","format":"double","description":"Amount of instrument 1 to receive."},"amount_instrument_2":{"type":"number","format":"double","description":"Amount of instrument 2 to receive."}}}}}}
```

## The QuoteLPDepositResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"QuoteLPDepositResponse":{"type":"object","required":["lp_tokens_to_mint","instrument_1_to_deposit","instrument_2_to_deposit"],"properties":{"lp_tokens_to_mint":{"type":"number","format":"double","description":"Amount of LP tokens that will be minted."},"instrument_1_to_deposit":{"type":"number","format":"double","description":"Amount of instrument 1 required for deposit."},"instrument_2_to_deposit":{"type":"number","format":"double","description":"Amount of instrument 2 required for deposit."}}}}}}
```

## The PoolYieldResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"PoolYieldResponse":{"type":"object","required":["pool_id","yield"],"properties":{"pool_id":{"type":"string","description":"The AMM pool identifier"},"yield":{"type":"object","additionalProperties":{"type":"number","format":"double"},"description":"Map of time period labels to annualized percentage yield (APY) values.\nKeys are time periods (1h, 4h, 12h, 1d, 2d, 3d, 7d, 14d, 30d).\nValues are APY as decimals (e.g., 0.05 = 5% APY).\nA value of 0 indicates insufficient data for that period.\n"}}}}}}
```

## The PoolVolumeResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"PoolVolumeResponse":{"type":"object","required":["pool_id","volume_usd"],"properties":{"pool_id":{"type":"string","description":"The AMM pool identifier"},"volume_usd":{"type":"object","additionalProperties":{"type":"number","format":"double"},"description":"Map of time period labels to USD-denominated trading volume.\nKeys are time periods (1h, 4h, 12h, 1d, 2d, 3d, 7d, 14d, 30d).\nValues are the total swap volume in USD for that period.\nUSD conversion uses stablecoin rates (1:1) or CC exchange rate from Scan API.\n"}}}}}}
```

## The PoolVolumeHistoryResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"PoolVolumeHistoryResponse":{"type":"object","required":["pool_id","window","history"],"properties":{"pool_id":{"type":"string","description":"The AMM pool identifier"},"window":{"type":"string","description":"The requested time window","enum":["hour","day","week"]},"history":{"type":"array","description":"Array of timestamped volume data points, ordered from oldest to newest","items":{"$ref":"#/components/schemas/VolumeHistoryDataPoint"}}}},"VolumeHistoryDataPoint":{"type":"object","required":["timestamp","volume_usd"],"properties":{"timestamp":{"type":"string","format":"date-time","description":"The start of the time interval (RFC3339 format)"},"volume_usd":{"type":"number","format":"double","description":"Trading volume in USD during this interval"}}}}}}
```

## The VolumeHistoryDataPoint object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"VolumeHistoryDataPoint":{"type":"object","required":["timestamp","volume_usd"],"properties":{"timestamp":{"type":"string","format":"date-time","description":"The start of the time interval (RFC3339 format)"},"volume_usd":{"type":"number","format":"double","description":"Trading volume in USD during this interval"}}}}}}
```

## The PoolYieldHistoryResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"PoolYieldHistoryResponse":{"type":"object","required":["pool_id","window","history"],"properties":{"pool_id":{"type":"string","description":"The AMM pool identifier"},"window":{"type":"string","description":"The requested time window","enum":["hour","day","week"]},"history":{"type":"array","description":"Array of timestamped APY data points, ordered from oldest to newest","items":{"$ref":"#/components/schemas/YieldHistoryDataPoint"}}}},"YieldHistoryDataPoint":{"type":"object","required":["timestamp","apy"],"properties":{"timestamp":{"type":"string","format":"date-time","description":"The start of the time interval (RFC3339 format)"},"apy":{"type":"number","format":"double","description":"Annualized percentage yield during this interval (e.g., 0.05 = 5% APY)"}}}}}}
```

## The YieldHistoryDataPoint object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"YieldHistoryDataPoint":{"type":"object","required":["timestamp","apy"],"properties":{"timestamp":{"type":"string","format":"date-time","description":"The start of the time interval (RFC3339 format)"},"apy":{"type":"number","format":"double","description":"Annualized percentage yield during this interval (e.g., 0.05 = 5% APY)"}}}}}}
```

## The DisclosedContract object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"DisclosedContract":{"type":"object","description":"A disclosed contract blob from the Canton ledger, required for submitting transactions.","required":["templateId","contractId","createdEventBlob","synchronizerId"],"properties":{"templateId":{"type":"string","description":"Fully qualified template identifier (packageId:moduleName:entityName)"},"contractId":{"type":"string","description":"The contract ID on the ledger"},"createdEventBlob":{"type":"string","format":"byte","description":"Base64-encoded created event blob"},"synchronizerId":{"type":"string","description":"The synchronizer (domain) ID where this contract lives"}}}}}}
```

## The PoolDisclosuresResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"PoolDisclosuresResponse":{"type":"object","description":"Disclosed contracts needed to submit transactions against this pool.\nIncludes the AMM, fees, rules, LP instrument config, allocation factory,\nand optionally the featured app right contract.\n","required":["amm","amm_fees","instrument_config","allocation_factory","amm_data","amm_fees_data"],"properties":{"amm":{"$ref":"#/components/schemas/DisclosedContract"},"amm_fees":{"$ref":"#/components/schemas/DisclosedContract"},"amm_rules":{"$ref":"#/components/schemas/DisclosedContract"},"instrument_config":{"$ref":"#/components/schemas/DisclosedContract"},"allocation_factory":{"$ref":"#/components/schemas/DisclosedContract"},"featured_app_right":{"$ref":"#/components/schemas/DisclosedContract"},"amm_data":{"type":"object","description":"Parsed V4 AMM contract data"},"amm_fees_data":{"type":"object","description":"Parsed V4 AMMFees contract data"},"amm_rules_data":{"type":"object","description":"Parsed AMMRules contract data (if present)"},"featured_app_right_id":{"type":"string","nullable":true,"description":"Contract ID of the FeaturedAppRight (if present)"}}},"DisclosedContract":{"type":"object","description":"A disclosed contract blob from the Canton ledger, required for submitting transactions.","required":["templateId","contractId","createdEventBlob","synchronizerId"],"properties":{"templateId":{"type":"string","description":"Fully qualified template identifier (packageId:moduleName:entityName)"},"contractId":{"type":"string","description":"The contract ID on the ledger"},"createdEventBlob":{"type":"string","format":"byte","description":"Base64-encoded created event blob"},"synchronizerId":{"type":"string","description":"The synchronizer (domain) ID where this contract lives"}}}}}}
```

## The AllocationFactoryResponse object

```json
{"openapi":"3.0.3","info":{"title":"Tradecraft AMM HTTP API","version":"0.1.14"},"components":{"schemas":{"AllocationFactoryResponse":{"type":"object","description":"The registry's allocation-factory contract and the context for exercising it.","required":["factoryId","choiceContext","cachedAt"],"properties":{"factoryId":{"type":"string","description":"Contract ID to exercise AllocationFactory_Allocate on"},"choiceContext":{"type":"object","description":"The registry's choice-context envelope, not a Daml ChoiceContext.","required":["disclosedContracts","choiceContextData"],"properties":{"disclosedContracts":{"type":"array","description":"Disclosures for the submission, not for ExtraArgs","items":{"$ref":"#/components/schemas/DisclosedContract"}},"choiceContextData":{"type":"object","description":"The Daml ChoiceContext to pass as ExtraArgs.context"}}},"cachedAt":{"type":"string","format":"date-time","description":"When this context was last fetched from the registry"}}},"DisclosedContract":{"type":"object","description":"A disclosed contract blob from the Canton ledger, required for submitting transactions.","required":["templateId","contractId","createdEventBlob","synchronizerId"],"properties":{"templateId":{"type":"string","description":"Fully qualified template identifier (packageId:moduleName:entityName)"},"contractId":{"type":"string","description":"The contract ID on the ledger"},"createdEventBlob":{"type":"string","format":"byte","description":"Base64-encoded created event blob"},"synchronizerId":{"type":"string","description":"The synchronizer (domain) ID where this contract lives"}}}}}}
```


# Fees and Pricing

Fees and incentive programs that keep pools deep and supply matched to demand.

Tradecraft is designed to make every Canton-listed asset reliably available to traders, with deep liquidity and the incentive programs needed to keep pools stocked across conditions.

### How Tradecraft markets work

Tradecraft is an automated market maker (AMM) running on Canton. Pools hold inventory in pairs of tokens. Anyone can [trade against a pool](/using-tradecraft/guide-how-to-trade) or [provide liquidity](/using-tradecraft/guide-how-to-provide-liquidity) to a pool. Inventory providers continuously bring supply to the pools where traders need it, keeping every pair stocked across conditions.

Three groups make Tradecraft markets work:

| Participant             | What they do                                                                        | What they earn                                       |
| ----------------------- | ----------------------------------------------------------------------------------- | ---------------------------------------------------- |
| **Liquidity providers** | Deposit pairs of tokens into pools so that trades have inventory to settle against. | A share of swap fees paid by traders in their pool.  |
| **Inventory providers** | Bring assets from other chains to fulfill trading demand on Canton.                 | The sourcing margin on each supply trade, less fees. |
| **Traders**             | Trade for any purpose: wallet swaps, settlement, hedging, rebalancing.              | Deep available liquidity and a small-trade discount. |

### Standard fees

The base swap fee on Tradecraft is usually **0.30%** (30 basis points) of trade size, paid by the trader at the time of the swap. This fee is shared with the liquidity providers in the pool. The fee amount and the liquidity provider/operator fee split can vary by pool.

Trades below a dynamic size threshold pay a reduced swap fee. Tradecraft updates these values continuously based on conditions; see *The small-trade discount* below for more.

### Liquidity providers

Liquidity providers (LPs) deposit pairs of tokens into Tradecraft pools so that incoming trades have inventory to settle against. LPs earn a share of every swap fee paid in their pool, in proportion to their share of the pool.

The deeper a pool's inventory, the more demand it can absorb without running thin. Tradecraft's incentive programs are designed to encourage stable, long-term liquidity, so that pools deepen over time and traders can rely on them across conditions.

Anyone can become a liquidity provider on Tradecraft. See the liquidity provider guide.

Additional incentive programs may be available for liquidity providers with larger or longer-term commitments. Liquidity providers participating in these programs are expected to maintain consistent participation across the pairs they cover. Contact <partnerships@tradecraft.fi> to discuss eligibility.

**Example**

Consider an LP holding 10% of a pool. If the pool sees $1,000,000 in daily trade volume:

* Swap fees collected by the pool: $1,000,000 x 0.20% = **$2,000/day**
* LP's share (10%): **$200/day**

LP earnings scale linearly with pool volume and with the LP's share of the pool. *Numbers illustrative.*

### Inventory providers

Inventory providers bring assets from other chains to fulfill trading demand on Canton. When demand for a token on Tradecraft outpaces the inventory currently available in the pool, an inventory provider sources the token from where it's available (typically another chain, sometimes another Canton venue) and supplies it to the pool. The provider earns the sourcing margin, the gap between where they sourced the asset and what the Tradecraft pool pays for it, less fees.

Inventory providers are net payers of fees and gas to Tradecraft and the network. When an inventory-supply trade qualifies under Tradecraft's program, Tradecraft refunds part (but not all) of the costs the inventory provider incurred. The sourcing margin covers the rest, making the overall transaction profitable enough to sustain continuous inventory supply.

Without inventory providers bringing supply where it's needed, Tradecraft pools would frequently run thin on the side traders want to buy. With inventory providers continuously sourcing tokens for the pools that need them, Tradecraft pools stay supplied across pairs and conditions.

Inventory provision is permissionless. Any party with the means to source assets and supply them to Tradecraft pools can participate. As Tradecraft's gas costs come down through ongoing protocol improvements, the addressable set of profitable inventory strategies widens.

Inventory providers participating in Tradecraft's program are expected to maintain consistent inventory supply across the pairs they cover; qualifying status is reviewed periodically.

Tradecraft offers a qualified onboarding program for new inventory providers and institutions:

* **Working capital.** A loan of up to 1M CC to support initial operating-capital requirements.
* **Onboarding period.** Full access to incentive benefits during the initial deployment period, without immediate volume or activity thresholds.

Contact <partnerships@tradecraft.fi> to discuss eligibility.

**Example**

An inventory provider notices that the TOKEN/USDC pool is paying 1.0015 USDC per TOKEN to bring in supply, while TOKEN can be sourced for 1.0000 USDC elsewhere. The IP brings $1,000 worth of TOKEN to the pool, in a trade size small enough to qualify for the small-trade discount.

Costs paid by the IP:

* Venue fee at the small-trade discounted rate *(illustrative, \~0.02%)*: $0.20
* Gas: $0.10
* **Total costs: $0.30**

Receipts:

* Sourcing margin (15 bps x $1,000): $1.50
* Inventory-provider refund *(separate from the small-trade discount; illustrative, covers most but not all costs)*: $0.24
* **Total receipts: $1.74**

**Net profit on the trade: $1.44.**

The IP paid $0.30 in fees and gas and received $0.24 back through the inventory-provider refund, remaining a net payer of $0.06 in unrefunded costs. The sourcing margin ($1.50) is the bulk of the IP's earnings; the inventory-provider refund makes the activity slightly more profitable than the small-trade discount alone would. *Numbers illustrative.*

### Traders

Traders are the participants Tradecraft is ultimately built for: anyone swapping tokens, whether through a wallet, an integrated app, or a trading desk. The combined effect of the participants and programs above is that traders find deep available inventory across all token pairs Tradecraft supports, and that trades below a dynamic size threshold pay reduced fees regardless of who is executing them.

**Example**

A trader executes a $200 swap (below the dynamic small-trade threshold):

* Discounted venue fee *(illustrative, \~0.02%)*: $0.04
* Gas: $0.10
* **Total: $0.14**

A trader executes a $50,000 swap (above the threshold):

* Venue fee at the base rate (0.30%): $150.00
* Gas: $0.10
* **Total: $150.10**

Small trades are essentially free of venue fees; larger trades pay the base rate. *Numbers illustrative.*

### The small-trade discount

Tradecraft's design goal is to keep pool inventory matched to trading demand across all pairs. For that to hold continuously, inventory providers need to find it continuously profitable to source tokens where demand outpaces local supply.

That is the role of the small-trade discount. Tradecraft applies a reduced swap fee to trades below a dynamic size threshold. For modest demand-supply gaps, only discounted small-trade supply remains profitable, so the supply work happens through small, distributed trades. When the gap between demand and local supply is larger, supply trades of any size become profitable for any party, restoring the pool to balance.

The size of the threshold is set by data analysis on trailing volume and other conditions, and updated automatically as conditions change.

### Self-dealing safeguards

Tradecraft's incentive system is designed around the following principles to limit extraction of incentives without performing the underlying economic activity:

* **Self-trading should not be profitable.** Rewards distributed on any trade are designed so that the rewards earned are smaller than the costs of executing it, making it uneconomical for a participant to trade against themselves.
* **Incentives should be proportional to fees paid.** No incentive should pay out more than the system collects in fees on the activity it rewards.
* **Tradecraft should not directly compete with inventory providers for the small-trade supply program.** Where Tradecraft sources its own inventory, it does so transparently and outside that program.

These rules are enforced in the protocol.

### A permissionless system

Liquidity provision and inventory provision are some of the most consistent ways to earn from exchange activity, and they are typically reserved for exchange operators or privileged market makers. Tradecraft is designed to make both roles open and permissionless:

* Liquidity providers can deposit to and withdraw from any pool freely.
* Inventory providers can run any inventory-sourcing strategy against any Tradecraft pool.
* The package any external party can run is the same package Tradecraft itself runs. There is no privileged operator version.

As Tradecraft's gas costs come down through ongoing protocol improvements, the set of profitable strategies widens to include participants who don't currently have the capital efficiency to compete.

### Changes and updates

Fee values and threshold parameters change as conditions change. The most recent fee schedule is the one on this page.


# Official Links & Channels

**Our only channels and accounts are the ones listed here:**

* Website: [tradecraft.fi](https://tradecraft.fi)
* Documentation: [docs.tradecraft.fi](https://docs.tradecraft.fi)
* Support: <support@tradecraft.fi> (our only support channel)
* X: <https://x.com/tradecraftfi>
* Auxiliary dashboard: <https://www.memora.systems/dashboard/pools>

We do not have any Telegram, Discord or other groups. We do not provide support or assistance on those platforms. Be wary of accounts using "tradecraft" in their name. We do not have official accounts on those platforms.

**Partnerships**

We are glad to connect for liquidity, product or marketing opportunities. Please note we do not engage solicitations for community moderators, community promotions, or social media promotions (X posts, Telegram posts, etc).

<partnerships@tradecraft.fi>


# Get Help

We are available to help if you are having trouble with a transaction or have questions about how to use Tradecraft.

**Support Availability Schedule**

Our support team is online during the following times:

* 9am - 5pm Monday through Friday, US Eastern time.
* Excluding US holidays.

Depending on the time your request was received it may take up to 72 hours to receive a response due to weekends and holidays.

Email: <support@tradecraft.fi>

```
support@tradecraft.fi
```

{% hint style="info" %}
**Our only support channel is our official support email address.** Accounts offering support on X, Telegram, or elsewhere are not us. Be wary of scams. We will never ask you to send us funds or to reveal your seed phrases.
{% endhint %}


# Terms of Service

Last Updated: January 13, 2026

These Terms of Service (the "Agreement") constitute a legally binding agreement between you ("you," "your," or "User") and Obsidian Software LLC, a Puerto Rico limited liability company ("Obsidian," "we," "us," or "our"). This Agreement governs your access to and use of the Tradecraft website located at <https://tradecraft.fi> (the "Website"), the Tradecraft web application, and any other software, tools, features, or functionalities provided by Obsidian in connection therewith (collectively, the "Interface").

**BY ACCESSING OR USING THE INTERFACE, YOU ACKNOWLEDGE THAT YOU HAVE READ, UNDERSTOOD, AND AGREE TO BE BOUND BY THIS AGREEMENT. IF YOU DO NOT AGREE TO THESE TERMS, YOU MUST NOT ACCESS OR USE THE INTERFACE.**

***

## 1. THE INTERFACE AND THE PROTOCOL

### 1.1 The Interface

The Interface is a web-hosted user interface that provides a convenient means of accessing the Tradecraft Protocol (defined below). The Interface is operated and maintained by Obsidian Software LLC. Through the Interface, users may interact with the Tradecraft Protocol to execute cryptocurrency swaps, provide liquidity to decentralized liquidity pools, and perform related functions.

### 1.2 The Protocol

The "Tradecraft Protocol" refers to a set of autonomous, self-executing smart contracts deployed on the Canton Network blockchain that implement automated market maker ("AMM") functionality enabling peer-to-peer cryptocurrency swaps without the need for a centralized intermediary. The Tradecraft Protocol operates independently of the Interface and independently of Obsidian.

### 1.3 The Interface Is Distinct from the Protocol

**You expressly acknowledge and agree that the Interface and the Tradecraft Protocol are separate and distinct.** Obsidian provides the Interface as one means of accessing the Tradecraft Protocol, but Obsidian does not own, control, operate, or maintain the Tradecraft Protocol. The Tradecraft Protocol consists of autonomous smart contracts that execute automatically based on their underlying code without any intervention, control, or discretion exercised by Obsidian.

Obsidian does not operate any liquidity pools, does not act as a counterparty to any transaction, and does not hold, custody, or control any user funds at any time. When you execute a swap or provide liquidity through the Interface, you are interacting directly with the Tradecraft Protocol's smart contracts on the Canton Network—not with Obsidian.

### 1.4 Third-Party Protocol Access

The Tradecraft Protocol may be accessed through means other than the Interface, including through third-party interfaces, direct smart contract interaction, or other methods. Obsidian is not responsible for and makes no representations regarding any third-party means of accessing the Protocol.

***

## 2. ELIGIBILITY AND ACCESS

### 2.1 Age and Capacity

You represent and warrant that you are at least eighteen (18) years of age or the age of legal majority in your jurisdiction (whichever is greater) and have the legal capacity to enter into this Agreement.

### 2.2 Authority

If you are accessing or using the Interface on behalf of a legal entity, you represent and warrant that you have the legal authority to bind that entity to this Agreement, and all references to "you" shall include that entity.

### 2.3 Compliance with Laws

You represent and warrant that your access to and use of the Interface complies with all applicable laws, regulations, and rules in your jurisdiction, including but not limited to laws relating to securities, commodities, money transmission, taxation, and anti-money laundering.

### 2.4 Prohibited Jurisdictions and Persons

You represent and warrant that you are not: (a) a citizen or resident of, or located in, a geographic area that is subject to comprehensive United States or other applicable sanctions or embargoes, including but not limited to Iran, Cuba, North Korea, Syria, Myanmar (Burma), the Crimea region of Ukraine, the so-called Donetsk People's Republic, or the so-called Luhansk People's Republic; (b) an individual or entity listed on any applicable sanctions list, including but not limited to the United States Treasury Department's Office of Foreign Assets Control ("OFAC") Specially Designated Nationals and Blocked Persons List, the United Nations Security Council Consolidated List, or the European Union Consolidated List; (c) otherwise prohibited by applicable law from accessing or using the Interface; or (d) accessing or using the Interface on behalf of any person or entity described in clauses (a) through (c).

### 2.5 Prohibition on Circumvention

You agree that you will not use any virtual private network ("VPN"), proxy service, or any other technology or mechanism to circumvent the geographic restrictions or eligibility requirements set forth in this Agreement. Any attempt to access the Interface through such means is a material breach of this Agreement.

***

## 3. NON-CUSTODIAL NATURE OF THE INTERFACE

### 3.1 Non-Custodial Service

**The Interface is a purely non-custodial application.** Obsidian does not at any time have custody, possession, or control of your digital assets, private keys, passwords, or any other credentials associated with your digital asset wallet. You are solely responsible for the custody and security of the cryptographic private keys to any digital asset wallets you use in connection with the Interface.

### 3.2 Wallet Connection

To access and use certain features of the Interface, you must connect a compatible, non-custodial digital asset wallet. By connecting your wallet to the Interface, you authorize the Interface to interact with your wallet to the extent necessary to facilitate your requested transactions. You understand and agree that Obsidian does not operate, maintain, or have any control over any third-party wallet software you use.

### 3.3 No Recovery of Assets

Because Obsidian does not have custody or control over the contents of your wallet, Obsidian cannot retrieve, recover, freeze, transfer, or return any digital assets. If you lose access to your wallet, private keys, or seed phrase, your digital assets may become permanently inaccessible. Obsidian has no ability or obligation to assist you in recovering lost assets.

### 3.4 Transaction Responsibility

You are solely responsible for all transactions you initiate through the Interface. Once a transaction is broadcast to the Canton Network and confirmed by the network's validators, it is irreversible. Obsidian cannot reverse, cancel, or modify any transaction once it has been submitted.

***

## 4. MAGIC ADDRESSES

### 4.1 Description of Magic Addresses

The Interface includes a feature known as "Magic Addresses," which allows users to send digital assets to designated Canton Network addresses controlled by Obsidian to automatically execute predefined actions. For example, a user may send Canton Coin ("CC") to a specific Magic Address associated with the CC/CBTC liquidity pool, whereupon the system will automatically swap the CC for CBTC and return the CBTC to the sending wallet address.

### 4.2 Non-Custodial Execution

Notwithstanding that Magic Addresses are controlled by Obsidian, the Magic Addresses feature operates on a non-custodial basis through atomically executed operations. This means that the receipt of assets, execution of the requested action, and return of assets occur within a single atomic transaction—either all steps complete successfully, or no steps complete. At no point does Obsidian hold user assets outside of the atomic transaction execution.

### 4.3 User Responsibility for Correct Addresses

**You are solely responsible for ensuring that you send digital assets to the correct Magic Address for your intended transaction.** Sending assets to an incorrect address may result in the permanent and irrecoverable loss of your assets.

### 4.4 No Responsibility for Misplaced Funds

**Obsidian expressly disclaims any responsibility or liability for digital assets sent to incorrect addresses, including but not limited to assets sent to the wrong Magic Address, assets sent to Magic Addresses that do not support the sent asset type, assets sent to non-Magic addresses, or assets lost due to any other user error in specifying the recipient address.** You acknowledge and agree that any such loss is solely your responsibility.

### 4.5 Verification Requirement

Before using any Magic Address, you agree to verify the correct address for your intended transaction through the official Interface at <https://tradecraft.fi>. Obsidian is not responsible for losses resulting from reliance on Magic Address information obtained from any source other than the official Interface.

### 4.6 No Guarantee of Returned Token Amounts

Using a Magic Address does not guarantee any specific amount of returned tokens. The actual amount of tokens you receive may differ from quotes, estimates, or pricing information displayed by the Interface, our application programming interface ("API"), or any other source of data provided by Obsidian, due to slippage, market movements, or other factors. Obtaining a quote or pricing information from any Obsidian data source does not constitute a guarantee, commitment, or promise that you will receive that amount when executing a transaction through a Magic Address.

***

## 5. PROHIBITED ACTIVITIES

You agree not to engage in any of the following prohibited activities in connection with your access to or use of the Interface:

### 5.1 Illegal Activity

Using the Interface for any purpose that is unlawful or prohibited by this Agreement, or to facilitate any illegal activity including but not limited to money laundering, terrorist financing, tax evasion, fraud, or the purchase or sale of illegal goods or services.

### 5.2 Sanctions Violations

Using the Interface in any manner that would cause Obsidian or any other person to violate any applicable sanctions laws or regulations, including OFAC regulations.

### 5.3 Manipulation

Engaging in any activity that manipulates, deceives, or defrauds the Interface, the Tradecraft Protocol, or any other users, including but not limited to front-running, wash trading, spoofing, layering, or other manipulative trading practices.

### 5.4 Interference

Interfering with, disrupting, or attempting to gain unauthorized access to the Interface, the servers or networks connected to the Interface, or any other user's access to or use of the Interface, including through the use of any robot, spider, scraper, or other automated means.

### 5.5 Intellectual Property Infringement

Using the Interface in any manner that infringes, misappropriates, or violates any intellectual property rights or other proprietary rights of Obsidian or any third party.

### 5.6 Harmful Code

Introducing any virus, worm, Trojan horse, malware, or other harmful code or material to the Interface or using the Interface to distribute such code or material.

### 5.7 False Information

Providing false, inaccurate, or misleading information in connection with your use of the Interface, including any misrepresentation regarding your identity, location, or eligibility to use the Interface.

### 5.8 Circumvention

Attempting to circumvent any security feature, access control, or usage restriction of the Interface.

***

## 6. DIGITAL ASSETS AND THIRD-PARTY TOKENS

### 6.1 No Endorsement

The Interface may display or facilitate transactions involving digital assets created by third parties. The availability of any digital asset on or through the Interface does not constitute an endorsement, recommendation, or approval of that asset by Obsidian. Obsidian does not investigate, verify, or guarantee the legitimacy, safety, value, or legal status of any digital asset.

### 6.2 Fraudulent Tokens

**You acknowledge that anyone can create a digital asset on the Canton Network, including fraudulent or deceptive versions of existing assets or assets that falsely claim association with a project or entity.** Obsidian cannot and does not verify the authenticity of any digital asset. You are solely responsible for conducting your own due diligence before transacting in any digital asset.

***

## 7. ASSUMPTION OF RISK

### 7.1 Cryptocurrency Risks

You acknowledge and agree that accessing and using the Interface involves significant risks, including but not limited to the following:

**Volatility.** The prices of digital assets are highly volatile and may fluctuate significantly over short periods of time. The value of your digital assets may decrease substantially or become worthless.

**Smart Contract Risk.** The Tradecraft Protocol consists of smart contracts that may contain bugs, vulnerabilities, or errors that could result in the loss of digital assets. Smart contracts may be subject to exploits, hacks, or attacks. No audit or review can guarantee that smart contracts are free from vulnerabilities.

**Impermanent Loss.** If you provide liquidity to the Tradecraft Protocol, you may experience impermanent loss, which occurs when the relative prices of the assets in a liquidity pool diverge. Impermanent loss can result in receiving fewer assets upon withdrawal than you would have held by simply retaining the original assets.

**Slippage.** The price at which your transaction executes may differ from the price displayed at the time you submit the transaction due to market movements, transaction ordering, or other factors.

**Stablecoin Risk.** Digital assets described as "stablecoins" may not maintain their intended peg to fiat currencies or other reference assets. Stablecoins may not be fully or adequately collateralized and may experience significant price fluctuations.

**Blockchain Risk.** The Canton Network and other blockchain networks may experience congestion, delays, forks, attacks, or other disruptions that could affect your transactions or the value of your digital assets.

**Regulatory Risk.** The regulatory status of digital assets and decentralized finance is uncertain and evolving. Changes in laws or regulations may adversely affect the use, transfer, exchange, or value of digital assets.

**Irreversibility.** Blockchain transactions are irreversible once confirmed. Errors in transaction parameters, including incorrect recipient addresses or amounts, cannot be corrected after confirmation.

**Taxation.** The tax treatment of digital asset transactions is uncertain and varies by jurisdiction. You are solely responsible for determining and fulfilling your tax obligations.

### 7.2 Express Assumption of Risk

**YOU EXPRESSLY ACKNOWLEDGE, UNDERSTAND, AND AGREE THAT YOUR ACCESS TO AND USE OF THE INTERFACE IS AT YOUR SOLE RISK. YOU ASSUME FULL RESPONSIBILITY FOR ALL RISKS ASSOCIATED WITH ACCESSING AND USING THE INTERFACE AND TRANSACTING IN DIGITAL ASSETS, INCLUDING BUT NOT LIMITED TO THE RISKS DESCRIBED ABOVE.**

***

## 8. NO INVESTMENT ADVICE

### 8.1 Informational Purposes Only

The Interface and any information, content, or materials made available through the Interface are provided for informational purposes only. Nothing contained in or accessible through the Interface constitutes, or is intended to constitute, investment advice, financial advice, trading advice, tax advice, legal advice, or any other form of professional advice.

### 8.2 No Recommendations

**OBSIDIAN DOES NOT RECOMMEND THAT ANY DIGITAL ASSET SHOULD BE BOUGHT, SOLD, HELD, OR USED IN ANY PARTICULAR WAY. YOU SHOULD NOT TAKE, OR REFRAIN FROM TAKING, ANY ACTION BASED ON ANY INFORMATION CONTAINED IN OR ACCESSIBLE THROUGH THE INTERFACE. OBSIDIAN DOES NOT MAKE ANY INVESTMENT RECOMMENDATIONS AND DOES NOT OPINE ON THE MERITS OF ANY TRANSACTION OR DIGITAL ASSET.**

### 8.3 Independent Decision-Making

Before making any financial, legal, or other decision in connection with the Interface, you should conduct your own research and due diligence and consult with qualified professionals as appropriate. Any decision to access or use the Interface or to transact in digital assets is made solely at your own risk and discretion.

### 8.4 Unsolicited Transactions

All transactions you execute through the Interface are unsolicited, meaning that you are solely responsible for initiating any transaction and that Obsidian does not solicit, recommend, or advise any transaction.

***

## 9. PRIVACY AND DATA

### 9.1 Privacy Policy

Your use of the Interface is subject to our Privacy Policy, available at <https://docs.tradecraft.fi/tradecraft/privacy-policy>, which is incorporated into this Agreement by reference.

### 9.2 Non-Collection of Personal Information

The Interface does not require you to create an account, provide an email address, or submit any personal information to access or use its features. The Interface operates solely through wallet connections without collecting personally identifiable information.

### 9.4 Blockchain Data

You acknowledge that information related to your blockchain transactions, including your wallet address and transaction history, may be publicly visible on the Canton Network or associated block explorers, subject to Canton Network's privacy features.

***

## 10. INTELLECTUAL PROPERTY

### 10.1 Ownership

The Interface, including all content, features, functionality, design, text, graphics, logos, icons, images, and software, is owned by Obsidian or its licensors and is protected by copyright, trademark, and other intellectual property laws. Except as expressly provided in this Agreement, Obsidian does not grant you any rights to use Obsidian's intellectual property.

### 10.2 Limited License

Subject to your compliance with this Agreement, Obsidian grants you a limited, non-exclusive, non-transferable, non-sublicensable, revocable license to access and use the Interface for your personal, non-commercial use. This license does not include any right to: (a) modify, copy, distribute, transmit, display, perform, reproduce, publish, license, create derivative works from, or sell any content obtained from the Interface; (b) use any data mining, robots, or similar data gathering methods; or (c) use the Interface for any commercial purpose without Obsidian's prior written consent.

### 10.3 Trademarks

"Tradecraft," the Tradecraft logo, and any other Obsidian trademarks, service marks, graphics, and logos used in connection with the Interface are trademarks or registered trademarks of Obsidian. Other trademarks, service marks, graphics, and logos used in connection with the Interface may be the trademarks of their respective owners. You are not granted any right or license to use any such trademarks.

### 10.4 Feedback

If you provide any feedback, suggestions, or ideas regarding the Interface ("Feedback"), you grant Obsidian a perpetual, irrevocable, worldwide, royalty-free license to use, copy, modify, create derivative works from, and otherwise exploit such Feedback for any purpose without compensation or attribution to you.

***

## 11. DISCLAIMERS

### 11.1 "As Is" and "As Available"

**THE INTERFACE IS PROVIDED ON AN "AS IS" AND "AS AVAILABLE" BASIS WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, OBSIDIAN DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT.**

### 11.2 No Warranty of Operation

**OBSIDIAN DOES NOT WARRANT THAT THE INTERFACE WILL BE UNINTERRUPTED, ERROR-FREE, SECURE, OR FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS. OBSIDIAN DOES NOT WARRANT THAT ANY ERRORS OR DEFECTS WILL BE CORRECTED OR THAT THE INTERFACE WILL MEET YOUR REQUIREMENTS OR EXPECTATIONS.**

### 11.3 No Warranty Regarding Protocol

**OBSIDIAN MAKES NO REPRESENTATIONS OR WARRANTIES REGARDING THE TRADECRAFT PROTOCOL, INCLUDING ANY REPRESENTATION THAT THE PROTOCOL WILL OPERATE AS INTENDED, THAT IT IS FREE FROM BUGS OR VULNERABILITIES, OR THAT IT HAS BEEN OR WILL BE AUDITED. THE PROTOCOL IS PROVIDED BY THIRD PARTIES AND IS NOT UNDER OBSIDIAN'S CONTROL.**

### 11.4 No Warranty Regarding Digital Assets

**OBSIDIAN MAKES NO REPRESENTATIONS OR WARRANTIES REGARDING ANY DIGITAL ASSET, INCLUDING ITS VALUE, LEGALITY, OR AUTHENTICITY. OBSIDIAN DOES NOT GUARANTEE THAT ANY DIGITAL ASSET WILL MAINTAIN ITS VALUE OR BE EXCHANGEABLE FOR ANY OTHER ASSET.**

### 11.5 Third-Party Services

The Interface may contain links to third-party websites, services, or resources. Obsidian does not endorse and is not responsible for any third-party content, products, services, or practices. Your interactions with third parties are solely between you and such third parties.

### 11.6 No Fiduciary Duty

**THIS AGREEMENT IS NOT INTENDED TO, AND DOES NOT, CREATE OR IMPOSE ANY FIDUCIARY DUTIES ON OBSIDIAN. TO THE FULLEST EXTENT PERMITTED BY LAW, YOU ACKNOWLEDGE AND AGREE THAT OBSIDIAN OWES NO FIDUCIARY DUTIES OR LIABILITIES TO YOU OR ANY OTHER PARTY, AND THAT TO THE EXTENT ANY SUCH DUTIES OR LIABILITIES MAY EXIST AT LAW OR IN EQUITY, THOSE DUTIES AND LIABILITIES ARE HEREBY IRREVOCABLY DISCLAIMED, WAIVED, AND ELIMINATED.**

### 11.7 No Registration

Obsidian is not registered with the U.S. Securities and Exchange Commission, the U.S. Commodity Futures Trading Commission, or any other regulatory authority in any capacity, including as a securities exchange, broker-dealer, investment adviser, commodity pool operator, or money services business. The Interface does not constitute a regulated financial service.

***

## 12. LIMITATION OF LIABILITY

### 12.1 Exclusion of Damages

**TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL OBSIDIAN, ITS AFFILIATES, OR THEIR RESPECTIVE OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, LICENSORS, OR SERVICE PROVIDERS BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, PUNITIVE, OR EXEMPLARY DAMAGES, INCLUDING BUT NOT LIMITED TO DAMAGES FOR LOSS OF PROFITS, GOODWILL, USE, DATA, OR OTHER INTANGIBLE LOSSES, REGARDLESS OF WHETHER SUCH DAMAGES WERE FORESEEABLE AND WHETHER OR NOT OBSIDIAN WAS ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.**

### 12.2 Liability Cap

**TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, THE TOTAL LIABILITY OF OBSIDIAN AND ITS AFFILIATES, AND THEIR RESPECTIVE OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, LICENSORS, AND SERVICE PROVIDERS, TO YOU FOR ALL CLAIMS ARISING OUT OF OR RELATING TO THIS AGREEMENT OR YOUR USE OF THE INTERFACE, WHETHER IN CONTRACT, TORT, OR OTHERWISE, SHALL NOT EXCEED ONE HUNDRED UNITED STATES DOLLARS (USD $100.00).**

### 12.3 Essential Purpose

**THE LIMITATIONS OF LIABILITY SET FORTH IN THIS SECTION SHALL APPLY EVEN IF YOUR REMEDIES UNDER THIS AGREEMENT FAIL OF THEIR ESSENTIAL PURPOSE.**

### 12.4 Jurisdictional Limitations

Some jurisdictions do not allow the exclusion or limitation of certain warranties or liabilities. In such jurisdictions, the exclusions and limitations set forth in this Agreement shall apply to the fullest extent permitted by applicable law.

***

## 13. INDEMNIFICATION

### 13.1 Indemnification Obligation

You agree to indemnify, defend, and hold harmless Obsidian, its affiliates, and their respective officers, directors, employees, agents, licensors, and service providers from and against any and all claims, liabilities, damages, losses, costs, and expenses (including reasonable attorneys' fees) arising out of or relating to: (a) your access to or use of the Interface; (b) your violation of this Agreement; (c) your violation of any applicable law or regulation; (d) your violation of any third-party rights, including intellectual property rights; (e) any transaction you execute through the Interface or the Tradecraft Protocol; (f) any digital asset you create, provide liquidity for, or transact in; or (g) any dispute between you and any third party.

### 13.2 Defense and Settlement

Obsidian reserves the right to assume the exclusive defense and control of any matter subject to indemnification by you, and you agree to cooperate with Obsidian in asserting any available defenses. You shall not settle any claim without Obsidian's prior written consent.

***

## 14. RELEASE AND WAIVER

### 14.1 General Release

**TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, YOU RELEASE OBSIDIAN, ITS AFFILIATES, AND THEIR RESPECTIVE OFFICERS, DIRECTORS, EMPLOYEES, AGENTS, LICENSORS, AND SERVICE PROVIDERS FROM ANY AND ALL CLAIMS, DEMANDS, DAMAGES, LOSSES, COSTS, AND EXPENSES OF EVERY KIND AND NATURE, KNOWN AND UNKNOWN, SUSPECTED AND UNSUSPECTED, DISCLOSED AND UNDISCLOSED, ARISING OUT OF OR IN ANY WAY CONNECTED WITH YOUR ACCESS TO OR USE OF THE INTERFACE, THE TRADECRAFT PROTOCOL, OR ANY DIGITAL ASSET.**

### 14.2 California Civil Code Section 1542 Waiver

**IF YOU ARE A CALIFORNIA RESIDENT, YOU HEREBY WAIVE CALIFORNIA CIVIL CODE SECTION 1542, WHICH PROVIDES: "A GENERAL RELEASE DOES NOT EXTEND TO CLAIMS THAT THE CREDITOR OR RELEASING PARTY DOES NOT KNOW OR SUSPECT TO EXIST IN HIS OR HER FAVOR AT THE TIME OF EXECUTING THE RELEASE AND THAT, IF KNOWN BY HIM OR HER, WOULD HAVE MATERIALLY AFFECTED HIS OR HER SETTLEMENT WITH THE DEBTOR OR RELEASED PARTY." YOU ACKNOWLEDGE THAT YOU MAY HEREAFTER DISCOVER CLAIMS PRESENTLY UNKNOWN OR UNSUSPECTED, AND YOU AGREE THAT THIS RELEASE SHALL BE AND REMAIN EFFECTIVE IN ALL RESPECTS NOTWITHSTANDING ANY SUCH DISCOVERY.**

### 14.3 Waiver of Unknown Claims

You acknowledge that you may later discover claims or facts in addition to or different from those you now know or believe to be true regarding the subject matter of this release. You intend this release to be and remain in effect notwithstanding the discovery of any such additional or different claims or facts.

***

## 15. DISPUTE RESOLUTION

### 15.1 Mandatory Arbitration

**PLEASE READ THIS SECTION CAREFULLY. IT AFFECTS YOUR LEGAL RIGHTS, INCLUDING YOUR RIGHT TO FILE A LAWSUIT IN COURT.**

Except for disputes relating to intellectual property rights or as otherwise specified below, any dispute, controversy, or claim arising out of or relating to this Agreement, including the formation, interpretation, breach, or termination thereof, whether based in contract, tort, statute, fraud, misrepresentation, or any other legal theory, shall be resolved by final and binding arbitration administered by JAMS in accordance with its Comprehensive Arbitration Rules and Procedures.

### 15.2 Arbitration Procedures

The arbitration shall be conducted by a single arbitrator in San Juan, Puerto Rico. The language of the arbitration shall be English. The arbitrator shall have the authority to grant any remedy or relief that would be available in a court of competent jurisdiction. The arbitrator's award shall be final and binding, and judgment on the award may be entered in any court having jurisdiction.

### 15.3 Pre-Arbitration Notice

Before initiating arbitration, you must send a written notice of the dispute to Obsidian describing the nature and basis of the claim and the specific relief sought. If the dispute is not resolved within thirty (30) days after receipt of such notice, either party may initiate arbitration.

### 15.4 Class Action Waiver

**YOU AND OBSIDIAN AGREE THAT ANY DISPUTE RESOLUTION PROCEEDINGS, WHETHER IN ARBITRATION OR COURT, WILL BE CONDUCTED ONLY ON AN INDIVIDUAL BASIS AND NOT IN A CLASS, CONSOLIDATED, OR REPRESENTATIVE ACTION. YOU AND OBSIDIAN EXPRESSLY WAIVE ANY RIGHT TO PARTICIPATE IN A CLASS ACTION OR CLASS ARBITRATION. IF A COURT OR ARBITRATOR DETERMINES THAT THIS CLASS ACTION WAIVER IS UNENFORCEABLE AS TO A PARTICULAR CLAIM, THAT CLAIM SHALL BE SEVERED AND PROCEEDED WITH IN A COURT OF COMPETENT JURISDICTION, WHILE THE REMAINING CLAIMS SHALL PROCEED IN ARBITRATION.**

### 15.5 Jury Trial Waiver

**TO THE FULLEST EXTENT PERMITTED BY APPLICABLE LAW, YOU AND OBSIDIAN WAIVE ANY RIGHT TO A JURY TRIAL IN ANY LEGAL PROCEEDING ARISING OUT OF OR RELATING TO THIS AGREEMENT OR YOUR USE OF THE INTERFACE.**

### 15.6 Exceptions

Notwithstanding the foregoing, either party may seek injunctive or other equitable relief in any court of competent jurisdiction to prevent the actual or threatened infringement, misappropriation, or violation of intellectual property rights or confidential information.

### 15.7 Arbitration Costs

Each party shall bear its own costs and expenses in connection with the arbitration, except that the arbitrator may award the prevailing party its reasonable attorneys' fees and costs if permitted by applicable law.

***

## 16. GOVERNING LAW

This Agreement and any dispute arising out of or relating to this Agreement shall be governed by and construed in accordance with the laws of the Commonwealth of Puerto Rico, without regard to its conflict of laws principles. To the extent that litigation is permitted under this Agreement, you consent to the exclusive jurisdiction of the courts located in San Juan, Puerto Rico.

***

## 17. EUROPEAN UNION USERS

### 17.1 MiCA Compliance Notice

If you are located in the European Union or European Economic Area, you acknowledge that the regulatory framework for crypto-assets, including Regulation (EU) 2023/1114 on Markets in Crypto-Assets ("MiCA"), may apply to certain activities involving crypto-assets. Obsidian does not provide crypto-asset services as defined under MiCA and is not authorized as a crypto-asset service provider in any EU or EEA member state.

### 17.2 No Regulated Services

The Interface provides access to decentralized protocol functionality and does not constitute: (a) custody and administration of crypto-assets on behalf of clients; (b) operation of a trading platform for crypto-assets; (c) exchange of crypto-assets for funds or other crypto-assets; (d) execution of orders for crypto-assets on behalf of clients; (e) placing of crypto-assets; (f) reception and transmission of orders for crypto-assets on behalf of clients; (g) providing advice on crypto-assets; (h) providing portfolio management on crypto-assets; or (i) providing transfer services for crypto-assets on behalf of clients. You interact directly with the decentralized Tradecraft Protocol, not with Obsidian as an intermediary.

### 17.3 Consumer Protections

Nothing in this Agreement shall limit any rights you may have under mandatory consumer protection laws in your jurisdiction that cannot be waived by contract. To the extent any provision of this Agreement conflicts with mandatory consumer protection laws applicable to you, that provision shall be modified to the minimum extent necessary to comply with such laws.

### 17.4 No Crypto-Asset White Paper

Obsidian has not issued and does not intend to issue any crypto-asset or crypto-asset white paper. The Tradecraft Protocol does not have a native token issued by Obsidian. Any digital assets accessible through the Interface are third-party assets for which Obsidian bears no responsibility.

***

## 18. MODIFICATIONS

### 18.1 Right to Modify

Obsidian reserves the right to modify this Agreement at any time in its sole discretion. Any modifications will be effective immediately upon posting the revised Agreement on the Interface with an updated "Last Updated" date.

### 18.2 Acceptance of Modifications

Your continued access to or use of the Interface after any modifications to this Agreement constitutes your acceptance of such modifications. If you do not agree to any modifications, you must immediately cease using the Interface.

### 18.3 Notification

Obsidian may, but is not obligated to, provide additional notice of material changes through the Interface or by other means. You are responsible for reviewing this Agreement periodically to stay informed of any modifications.

***

## 19. TERMINATION

### 19.1 Termination by Obsidian

Obsidian may, in its sole discretion, terminate or suspend your access to all or part of the Interface at any time, with or without notice, for any reason, including but not limited to your breach of this Agreement or if Obsidian believes you pose a legal, regulatory, or reputational risk.

### 19.2 Termination by You

You may terminate this Agreement at any time by ceasing all use of the Interface.

### 19.3 Effect of Termination

Upon termination of this Agreement for any reason: (a) all rights and licenses granted to you under this Agreement shall immediately terminate; (b) you shall immediately cease all use of the Interface; and (c) the following sections shall survive termination: Sections 1.2, 1.3, 3, 4.3, 4.4, 6 through 16, and 19 through 21.

***

## 20. GENERAL PROVISIONS

### 20.1 Entire Agreement

This Agreement, together with the Privacy Policy, constitutes the entire agreement between you and Obsidian regarding your use of the Interface and supersedes all prior and contemporaneous agreements, proposals, or representations, written or oral, concerning its subject matter.

### 20.2 Severability

If any provision of this Agreement is held to be invalid, illegal, or unenforceable by a court or arbitrator of competent jurisdiction, such provision shall be modified to the minimum extent necessary to make it valid, legal, and enforceable, or if modification is not possible, shall be severed from this Agreement. The invalidity, illegality, or unenforceability of any provision shall not affect the validity, legality, or enforceability of the remaining provisions.

### 20.3 Waiver

No waiver of any term or condition of this Agreement shall be deemed a further or continuing waiver of such term or condition or any other term or condition, and Obsidian's failure to assert any right or provision under this Agreement shall not constitute a waiver of such right or provision.

### 20.4 Assignment

You may not assign or transfer this Agreement or any of your rights or obligations hereunder without Obsidian's prior written consent. Obsidian may freely assign or transfer this Agreement without restriction. Any attempted assignment in violation of this section shall be void.

### 20.5 No Third-Party Beneficiaries

This Agreement does not create any third-party beneficiary rights in any person, except that Obsidian's affiliates and licensors are intended third-party beneficiaries of the disclaimers and limitations of liability set forth herein.

### 20.6 Force Majeure

Obsidian shall not be liable for any failure or delay in performing its obligations under this Agreement due to causes beyond its reasonable control, including but not limited to acts of God, natural disasters, war, terrorism, riots, embargoes, acts of civil or military authorities, fire, floods, accidents, pandemic, strikes, or shortages of transportation, facilities, fuel, energy, labor, or materials.

### 20.7 Headings

The section headings in this Agreement are for convenience only and have no legal or contractual effect.

### 20.8 Language

This Agreement is drafted in English. If this Agreement is translated into any other language, the English version shall control.

***

## 21. CONTACT INFORMATION

If you have any questions about this Agreement, please contact us at:

**Obsidian Software LLC**

Mailing Address:\
151 Calle de San Francisco, Suite 200 Mailbox 1513\
San Juan, PR 00901

Email:\
<info@tradecraft.fi>

***

**BY ACCESSING OR USING THE INTERFACE, YOU ACKNOWLEDGE THAT YOU HAVE READ THIS AGREEMENT, UNDERSTAND IT, AND AGREE TO BE BOUND BY ITS TERMS AND CONDITIONS.**


# Privacy Policy

Last Updated: January 13, 2026

This Privacy Policy describes how Obsidian Software LLC ("Obsidian," "we," "us," or "our") collects, uses, and shares information in connection with your use of the Tradecraft website located at <https://tradecraft.fi> (the "Website"), the Tradecraft web application, and any other software, tools, features, or functionalities provided by Obsidian in connection therewith (collectively, the "Interface"). This Privacy Policy also describes your rights and choices regarding your information.

By accessing or using the Interface, you acknowledge that you have read and understood this Privacy Policy. If you do not agree with this Privacy Policy, please do not access or use the Interface.

***

## 1. INFORMATION WE COLLECT

### 1.1 Information You Provide to Us

**Email Addresses.** If you subscribe to our email newsletter, we collect the email address you provide through the subscription form on the Website. We do not require any other personal information to subscribe to the newsletter.

**Communications.** If you contact us directly, such as by sending an email to our contact address, we may receive and retain the contents of your message, your email address, and any other information you choose to provide.

### 1.2 Information Collected Automatically

When you access or use the Interface, we may automatically collect certain information, including:

**Device and Browser Information.** We may collect information about the device and browser you use to access the Interface, such as your device type, operating system, browser type and version, language preferences, and screen resolution.

**Log and Usage Data.** We may collect information about your interactions with the Interface, including the pages or features you access, the time and date of your visits, the time spent on pages, and other diagnostic data.

**IP Address.** We may collect your Internet Protocol (IP) address when you access the Interface. Your IP address may be used to approximate your general geographic location.

**Cookies and Similar Technologies.** We use cookies and similar tracking technologies to collect information about your interactions with the Interface. See Section 5 below for more information about our use of cookies.

### 1.3 Information We Do Not Collect

The Interface is designed to minimize personal data collection. Notably:

**No Account Information.** The Interface does not require you to create an account, and we do not collect usernames, passwords, or account credentials.

**No Wallet Credentials.** When you connect a digital asset wallet to the Interface, we do not collect or have access to your private keys, seed phrases, or wallet passwords. Your wallet connection is facilitated through third-party wallet software that you control.

**No Financial Information.** We do not collect traditional financial information such as bank account numbers or credit card details.

### 1.4 Blockchain Information

When you conduct transactions through the Interface, those transactions occur on the Canton Network blockchain. Blockchain transactions are recorded on a distributed ledger and may be visible to network participants in accordance with the Canton Network's privacy architecture. Obsidian does not control the Canton Network and is not responsible for the information recorded on or accessible through the blockchain.

***

## 2. HOW WE USE YOUR INFORMATION

We use the information we collect for the following purposes:

**To Provide and Maintain the Interface.** We use automatically collected information to operate, maintain, and improve the functionality and performance of the Interface.

**To Send Newsletters and Communications.** If you subscribe to our email newsletter, we use your email address to send you newsletters, updates, and other communications about Tradecraft. You may unsubscribe from these communications at any time.

**To Respond to Inquiries.** We use contact information you provide to respond to your questions, comments, or requests.

**To Analyze and Improve.** We use automatically collected information to analyze usage patterns, diagnose technical issues, and improve the Interface.

**To Ensure Security.** We use information to detect, prevent, and address fraud, abuse, security risks, and technical issues.

**To Comply with Legal Obligations.** We may use information as necessary to comply with applicable laws, regulations, legal processes, or governmental requests.

**To Enforce Our Terms.** We may use information to enforce our Terms of Service and other agreements.

***

## 3. HOW WE SHARE YOUR INFORMATION

We may share your information in the following circumstances:

**Service Providers.** We share information with third-party service providers who perform services on our behalf, such as email marketing platforms, analytics providers, hosting and infrastructure providers, and security services. These service providers are contractually obligated to use your information only for the purposes of providing services to us and in accordance with this Privacy Policy. Our service providers are subject to change and may operate in various locations.

**Marketing Services.** We use third-party marketing and email campaign services, including ActiveCampaign, to manage our email newsletter and communications. When you subscribe to our newsletter, your email address is shared with these service providers to facilitate the delivery of our communications.

**Legal Requirements.** We may disclose your information if required to do so by law or in response to valid requests by public authorities, such as a court order, subpoena, or government investigation.

**Protection of Rights.** We may disclose your information where we believe it is necessary to investigate, prevent, or take action regarding potential violations of our Terms of Service, suspected fraud, situations involving potential threats to the safety of any person, or as evidence in litigation in which we are involved.

**Business Transfers.** If Obsidian is involved in a merger, acquisition, reorganization, bankruptcy, or sale of assets, your information may be transferred as part of that transaction. We will provide notice if your information becomes subject to a different privacy policy.

**With Your Consent.** We may share your information with third parties when you have given us your consent to do so.

***

## 4. INTERNATIONAL DATA TRANSFERS

Obsidian is based in Puerto Rico. If you access the Interface from outside Puerto Rico or the United States, please be aware that your information may be transferred to, stored, and processed in Puerto Rico, the United States, or other jurisdictions where our service providers operate. These jurisdictions may have data protection laws that differ from those in your country.

By using the Interface or providing your information to us, you consent to the transfer, storage, and processing of your information in jurisdictions that may have different data protection standards than your home jurisdiction.

For users in the European Union or European Economic Area, we rely on appropriate safeguards for international data transfers, including standard contractual clauses, adequacy decisions, and data privacy frameworks, as applicable to our service providers.

***

## 5. COOKIES AND SIMILAR TECHNOLOGIES

### 5.1 What Are Cookies

Cookies are small text files that are stored on your device when you visit a website. Cookies allow websites to recognize your device and remember certain information about your visit.

### 5.2 How We Use Cookies

We use cookies and similar technologies for the following purposes:

**Necessary Cookies.** These cookies are essential for the operation of the Interface and enable core functionality such as security, network management, and accessibility. You cannot opt out of necessary cookies as the Interface cannot function properly without them.

**Functional Cookies.** These cookies enable enhanced functionality and personalization, such as remembering your preferences and settings. If you disable functional cookies, some features of the Interface may not work as intended.

**Analytics Cookies.** These cookies help us understand how visitors interact with the Interface by collecting and reporting information about usage patterns. Analytics cookies help us improve the Interface by understanding which pages and features are most popular and how users navigate through the site.

### 5.3 Future Technologies

We may implement additional tracking technologies in the future to improve the Interface and our services.

***

## 6. DATA RETENTION

We retain your information for as long as necessary to fulfill the purposes described in this Privacy Policy, unless a longer retention period is required or permitted by law.

**Newsletter Subscriptions.** We retain your email address for as long as you remain subscribed to our newsletter. If you unsubscribe, we will delete your email address within a reasonable period, unless we are required by law to retain it or have another lawful basis for retention.

**Automatically Collected Information.** We retain automatically collected information, such as log data and analytics information, for a reasonable period necessary to fulfill the purposes described in this Privacy Policy, after which it is either deleted or anonymized.

**Legal Requirements.** We may retain information for longer periods if required by applicable law, regulation, or legal process, or to establish, exercise, or defend legal claims.

***

## 7. DATA SECURITY

We implement reasonable technical and organizational measures designed to protect your information against unauthorized access, alteration, disclosure, or destruction. However, no method of transmission over the Internet or method of electronic storage is completely secure. While we strive to use commercially acceptable means to protect your information, we cannot guarantee its absolute security.

You are responsible for maintaining the security of your digital asset wallet, including your private keys and seed phrases. Obsidian does not have access to your wallet credentials and cannot recover lost or stolen assets.

***

## 8. YOUR RIGHTS AND CHOICES

### 8.1 Newsletter Unsubscribe

You may unsubscribe from our email newsletter at any time by clicking the "unsubscribe" link included in each newsletter or by contacting us at the email address provided below.

### 8.2 Browser Controls

You can manage cookies and similar technologies through your browser settings.

### 8.3 Do Not Track

Some browsers offer a "Do Not Track" feature that signals to websites that you do not wish to be tracked. The Interface does not currently respond to Do Not Track signals.

***

## 9. ADDITIONAL RIGHTS FOR EUROPEAN UNION USERS

If you are located in the European Union or European Economic Area, you have certain additional rights under the General Data Protection Regulation ("GDPR"):

**Legal Basis for Processing.** We process your personal data on the following legal bases: (a) your consent, such as when you subscribe to our newsletter; (b) our legitimate interests in operating and improving the Interface, provided those interests are not overridden by your rights; and (c) compliance with legal obligations.

**Right of Access.** You have the right to request access to the personal data we hold about you and to receive a copy of that data.

**Right to Rectification.** You have the right to request that we correct any inaccurate personal data we hold about you.

**Right to Erasure.** You have the right to request that we delete your personal data in certain circumstances, such as when the data is no longer necessary for the purposes for which it was collected.

**Right to Restriction.** You have the right to request that we restrict the processing of your personal data in certain circumstances.

**Right to Data Portability.** You have the right to receive your personal data in a structured, commonly used, and machine-readable format and to transmit that data to another controller.

**Right to Object.** You have the right to object to the processing of your personal data for direct marketing purposes or where processing is based on our legitimate interests.

**Right to Withdraw Consent.** Where we rely on your consent to process your personal data, you have the right to withdraw your consent at any time. Withdrawal of consent does not affect the lawfulness of processing based on consent before its withdrawal.

**Right to Lodge a Complaint.** You have the right to lodge a complaint with a supervisory authority in the EU member state of your habitual residence, place of work, or place of the alleged infringement.

To exercise any of these rights, please contact us using the contact information provided below. We may request specific information from you to confirm your identity before responding to your request.

***

## 10. CHILDREN'S PRIVACY

The Interface is not intended for use by individuals under the age of eighteen (18) or the age of legal majority in their jurisdiction, whichever is greater. We do not knowingly collect personal information from children. If we become aware that we have collected personal information from a child without verification of parental consent, we will take steps to delete that information. If you believe we may have collected information from a child, please contact us.

***

## 11. THIRD-PARTY LINKS AND SERVICES

The Interface may contain links to third-party websites, services, or applications that are not operated by us. This Privacy Policy does not apply to third-party services, and we are not responsible for the content, privacy policies, or practices of any third-party services. We encourage you to review the privacy policies of any third-party services you access.

When you connect a third-party digital asset wallet to the Interface, your use of that wallet is subject to the wallet provider's terms and privacy policy, not this Privacy Policy.

***

## 12. CHANGES TO THIS PRIVACY POLICY

We may update this Privacy Policy from time to time to reflect changes in our practices, technologies, legal requirements, or other factors. Any changes will be effective immediately upon posting the revised Privacy Policy on the Interface with an updated "Last Updated" date.

Your continued use of the Interface after we post any modifications to this Privacy Policy constitutes your acceptance of the modified Privacy Policy. We encourage you to review this Privacy Policy periodically to stay informed about how we collect, use, and protect your information.

***

## 13. CONTACT US

If you have any questions, concerns, or requests regarding this Privacy Policy or our data practices, please contact us at:

**Obsidian Software LLC**

Email: <info@tradecraft.fi>

For users in the European Union, you may also contact your local data protection authority if you have concerns about our processing of your personal data.

***

**BY USING THE INTERFACE, YOU ACKNOWLEDGE THAT YOU HAVE READ AND UNDERSTOOD THIS PRIVACY POLICY.**


# Security

## Audits

{% updates format="full" %}
{% update date="2026-01-14" %}

## AMM Exchange

Tradecraft and [Halborn](https://www.halborn.com/) have completed an audit of all DAML contracts for the AMM decentralized exchange.

<i class="fa-check">:check:</i> All issues addressed.

<https://www.halborn.com/audits/obsidian/tradecraft-amm-1e29e9>
{% endupdate %}
{% endupdates %}


