Hello guys - I’m Karthik, one of the cofounders of Spicenet. Spicenet is the Unified and Composable Liquidity Layer enabling developers to build highly performant, customizable and capital-efficient trading applications. We build permissionless trading and liquidity infrastructure allowing developers to customize the trading primitives, asset pairs, markets, and collateral types they want to support in their trading app.
We’re built on an intent-driven backend, allowing us to support highly heterogenous asset pairs, markets, and collateral types that various applications may demand. Intents also allow us to unify major liquidity hubs like Ethereum and Solana into one composable liquidity structure. At the core of our intent architecture is the Spicenet Execution Network that consumes incoming orders and finds optimal liquidity routes to fulfil this order, using liquidity orchestration.
I’ve been in touch with your team, incl. Maurice, Mike and Patrick regarding integrating Anoma into our Execution Network, allowing us to pass user/solver intents to Anoma for fulfilment. We have also been working on initial integration architectures. Cross-posting the architecture here to get better feedback from you all. Thank you!
Background of Spicenet Execution Network
The Spicenet Execution Network allows solvers to
- Orchestrate liquidity and therefore provide better fills to users submitting intents(orders).
- Create and share commitments with each other stating future settlement.
- Verify counterparty settlement and challenge fraudulent commitments, aka incomplete settlements.
To join the Spicenet Execution Network, solvers operate a local daemon that acts as a communication interface with other solvers over the TCP networking protocol. Support for “widgets” can be added, that are gateways to other solver protocols/networks like Anoma. What widgets allow for:
- Collaborated solving with solvers of foreign protocols.
- Expanded liquidity routes to fulfil an order, improving the quality of fills, number of markets/asset pairs that can be listed, and so on.
We’d love to integrate Anoma as a widget. Here I describe the technical integration architecture. Please feel free to suggest any improvements.
Some more detail into how Solver daemons work
A solver joining the Spicenet Executions Network does so by booting his installed solver node written in Rust. (I interchangeably use solver node and solver daemon). The solver node joins the network and starts building peers, how it is done in every other gossip network. Now the solver can use the solver node to submit new intent requests(also interchangeably referred to as RFQs), and conduct other actions listed below:
- Respond to an RFQ from an other solver with a “Quote”.
- Create and share a “pending” commitment with a counterparty solver to agree on settlement parameters.
- Create and share proofs of settlement for the counterparty solver to verify each leg of the settlement.
Integration with Anoma
As said above, we propose integrating Anoma as a widget into our solver node, effectively allowing us to
- During liquidity orchestration, submit user intents to Anoma for fulfilment.
- Allow solvers in the Execution Network to collaborate with Anoma’s solver network for coordinated liquidity settlement.
Bullet-point description of integration
Before solvers on the Spicenet Execution Network can interact with Anoma, there are some pre-requisites they need to fulfil:
- Create an Anoma keypair to sign new intents.
- At node startup, the node deploys a Juvix script that allows creation of new intents.
There are various components at play required to enable creation of new intents, signatures, gas, and submission. These can be classified into the Anoma Intent Manager and the Anoma Node. Let’s learn what each component does.
- Anoma Intent Manager: Consists of
– Intent Composer: Constructs a new intent by invoking the deployed Juvix script.
– Keypair Manager: Signs the said intent.
– Balance Manager: Verifies that appropriate gas has been paid - Anoma Node: A node running the Anoma network that receives a fully constructed intent and submits it to the Anoma network for fulfilment.
Let’s also understand what each component in the Anoma Intent Manager does.
-
Intent Composer: Does the following
– Solvers post new RFQs to a DB endpoint.
– The Intent Composer then asynchronously picks up these RFQs and creates an intent layout with the said parameters, invoking the Juvix script deployed on Anoma.
– To construct intents and invoke programs, it would use an Anoma SDK that facilitates interactions with the network. -
Juvix Script: A stateful program on Anoma written in Juvix enabling basic cross-chain swapping of tokens
– Allows solvers to interact with the program via intents.
– Maintains state such as volume swapped, keypairs interacting with the program, etc -
Keypair Manager: A module that facilitates management of keypairs on Anoma and elsewhere.
– Allows solvers to add keypairs on Anoma to sign intents
– Allows solvers to add keypairs on chains where they hold funds(i.e the source chain. For example, to swap ETH on L1 to USDC on Solana, the solver needs to provide a keypair with sufficient ETH balance).
– Allows solvers to add keypairs on chains where they desire to receive funds(in the above example, the solver needs to provide a valid Solana keypair).
– Signs the intent before submission.
– Also facilitates removal of keypairs as required. -
Balance Manager: Does the following job
– Validates where the solver has enough gas to pay for the intent
– Validates whether the solver has enough funds on the source chain to pay the Anoma solver during intent fulfillment.
Here’s how interaction with Anoma would look from a flow perspective:
- Step 1: A solver on Spicenet would invoke the solver node daemon to submit a new intent request, and specifies that settlement to be fulfilled by Anoma. Parameters of the intent request are stored in the local DB.
- Step 2: The Intent Composer asynchronously picks up the parameters, and constructs an intent invoking the Juvix script, using the intent layout specified by the Juvix script, and passing in the said parameters to the intent.
- Step 3: The intent is then signed by the keypair manager, and appropriate gas is deducted by the balance manager.
- Step 4: At this point, we have a fully constructed intent with a proper layout and parameters expressing the outcome of the intent, signature of the solver over the intent and gas to cover costs. What is left is to submit the intent to the Anoma network. This step is executed by the Anoma Node, a full node of the Anoma network that receives intents locally from solvers, and submits them to the Anoma network for execution.
- Step 5: The payload is executed by the Anoma network, and the outcome is given back to the solver.
Here is also how the actual intent would look(excluding all the script calls, etc).
- A source chain ID: Where the Spicenet solver holds funds.
- A destination chain ID: Where the Spicenet solver wants to go to.
- Note: When constituting chain IDs, we use the following format:
chain_ecosystem:chain_id
. For example, for Arbitrum, we would useeth:42161
.
- Note: When constituting chain IDs, we use the following format:
- An address on the destination chain: Where the solver wants to receive funds.
- Quote Asset: Asset that the solver is selling and its quantity.
- Base Asset: Asset that the solver is buying, its quantity, and other information such as:
- Minimum quantity to receive
- Maximum quantity to receive
- Minimum price that the solver wants to pay to buy the asset.
- Maximum price that the solver wants to pay to buy the asset.
However, I have some questions on how we could integrate Spicenet into Anoma, a reverse of this process where the Spicenet liquidity orchestrator, the party that receives orders, orchestrates them into sub-orders and submits them to solvers, could be integrated into Anoma, allowing it to fulfil intents originating on the Anoma network.
Secondly, I also wanted to know if private intents could be used here if a solver wants to keep his intents private by default.
Thank you!