diff --git a/README.md b/README.md index 5459b59..e774bb7 100644 --- a/README.md +++ b/README.md @@ -6,5 +6,6 @@ The purpose of the repository is to store and discuss intent specifications that The specifications are intended to be used as a reference for developers to understand how to create and interact with the intent. -| Number | Title | Author | Status | -| ------ | ----- | ------ | ------ | +| Number | Title | Author | Status | +| ------ |--------------------------| ------ | ------ | +| [0001](intents/dip-0001.md) | NEP-141 Token Exchange Intent Specification | @gonchar1987 | Draft | diff --git a/intents/dip-0001.md b/intents/dip-0001.md new file mode 100644 index 0000000..84b2485 --- /dev/null +++ b/intents/dip-0001.md @@ -0,0 +1,128 @@ + +| DIP | Title | Author | Status | DiscussionsTo | Version | Created | Last Updated | +|--------|-------------------|-------------------------------------|--------|---------------|---------|-------------|-------------| +| 1 | NEP-141 Token Exchange Intent Specification | Alex Gonchar | Draft | [#1](https://github.com/defuse-is-near/DIPs/pull/1)| 0.1.0 | 2024-06-20 | 2024-06-20 | + +## Overview + +This document specifies the intent for an exchange mechanism that enables the transfer of NEP-141 tokens within the [Defuse](https://defuse.org) +ecosystem. NEP-141 is the standard for fungible tokens on the NEAR blockchain, and this intent aims to facilitate +seamless and secure token exchanges between users and solvers. + +## Scope + +- Token Standard: NEP-141 +- Blockchain: NEAR Protocol +- Participants: Users and Solvers + +## Intent Interaction + +All interactions with the intent (creation and execution) are performed by sending the `ft_transfer_call` transaction to +the corresponding NEP-141 tokens which are involved in the exchange process. + +### Creation + +For the creation of the intent the initiator needs to create `Action::CreateIntent` action, serialize it with the +[Borsh](https://borsh.io) library, and encode given bytes with base64. After that, send the `ft_transfer_call` +transaction to the NEP-141 token, which the initiator wants to exchange with such arguments: + +```json +{ + "receiver_id": "intent.near", // Intent contract account id + "amount": "1000", // Amount of tokens the intent initiator wants to exchange + "msg": "base64_encoded_borsh_create_action" // Base64 encoded serialized in Borsh create action + "memo": "Create intent: NEP-141 to NEP-141" +} +``` + +### Execution + +For execution the intent the solver needs to create `Action::ExecuteIntent` action, serialize it with the +[Borsh](https://borsh.io) library, and encode given bytes with base64. After that the solver needs to send the +`ft_transfer_call` transaction to the NEP-141 token which the intent initiator wants to get with such arguments: + +```json +{ + "receiver_id": "intent.near", // Intent contract account id + "amount": "2000", // Amount of tokens the intent initiator wants to get + "msg": "base64_encoded_borsh_execute_action", // Base64 encoded serialized in Borsh execute action + "memo": "Execute intent: NEP-141 to NEP-141" +} +``` + +The exchange of the token will happen after successful intent execution. + +### Rollback + +If the intent initiator changes his mind he can roll back the intent after [minimum TTL](#minimum-ttl) by sending the +`rollback_intent` transaction to the intent contract with the intent id as an argument. After successful rollback, the +tokens will be returned to the intent initiator and the solver. + +### Minimum TTL + +The minimum TTL defines after what time the intent can be roll backed by the intent initiator. The default value +of minimum TTL is one minute, however the owner of the intent can change the value by sending `set_min_ttl` transaction +to the intent contract. + +## Data Structures + +The action for creation or execution an intent represented by the following enumeration: + +```rust +pub enum Action { + /// Action to create an intent + CreateIntent( + String, // intent id + Intent, // intent + ), + /// Action to execute an intent + ExecuteIntent( + String, // intent id + ), +} +``` + +The intent is represented by the following data structure: + +```rust +pub struct Intent { + /// Initiator of the intent + pub initiator: AccountId, + /// Tokens the initiator wants to exchange + pub send: TokenAmount, + /// Tokens the initiator wants to get instead + pub receive: TokenAmount, + /// Intent expiration + pub expiration: Expiration, + /// Referral for getting a fee + pub referral: Option, +} +``` + +The `TokenAmount` structure is defined as follows: + +```rust +pub struct TokenAmount { + /// Account id of token + pub token_id: AccountId, + /// Amount of tokens + pub amount: U128, +} +``` + +The `Expiration` is the enumeration and defined as follows: + +```rust +pub enum Expiration { + /// No expiration + None, + /// Expiration time in seconds. + Time(u64), + /// Expiration block. + Block(u64), +} +``` + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).