Introduction
Welcome to Anthic, an intent-based trading platform which settles trades on the Radix network.
Anthic connects DEXes, Market Makers, and Solvers into a cohesive ecosystem providing a low-fee, low-spread liquidity for DEXes, high capital efficiency for Market Makers, and profitable solving for Solvers.
How a Typical Trade on Anthic Looks Like
- A user goes to a DEX frontend and looks to swap for some amount of one token to another.
- The DEX gets pricing information from Anthic and decides how much of the trade it wants to run through its own pools or other sources of liquidity, and how much it wants to source from Anthic.
- The user sees the available deal on the DEX and confirms their interest.
- The DEX sets up a pre-authorization (subintent) which contains the steps of the desired trade and supplies the user's side of the assets and required outcomes.
- The user confirms and signs the pre-authorization in their Radix Wallet and sends it back to the DEX.
- The DEX submits the signed pre-authorization to Anthic.
- Anthic sends the market maker(s) with the best advertised price an order fill request.
- The market maker(s) send their own signed pre-authorizations to Anthic which supply the requested assets.
- Anthic publishes all signed pre-authorizations to Solvers.
- Solvers see these pre-authorizations and bundle them into a transaction and it as a transaction on the Radix network.
APIs
All functionality required by DEXes, Market Makers and Solvers to utilize Anthic are provided through three APIs:
API | Description | Requires Auth |
---|---|---|
Trade API | View supported tokens, order books, and accounts. Submit Limit Orders. | Some |
Flash Liquidity API | Allows Market Makers to provide Flash Liquidity. | Yes |
Solver API | Provides a stream of subintents which can be formed into transactions and submitted to the network. Each subintent provides a fee reward to the transaction submitter. | No |
Changes to the API can be expected as requirements are updated before production.
Rust SDK
A Rust SDK which wraps these APIs is being developed and available here.
Limit Order Subintents
Anthic currently supports limit orders for both trades going through the Trade API POST /trade/orders
endpoint and through the Flash Liquidity API.
To support off-chain processing of limit orders, Anthic uses Radix subintents. More specifically, Anthic requires a specific Subintent Manifest schema to express what is desired in the order.
The details of the exact manifest model is abstracted by the /construction/compose
endpoint. But if you wish to
build these manifests yourself either for performance reasons or for more complex manifests then this schema must
be understood.
Example
Examples of manually constructing subintent manifests can be found in the Anthic SDK Repo:
Subintent Manifest Schema
...
1. VERIFY_PARENT <verify_parent_access_rule>;
2. CALL_METHOD <account> "withdraw" <sell_resource> <sell_amount + anthic_fee_amount + settlement_fee_amount>;
3. TAKE_FROM_WORKTOP <sell_resource> <sell_amount>; -> [SellBucket]
4. ASSERT_NEXT_CALL_RETURNS_ONLY <buy_resource> AtleastAmount(<buy_amount>);
5. YIELD_TO_PARENT [SellBucket];
6. TAKE_FROM_WORKTOP <sell_resource> <anthic_fee_amount>; -> [AnthicFeeBucket]
7. TAKE_FROM_WORKTOP <sell_resource> <settlement_fee_amount>; -> [SettlementFeeBucket]
8. YIELD_TO_PARENT [AnthicFeeBucket], [SettlementFeeBucket];
9. DEPOSIT_ENTIRE_WORKTOP <account>
...
10. YIELD_TO_PARENT;
Variable | Description |
---|---|
<verify_parent_access_rule> | An AccessRule provided by Anthic on the /trade/info endpoint. It allows Anthic to ensure that the subintent gets processed by the Anthic server before being committed on-ledger. |
<account> | The user's account address which the order will swap against. The level of this account will also determine the Anthic fees required. |
<sell_resource> | The resource address the user is swapping from |
<sell_amount> | The amount the user is swapping from |
<buy_resource> | The resource address the user is swapping to |
<buy_amount> | The amount the user is swapping to |
<anthic_fee_amount> | The fee amount the user must pay to Anthic, based on the user's account level. |
<settlement_fee_amount> | The fee amount the user must pay to solvers and transaction execution |
Additional Rules:
- The manifest may begin with any number of instructions. This can include swap method calls on AMMs for example.
- 3 and only 3
YIELD_TO_PARENTS
in the pattern described in the schema above may be called. - Rebates from fees may be yielded to your subintent in the
YIELD_TO_PARENT
in line 8 (YIELD_TO_PARENT
will return some resources to you). - The execution cost of the subintent cannot exceed
5 XRD
. - The expiry timestamp of the subintent must be between 15 and 60 seconds from the time of receival by the Anthic server.
Fees
Every order submitted to Anthic requires two fees:
- An Anthic Fee which is based on the level of the user's account address and is a percentage of the sell asset
- A fixed Settlement Fee which is based on the sell asset. This consists of a Solver Fee which is a fee paid to the solver and a Transaction Execution Fee which covers the transaction execution cost. A portion of the transaction execution fee may be rebated to the user when the transaction is executed.
To see how these fees are executed see Limit Order Subintent.
Anthic Fee
To compute the Anthic Fee, retrieve the level of the user's account using the GET /trade/account_addresses
endpoint.
Every level has an associated maker/taker fee percentage which can be retrieved by using the GET /trade/info
endpoint.
Multiply this percentage to the sell amount to get the final anthic_fee_amount
.
anthic_fee_amount = anthic_fee_table[account_level].fee * sell_amount
Settlement Fee
You can retrieve the Settlement Fee by using the GET /trade/info
endpoint. For a given asset, you can retrieve
the solver_amount
and transction_execution_amount
. The sum of these two amounts is the settlement fee required
for Anthic to process the order.
A portion of the transaction_execution_amount
will be rebated back in the transaction if the execution cost
is estimated to be lower than what was paid.
settlement_fee_amount = solver_amount + transaction_execution_amount
rebated_amount = transaction_execution_amount - estimated_transaction_execution_fee_amount
DEX Integration
Anthic provides DEXes low fees, low spreads, and high liquidity across a wide number of token pairs.
To view and interact with this liquidity (expressed as an order book), you will interact with the Anthic Trade API. Orders sent to the Anthic Trade API must be sent as a Subintent Limit Order. The Anthic Trade API also allows you to read user account info and fee info in order to display accurate information to your users.
To integrate with the Radix Wallet you will utilize the Radix Dapp Toolkit to request pre-authorizations from a user's wallet.
DEX Flow of Operations
Anthic supports four main operations for DEXes:
- Get Order Book to get the latest pricing/liquidity of different token pairs
- Get Fee info to understand the fee model and be able to compute fee requirements for trades
- Create Limit Order Subintent to compose a Radix subintent manifest which Anthic supports
- Submit Limit Order to execute a subintent order on the Anthic platform
Submit Order Example
This example will go through how to integrate your DEX with the Anthic Trade API and the Radix Dapp Toolkit so that a user may submit a Limit Order Subintent to Anthic.
In this example a user wants to:
Sell 0.0003 xwBTC for xUSDC
Stream Prices
Pricing of assets can be retrieved by calling GET /trade/order_book?base=xwBTC"e=xUSDC
.
{
"pair": {
"base": "xwBTC",
"quote": "xUSDC"
},
"bids": [
[ "95086", "0.000013" ],
[ "95075", "0.000254" ],
[ "95072", "3.522345" ]
],
"asks": [
[ "95263", "4.151835" ],
[ "95264", "0.229412" ]
]
}
bids
and asks
are price-sorted arrays of (price, amount) tuples, expressing the available liquidity which
a user may take at that point in time.
This endpoint can be polled to retrieve near real-time pricing.
Compute Limit Order
Using the bids
array, we keep taking from the front of the array until the amount of requested from the user
is satisfied. This will give us an amount of xUSDC
which the user is capable of "buying" from the amount of
xwBTC
the user is "selling".
xusdc_amount = (0.000013 * 95086) + (0.000254 * 95075) + (0.000033 * 3.522345) = 25.3852842374
This value must then be rounded down based on the token's divisibility. xUSDC
has a divisibility of
6
so we round down this value to 25.385284
.
The limit order is then:
{
"sell": {
"symbol": "xwBTC",
"amount": "0.0003"
},
"buy": {
"symbol": "xUSDC",
"amount": "25.385284"
}
}
There is a possibility that the order book changes by the time submission occurs and that the order when submitted may not be filled. In order to prevent this from happening, you may on behalf of the user reduce the "buy" amount or increase the "sell" amount by a small percent. This will give the user worse pricing but a greater chance of having their order filled.
Compute Fee Amount
Anthic requires two fees which must be computed:
- An Anthic Fee which is based on the level of the user's account address and is a percentage of the sell asset
- A fixed Settlement Fee which is based on the fee payment asset. This consists of a Solver Fee which is a fee paid to the solver and a Transaction Execution Fee which covers the transaction execution cost. A portion of the transaction execution fee may be rebated to the user when the transaction is executed.
The level of a user's account address can be retrieve by GET /trade/account_addresses/account_tdx_2_128cmrtgzw82ukaphgy7yrfddh34gjnyxpmm00vkckpwzjjstwxqajm
{
"level": 1
}
The fee table configuration can be retrieved by GET /trade/info
{
"verify_parent_access_rule_sbor_hex": "5c2202012200012200012200012102809a4c6318c6318c6cb554820c6318c6318cf7a951d7a9e547c6318c6318c6c0021de40b09665d6aa3c8c9d4bcb4e4af712d5960b638efe78206591d5c7c19",
"per_token_settlement_fee": [
{
"symbol": "xwBTC",
"solver_amount": "0.000001",
"transaction_execution_amount": "0.000002"
},
{
"symbol": "xUSDC",
"solver_amount": "0.002",
"transaction_execution_amount": "0.2"
}
],
"per_level_anthic_fee": [
{
"taker_fee": "0.001",
"maker_fee": "0"
},
{
"taker_fee": "0.0009",
"maker_fee": "0"
}
]
}
If the user's account address is level 1
, then their Anthic fee given the above info is computed as:
anthic_fee = 0.0009 * 0.0003 = 0.00000027
settlement_fee = 0.000001 + 0.000002 = 0.000003
This value must then be rounded up based on the token's divisibility. xwBTC
has a divisibility of
8
so no rounding is required.
The fees will then end up looking like:
{
"symbol": "xwBTC",
"anthic_amount": "0.00000027",
"settlement_amount": "0.000003"
}
Compose Subintent Manifest
To construct a subintent manifest from a user's limit order and fee amounts you can call POST /construction/compose
with the request:
{
"type": "LimitOrder",
"account": "account_tdx_2_128cmrtgzw82ukaphgy7yrfddh34gjnyxpmm00vkckpwzjjstwxqajm",
"sell": {
"symbol": "xwBTC",
"amount": "0.0003"
},
"buy": {
"symbol": "xUSDC",
"amount": "25.385284"
},
"fee": {
"symbol": "xwBTC",
"anthic_amount": "0.00000027",
"settlement_amount": "0.000003"
}
}
You will then receive a response with a subintent manifest:
{
"manifest": "VERIFY_PARENT\n Enum<2u8>(\n Enum<0u8>(\n Enum<0u8>(\n Enum<0u8>(\n NonFungibleGlobalId(\"resource_tdx_2_1nfxxxxxxxxxxed25sgxxxxxxxxx002236757237xxxxxxxxx3e2cpa:[e40b09665d6aa3c8c9d4bcb4e4af712d5960b638efe78206591d5c7c19]\")\n )\n )\n )\n )\n;\nCALL_METHOD\n Address(\"account_tdx_2_128cmrtgzw82ukaphgy7yrfddh34gjnyxpmm00vkckpwzjjstwxqajm\")\n \"withdraw\"\n Address(\"resource_tdx_2_1t5e0853tynmm42rwjts37q4ssemxnxzx5c6ywd0fdpanm30mkkav79\")\n Decimal(\"0.00030327\")\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_tdx_2_1t5e0853tynmm42rwjts37q4ssemxnxzx5c6ywd0fdpanm30mkkav79\")\n Decimal(\"0.0003\")\n Bucket(\"sell\")\n;\nASSERT_NEXT_CALL_RETURNS_ONLY\n Map<Address, Enum>(\n Address(\"resource_tdx_2_1t5ggr0lr9vzr3mezxfrwf4g6c82ykq7yuuedkxjyns56va7vpclrkf\") => Enum<2u8>(\n Decimal(\"25.385284\")\n )\n )\n;\nYIELD_TO_PARENT\n Bucket(\"sell\")\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_tdx_2_1t5e0853tynmm42rwjts37q4ssemxnxzx5c6ywd0fdpanm30mkkav79\")\n Decimal(\"0.00000027\")\n Bucket(\"anthic-fee\")\n;\nTAKE_FROM_WORKTOP\n Address(\"resource_tdx_2_1t5e0853tynmm42rwjts37q4ssemxnxzx5c6ywd0fdpanm30mkkav79\")\n Decimal(\"0.000003\")\n Bucket(\"solver-fee\")\n;\nYIELD_TO_PARENT\n Bucket(\"anthic-fee\")\n Bucket(\"solver-fee\")\n;\nCALL_METHOD\n Address(\"account_tdx_2_128cmrtgzw82ukaphgy7yrfddh34gjnyxpmm00vkckpwzjjstwxqajm\")\n \"deposit_batch\"\n Expression(\"ENTIRE_WORKTOP\")\n;\nYIELD_TO_PARENT;\n"
}
If you would like to use a more custom manifest or manually create the manifest yourself, see Limit Order Subintents.
This manifest may then be passed to the user's wallet for signature request via a PreAuthorizationRequest
using the Radix Dapp Toolkit.
Anthic requires a delay of between 15
seconds and 60
seconds to accept a subintent. In this case, we will
use 45
seconds.
rdt.walletApi.sendPreAuthorizationRequest(
SubintentRequestBuilder()
.manifest(manifest)
.setExpiration('afterDelay', 45)).then((result) => {
return result.value.signedPartialTransaction;
})
.onSubmittedSuccess((transactionIntentHash) => {
console.log('Submitted Successfully', transactionIntentHash);
})
Submit Signed Partial Transaction To Anthic
Once the user's wallet signs the subintent a signed_partial_transaction
will be returned. You can then call
POST /orders
with the signed_partial_transaction
{
"signed_partial_transaction": "<signed-partial-transaction>"
}
On success, this will return:
{
"success": true,
"success_response": {
"subintent_id": "<transaction-subintent-id>"
}
}
Track Status of Signed Partial Transaction
The onSubmittedSuccess
callback on the subintent builder above will be called if the partial
transaction is successfully committed on-ledger.
It is possible that the partial transaction has expired before even becoming visible to the Gateway, in which case you can track if a transaction's expiry timestamp has passed and assume it will fail.
Market Maker Integration
Anthic provides Market Makers the ability to provide Flash Liquidity, or the ability provide liquidity without pre-funding on-chain, by primarily using the Flash Liquidity API.
Providing Flash Liquidity is a 3 step process:
- Publish your prices for different token pairs
- Anthic will then send you new orders which will take from the liquidity you've published
- You will response with a fill of the new order by sending a Limit Order Subintent to Anthic
If you are an instamint customer, instamint info relating to your account is available on the Trade API as well as other useful info.
Flow of Operations
Anthic supports four main operations for Market Makers utilizing Flash Liquidity:
- Publish Prices to submit your latest prices for each token pair
- Fill Orders to start receiving new orders which you will fill
- Reconcile Fills to receive updates on both historic and live fills
Flash Liquidity Example
Start Web Socket Connection
Connect to the websocket-based Flash Liquidity API with your
ANTHIC-API-KEY
.
Reconcile Past Fills
Your client most likely needs to reconcile the state of its not-yet-completed fills (because they may have been e.g. settled on-ledger since your previous session got disconnected).
Let's assume that your database has stored the latest fill update of sequence number 1337
,
and while your client was offline, Anthic has recorded that 3 of your pending fills have
been settled on-ledger.
This means that you should call the platform.fill_execution.start_stream
with a configuration
of historical_starting_point.at_sequence_number
of 1338
.
{
"method": "platform.fill_execution.start_stream",
"params": {
"enabled": true,
"historical_starting_point": 1338
}
}
Anthic will immediately call the maker.fill_execution.next
method 3 times (with
sequence numbers 1338
, 1339
and 1340
), allowing you to apply these changes and bring your
database to the current state.
{
"method": "maker.fill_execution.next",
"params": {
"sequence_number": 1338,
"occurred_at": 1733248268,
"order_id": "abc123",
"change": {
"completed": {
"outcome": "Settled"
}
}
}
}
If another fill gets settled during this session, Anthic will call the same maker.fill_execution.next
with sequence number 1341
.
Publish Your Prices
At this point, your books are up-to-date and you know your available liquidity. Thus, you can
begin streaming your prices. This is done by continuously sending platform.price_books.on_change
notifications.
{
"method": "platform.price_books.on_change",
"params": {
"pair": {
"base": "xwBTC",
"quote": "xUSDC"
},
"bids": [
[ "95086", "0.000013" ],
[ "95075", "0.000254" ],
[ "95072", "3.522345" ]
],
"asks": [
[ "95263", "4.151835" ],
[ "95264", "0.229412" ]
]
}
}
It is fine to only include pairs which actually changed (i.e. each call is treated as a "delta", not a complete re-definition of an entire catalog of pricebooks).
It is also expected that you only send pricebooks for the pairs that you actually want to trade at the moment (i.e. if you do not trade the xwBTC/XRD pair, you never include its order book in the pricebook update).
If you stop trading a particular pair, it is okay to simply update its order book with
{asks: [], bids: []}
.
Subscribe to New Orders
Since you are now ready to trade and Anthic knows your pricing, you can start the new orders
live stream by calling platform.new_orders.start_stream
.
{
"method": "platform.new_orders.start_stream",
"params": {
}
}
Optionally, you can customize the configuration here, e.g. only allow new orders of certain token pair.
Fill New Orders
From this point on, Anthic will keep sending you platform.new_orders.new
notifications
for each newly-created order.
{
"method": "platform.new_orders.new",
"params": {
"id": "abc123",
"created_at": 1733248268,
"fill_before": 1733248278,
"limit_order": {
"sell": {
"symbol": "xwBTC",
"amount": "0.0003"
},
"buy": {
"symbol": "xUSDC",
"amount": "25.385284"
}
}
}
}
Anthic will only forward orders which match your most recent pricebook (in particular,
if you do not currently trade the xwBTC
/XRD
pair, the corresponding orders will not be
offered).
You actively decide to fill some order, by calling the platform.fills.fill
and
providing a signed Limit Order Subintent for on-ledger settlement.
Track Status of Fills
If the fill is valid, Anthic sends you a maker.fill_execution.next
notification with
change.started
details. This is a de facto confirmation that Anthic began the efforts
to settle your fill on-ledger.
After some time, Anthic sends you another maker.fill_execution.next
notification,
this time with change.completed
details. This is a de facto notification of a successful
settlement (allowing you to update your books and adjust the token's availability).
Solver Integration
Solvers will receive wrapped versions of limit order subintents submitted by both DEXes and Market Makers by using the Solver API. For every subintent submitted, you will receive both a flat solver fee in XRD and an additional transaction execution fee to cover the network cost of committing the subintent on-ledger.
In general, these subintents are bundled such that they all form a coincidence of wants and it is your job as a solver to simply pass the required resources from one subintent to another subintent through your root subintent.
Each subintent yields tokens for which it is trading as well as fees which you may deposit into your own account as a solver as reward.
Once finished, the solver will submit a full transaction composed of all of these subintents to the network like a normal transaction.
Solver Example
Start Web Socket Connection
Connect to the websocket-based Solver API.
Wait for Subintent Bundles
Anthic will send subintent bundles as soon as they are available.
{
"id": null,
"jsonrpc": "2.0",
"method": "new_subintent_bundle",
"params": [
"4d2103210221012105210607020a94ef0000000000000a96ef0000000000002200002200000a9bcde95acae5855320200022000020200107209b529edcd8f768182dc20d5b5bcb5968b6cf5adaa3b83272628f07428d27748b20220b610209000000002100000280005d62a3f5498520803a31ec9034c613e205f53100f5f7021b5e2d53d737ac850090c051f4cbcbe504000000000000000000000000000000600121018100000000020180005d32f3d22b24f7baa86e92e11f02b08676699846a6344735e9687b3dc5fb6102090000000021018101000000000280005d62a3f5498520803a31ec9034c613e205f53100f5f7021b5e2d53d737ac8500a06d9e32144801000000000000000000000000000000004103800051e40b09665d6aa3c8c9d4bcb4e4af712d5960b638efe78206591d5c7c190c076465706f7369742101810200000061020900000000210183004103800051e40b09665d6aa3c8c9d4bcb4e4af712d5960b638efe78206591d5c7c190c087769746864726177210280005da66318c6318c61f5a61b4c6318c6318cf794aa8d295f14e6318c6318c6850000b2d3595bf00600000000000000000000000000000000000280005da66318c6318c61f5a61b4c6318c6318cf794aa8d295f14e6318c6318c6850000b2d3595bf00600000000000000000000000000000000600121018103000000202101012105210607020a94ef0000000000000a96ef0000000000002200002201010508aa5c67000000000a000000000000000020200022000020200020220a6201220201220001220001220001210280009a4c6318c6318c6cb554820c6318c6318cf7a951d7a9e547c6318c6318c687021de40b09665d6aa3c8c9d4bcb4e4af712d5960b638efe78206591d5c7c19410380005109b94817ce100f25a0a35a42d78c253a40aa0f34b4b14b8a52bce956dd0c087769746864726177210280005d62a3f5498520803a31ec9034c613e205f53100f5f7021b5e2d53d737ac8500302ef026e013e704000000000000000000000000000000000280005d62a3f5498520803a31ec9034c613e205f53100f5f7021b5e2d53d737ac850090c051f4cbcbe5040000000000000000000000000000000a0123802201005d32f3d22b24f7baa86e92e11f02b08676699846a6344735e9687b3dc5fb02018500a044d2b0e0020000000000000000000000000000000000600121018100000000000280005d62a3f5498520803a31ec9034c613e205f53100f5f7021b5e2d53d737ac8500a0e05435f9400100000000000000000000000000000000000280005d62a3f5498520803a31ec9034c613e205f53100f5f7021b5e2d53d737ac8500008d49fd1a0700000000000000000000000000000000006001210281010000008102000000410380005109b94817ce100f25a0a35a42d78c253a40aa0f34b4b14b8a52bce956dd0c0d6465706f7369745f626174636821018300600121002022010102200720d047686b25ca256ddd547b0f3b139d512a864859ec3ac26de9c9273bd4b7c9ac21012007405f507a5c9c84e8d750e19e7cea96b4771b4367c418407d5a0f9b26d8d2f7f58863fd7698029fa5f7088f7cc4359e40cb1e3090da5d4194aa55a7a0734fab080a20200122010102200720a4d2cf90aee486c748f9da81bebdc44f3a39808aee6ac85b326423771d107127210120074063451de7fd791f09a850c9c545a09d397039f570166fb6c1e7dca498d187beb80707f54f2697eb50c259216efff11f95a27f9ca7049e4cf5090c45a69a7ecd08",
"4d2103210221012105210607020a94ef0000000000000a96ef0000000000002200002200000a806e24d0021167a1202000220000202001072088842f428c7c8a5c5bad51ac5cc4d98fbf0bc19651afd9a821ef2351351e538820220b610209000000002100000280005d32f3d22b24f7baa86e92e11f02b08676699846a6344735e9687b3dc5fb8500a044d2b0e0020000000000000000000000000000000000600121018100000000020180005d62a3f5498520803a31ec9034c613e205f53100f5f7021b5e2d53d737ac6102090000000021018101000000000280005d32f3d22b24f7baa86e92e11f02b08676699846a6344735e9687b3dc5fb850030ef7dba020000000000000000000000000000000000004103800051e40b09665d6aa3c8c9d4bcb4e4af712d5960b638efe78206591d5c7c190c076465706f7369742101810200000061020900000000210183004103800051e40b09665d6aa3c8c9d4bcb4e4af712d5960b638efe78206591d5c7c190c087769746864726177210280005da66318c6318c61f5a61b4c6318c6318cf794aa8d295f14e6318c6318c6850000b2d3595bf00600000000000000000000000000000000000280005da66318c6318c61f5a61b4c6318c6318cf794aa8d295f14e6318c6318c6850000b2d3595bf00600000000000000000000000000000000600121018103000000202101012105210607020a94ef0000000000000a96ef0000000000002200002201010503aa5c67000000000a332b872818d5b3b020200022000020200020220d41038000c1646fa75f334d38a794c9f74de7dd57f5fea33adc8b90edf71b597899fa0c1d6372656174655f70726f6f665f6f665f6e6f6e5f66756e6769626c6573210280009a68762738e7a5006c70df616ec8e002322084bad529c7b1b9cc9198c9cd20870103532fb7d5f6369c66e129ba32d1b81dbc24a72b4c24b922dd16649b5ae5522cd8150280009a68762738e7a5006c70df616ec8e002322084bad529c7b1b9cc9198c9cd20870103532fb7d5f6369c66e129ba32d1b81dbc24a72b4c24b922dd16649b5ae5522cd841038000c05b45d24b96f686afd33c69a18b0b2027e4286c881ba778e1b3d05190480c0f6d696e745f746f5f6163636f756e74210380005d32f3d22b24f7baa86e92e11f02b08676699846a6344735e9687b3dc5fb8500d033506be302000000000000000000000000000000000082000000006201220201220001220001220001210280009a4c6318c6318c6cb554820c6318c6318cf7a951d7a9e547c6318c6318c687021de40b09665d6aa3c8c9d4bcb4e4af712d5960b638efe78206591d5c7c1941038000c1646fa75f334d38a794c9f74de7dd57f5fea33adc8b90edf71b597899fa0c087769746864726177210280005d32f3d22b24f7baa86e92e11f02b08676699846a6344735e9687b3dc5fb8500d033506be3020000000000000000000000000000000000000280005d32f3d22b24f7baa86e92e11f02b08676699846a6344735e9687b3dc5fb8500a044d2b0e00200000000000000000000000000000000000a0123802201005d62a3f5498520803a31ec9034c613e205f53100f5f7021b5e2d53d737ac0201850090c051f4cbcbe504000000000000000000000000000000600121018100000000000280005d32f3d22b24f7baa86e92e11f02b08676699846a6344735e9687b3dc5fb85000000000000000000000000000000000000000000000000000280005d32f3d22b24f7baa86e92e11f02b08676699846a6344735e9687b3dc5fb850030ef7dba02000000000000000000000000000000000000600121028101000000810200000041038000c1646fa75f334d38a794c9f74de7dd57f5fea33adc8b90edf71b597899fa0c0d6465706f7369745f626174636821018300600121002022010102200720d047686b25ca256ddd547b0f3b139d512a864859ec3ac26de9c9273bd4b7c9ac2101200740decb5ae36c4907ab99fdee07c9e3162c2d286ace1cac23c8304c5dfa35e15d0ca0e8611e8044caca56e6050b1bff31f280182714e75bcc7a089151d077cd5c0020200122010001210120074101066f866fdca0d2aad13917fa73cd030ca6f85c2b4dd8d45e2f28a03d04f4537d0523d29d40e578829e1def4863fad3b1604a17bea611181aee45b7d8b45dfd2e"
]
}
The two values in the params
array are hex-encoded Manifest-SBOR Signed Partial Transactions.
Parse Manifest into Anthic Limit Orders
Because each limit order subintent is wrapped by an Anthic subintent you must first remove outer subintent before analyzing the limit order manifest.
Once done, parse the manifests of all signed partial transactions following the Anthic Limit Order Subintent Schema.
At this point you will be able to know the <sell_resource>
, <sell_amount>
, <buy_resource>
, and <buy_amount>
of every subintent. This represents what resources each subintent is providing and requires.
Construct Root SubIntent
With this knowledge you can now construct a root subintent which includes these subintents as children and perform the required swaps between these children.
1. USE_CHILD NamedIntent("child0") Intent("...");
2. USE_CHILD NamedIntent("child1") Intent("...");
3. YIELD_TO_CHILD NamedIntent("child0");
4. YIELD_TO_CHILD NamedIntent("child1");
5. TAKE_FROM_WORKTOP <buy_resource_0> <buy_amount_0> Bucket("Buy0");
6. TAKE_FROM_WORKTOP <buy_resource_1> <buy_amount_1> Bucket("Buy1");
7. YIELD_TO_CHILD NamedIntent("child0") Bucket("Buy0");
8. YIELD_TO_CHILD NamedIntent("child1") Bucket("Buy1");
9. CALL_METHOD <solver_account> "deposit_batch" Expression("ENTIRE_WORKTOP");
The fees you will receive will be sent to your worktop in lines 7 and 8.
Submit Transaction
Once finished, sign and submit the transaction. The fees you are rewarded is deposited into your account within the same transaction.
Introduction
The Anthic Trade API is a REST-based API which allows you to view supported tokens, order books, accounts and submit limit orders.
Base URL
Staging (Stokenet): https://trade-api.staging.anthic.io
Production (Mainnet): N/A
Methods
Method | Path | Authentication Required | Description |
---|---|---|---|
GET | /network/status | No | Get network status including current epoch |
GET | /trade/info | No | Get fee info and verify parent access rule |
GET | /trade/account_addresses/:address | No | Get the level of an account address |
GET | /trade/tokens | No | Get supported tokens and associated info per token. |
GET | /trade/token_pairs | No | Get supported token pairs which have order books |
GET | /trade/accounts | Yes | Get ledger data around your ledger account |
GET | /trade/order_book?base=base"e=quote | No | Get an order book of some token pair |
POST | /trade/orders | No | Submit a Limit Order |
GET | /instamint/info | No | Get associated instamint component and resource addresses |
GET | /instamint/accounts | Yes | Get instamint accounts |
POST | /construction/compose | No | Compose a Limit Order Subintent Manifest |
POST | /construction/parse | No | Parse a subintent manifest into a Limit Order |
POST | /construction/create_subintent | No | Create a Subintent |
POST | /construction/sign | No | Create a Signed Partial Transaction given a subintent and signature |
Trade API Specification
The Trade API Specification can be found here: API Specification
Authentication
Authentication is only required for the /trade/accounts
and /instamint/accounts
endpoints.
To authenticate, http requests to these endpoints must include ANTHIC-API-KEY
as an HTTP header with
your Anthic API Key as the value.
Introduction
The Flash Liquidity API is a WebSocket-based, bidirectional JSON-RPC 2.0 API used for RFS-style ("Request For Stream") trading.
At the JSON-RPC level, both parties are technically "JSON-RPC servers" (since both you and Anthic expose some methods to be called by the other party). Each method name's prefix indicates the direction in which the message is expected to travel.
Websocket URL
Staging (Stokenet): wss://flash-liquidity-api.staging.anthic.io
Production (Mainnet): N/A
API Scope
The Flash Liquidity API is split into four channels.
Two channels where you will send data to Anthic:
- Pricebooks
- Fills
Two channels where data will be sent to you. These must be subscribed to:
- New Orders
- Fill Execution
A ping channel also exists to verify that the websocket connection is still alive.
Pricebooks
The Pricebooks channel allows you to continuously stream your newest bid/ask pricing for token pairs you are willing to trade.
See the platform.price_books.on_change
method for details.
New Orders
The New Orders channel sends you newly-created orders which match your pricebook. These orders may then be be filled or rejected by you.
Each new order is an intent to consume a specific part of liquidity which you offered in the latest pricebook you have sent.
Anthic will start the new orders live stream only after you request it for a specific session
(see the platform.new_orders.start_stream
method and the Multi-session handling
section).
Fills
The Fills channel allows you to submit signed fills for new orders sent to you
(see the platform.fills.fill
method for details).
Fill Execution
The Fill Execution channel will continuously send you both historical and live updates related to your fills.
Each fill is persistently recorded and handled by Anthic. You will be notified about the fill's
execution progress by the maker.fill_execution.next
method.
The fill execution channel uses strictly-incrementing-by-1 sequence numbers, and is thus resumable (in fact, rewindable): you can request it to be started from an arbitrary point in history. This allows you to reconcile any missed status change notifications (after your client restarts or recovers from an outage). It can also be used for performing historical queries.
Anthic will start the fill updates stream only after you request it for a specific session (see
the platform.fill_execution.start_stream
method and the Multi-session handling
section).
Flash Liquidity API Specification
The Flash Liquidity API Specification can be found here: API Specification
Authentication
Use of Flash Liquidity API requires authentication in which case you will need an Anthic API Key.
If you do not have one, please request for one from one of the team members in Slack or Telegram.
To authenticate, the initial WebSocket connection must include ANTHIC-API-KEY
as an HTTP header
with a valid Anthic API key as the value.
Multi Session Handling
This API allows you to maintain multiple API sessions (i.e. concurrent WebSocket connections) with Anthic's endpoint. However, in most aspects, the distinct sessions are not treated separately - on the contrary, they represent your single account on Anthic's backend.
In particular:
- Pricebooks sent over session B overwrite any previous pricing sent over session A
(i.e. it does not matter which session sent which token pairs and prices - a single aggregate
pricebook list is built from all pricebook updates that you send).
- For this reason, special care must be taken if multiple concurrent sessions update the pricebook of the same pair: the ordering of messages sent over the network is not deterministic, and the last update that Anthic processes overwrites any previous one.
- The same live new orders are broadcasted to all your active sessions.
- To be specific: this means all active sessions which have started the new orders stream.
- To clarify: even if session A only provides pricing for BTC/USDC while session B only provides pricing for ETH/USDC, both sessions will receive new orders for BTC/USDC and both sessions will receive new orders for ETH/USDC.
- Fill execution updates are broadcasted to all of your active sessions.
- To be specific: this means all active sessions which have started the fill execution stream.
- To clarify: even if session A has filled an order ID=abc123, both session A and session B will receive fill updates for order ID=abc123.
Solver API
The Solver API is a publicly accessible websocket based API. The connection is one-way with Anthic just pushing signed partial transactions to the client.
Websocket URL
Staging (Stokenet): wss://solver-api.staging.anthic.io/subintent-stream
Production (Mainnet): N/A
API Specification
The Solver API Specification can be found here: API Specification
Rust SDK
A Rust SDK which thinly wraps the Anthic Trade API can be found here.