Swaps represent the simplest intent, the offer to buy/sell at a price. Swaps can be between tokens, NFTs, other swaps, or bonds. Swaps can be fulfilled directly from inventory or by engineering a route via liquidity.
The Fabriq SDK provides the IntentClient class as an API for creation, approval and submission of intents. It also provides abstractions for fetching metadata from the intentpool and on-chain to track the state of intents.
The Swaps section cover:
Issuing Swaps
Checking the Status of a Swap
Querying Swaps in UnEx
Winning Auctions for Swaps
Fulfilling a Swap
Finalizing a Swap
Initializing the Environment
For ease the guides will assume a common environment/setup:
The process of issuing a SwapIntent with the SDK is very simple. The IntentClient class provides a direct wrapper function for submitting intent messages to a GRPC intentpool such as UnEx.
Once the intent has been sent to UnEx, the SDK provides a function to easily report the status of an intent:
constswap=intentClient.getSwapIntent(intentId);console.log(swap.status);// `pending`, `registered`, `finalized` or `expired`
This will either report that the status of the intent is pending, registered, finalized, or expired (finalized and expired intents are only kept temporarily).
Querying Swaps
Querying intents is the first step as a potential counterparty. There are a few useful querying functions such as:
By Origin and/or Destination
By Origin and/or Destination Token Types
constswaps=awaitintentClient.querySwaps();// all fields in the filter interface are optionalfilter = { originChainIds = [ /* ... */ ], destinationChainIds = [ /* ... */ ], originTokens = [ /* ... */ ], destinationTokens = [ /* ... */ ] }constfilteredSwaps=awaitintentClient.querySwaps(filter);
The following example gets all intents originating from Optimism and destined for Sei, using the filter interface
To promote optimal routing, all potential counterparties participate in a dutch auction competing to fulfill swap intents. The first to register the intent on-chain and commit is the winner. The counterparty will need to register it on-chain.
This example first filters the intents by chain, uses a
The SDK currently does not support fulfillment from the APIs it provides. For this example, we complete fulfillment with viem provided APIs.
// get a Swap as an exampleconstswap= wonSwaps[0];// Sender's private keyconstfillerPrivateKey=/* ... */;asyncfunctiontransferExampleToken() {constwalletClient=createWalletClient({ account:privateKeyToAccount(fillerPrivateKey), chain:sei.id, transport:http(sei.url), });consttxHash=awaitwalletClient.writeContract({ abi:ERC20_ABI, address: exampleTokenAddress, functionName:'transfer', args: [swap.destinationAddress,swap.destinationAmount] });console.log('Transaction Hash:', txHash);// finalize}transferExampleToken().catch(console.error);
The last step in a swaps lifecycle, finalization, which releases the input tokens to the filler, is handled automatically by the oracle system. No interaction from the SDK is needed at this point.