Intentpool

Overview

The intentpool is a service that can be run which receives intents, makes them discoverable to other parties, propagates intents peer-to-peer and tracks the state of the intent.

Intentpools serve as the layer for counterparty discovery over available swap and bond intents today and soon option and future intents. Market participants interact with the intentpool to identify fillable opportunities. Intentpools can be configured to be participate in peer-to-peer propagation or hold intents privately, depending on the needs of the application. Fabriq provides a public intentpool we call the Universal Exchange Orderbook (UnEx), which serves well as a common intentpool for the propagation of user and application intents for most use-cases. Intents submitted to UnEx are only persisted in the intentpool until they have been finalized onchain or expired.

The intentpool peer-to-peer system is currently limited but will in the future be able to share selective share intent flow peer-to-peer in the future. In the future participants will be able to have greater control over intent propagation and discover. The intentpool is implemented as a Kademlia DHT. Participants can run their own instance to ensure low latency order discovery and increase resilience of the P2P system.

Intentpool Interaction

The intentpool can be interacted with via GRPC and Protobuf-formatted messages. The Intentpool provides the following RPC calls:

service Intentpool {
    rpc Send(SendRequest) returns (SendResponse);
    rpc Get(GetRequest) returns (GetResponse);
    rpc GetAll(GetAllRequest) returns (GetAllResponse);
    rpc StreamIntents(StreamRequest) returns (stream Intent);
}

Send will provide any party connected to the intentpool the ability to submit intents:

message SendRequest {
    repeated Intent intents = 1;
}

It has the following response empty response acknowledging receipt:

message SendResponse {}

Get provides a call to check the status of an individual intent, using the Keccak256 hash of the intent data structure, in the intentpool:

message GetRequest {
    repeated bytes hashes = 1;
}

It will respond with the intent:

message GetResponse {
    repeated Intent intents = 1;
}

GetAll retrieves the contents of the intentpool. This function is diagnostic:

message GetAllRequest {}

It responds with all intents available in the intentpool:

message GetAllResponse {
    repeated Intent intents = 1;
}

StreamIntent takes an empty StreamRequest and will return a stream of intents and updates as they are made in the intentpool:

message StreamRequest {}

Intent messages are constructed through the next series of data structures. Intent message are flexible and allow for a base level of composition. Intent can either represent an intention to swap or issue a bond. A request will not need to provide IntentStatus, but responses from the intentpool will include IntentStatus.

message Intent {
    optional IntentStatus status = 1;
    oneof intent_data {
        SwapIntent swap_intent = 2;
        BondIntent bond_intent = 3;
    }
}

A SwapIntent requires a series of fields. The particular uses of these fields can be discovered in depth the [Intent Types] section. Importantly, the Item type provides a way of specifying price and price ranges for the input and output of a swap.

The initiateAfter and initiateDeadline specify when initialization of the intent by a filler is valid. The finalizeDeadline provides an expiration for fulfillment.

message SwapIntent {
    bytes swapper = 1;
    bytes nonce = 2;
    Item input = 3;
    repeated Item outputs = 4;
    bytes initiateAfter = 5;
    bytes intitateDeadline = 6;
    bytes finalizeDeadline = 7;
    bytes signature = 8;
}

A BondIntent is similar in its fields. The particular uses of these fields can be discovered in depth in the [Intent Types] section. Item similarly provides a way of specifying price and price ranges for the input and output of a bond.

message BondIntent {
    bytes solver = 1;
    bytes nonce = 2;
    bytes orderHash = 3;
    bytes srcFee = 4;
    Item input = 5;
    Item output = 6;
    bytes lpToken = 7;
    bytes lpAmount = 8;
    bytes deadline = 9;
    bytes signature = 10;
}

The Item type features four fields. The token, identified by it’s contract address, the chainId which specifies the chain, and the amountStart and amountEnd fields which specify the starting and ending prices of a dutch auction for the token. If these fields are the same, the price is fixed. Auctions can only be run over fields with a price spread.

message Item {
    bytes token = 1;
    bytes amountStart = 2;
    bytes amountEnd = 3;
    bytes chainId = 4;
}

Finally IntentStatus is given here, which will be included with queries regarding intents that exist in the intentpool.

Last updated