Intent types and execution
Last updated
Last updated
An intent is a desired action done on your account in the Verifier
smart contract, performed by submitting a transaction to the NEAR blockchain. There are multiple possible actions that can be done, and the Verifier
allows submitting a list of these actions to be done using execute_intents
.
Multiple intents can be submitted to execute_intents
in a list, as will be seen later in the examples, where all of them will be executed in the order they are provided. Because NEAR is an asynchronous and sharded blockchain, intents submitted in a sequence does not mean that they will complete in that sequence. This is because while individual intents will be executed in order, there is no guarantee that originating from the Verifier
will end up finishing in order.
For example: The user submits a list of intents that will do two things:
Intent 1: Perform a on usdc.near to create an account on it
Intent 2: Withdraw native NEAR from the user's account in the Verifier
to usdc.near
account
In this example, there is no guarantee that the whole process will be successful, given that we quantify the success of these intent by having them all pass. The usdc.near
contract requires a storage deposit before tokens can be deposited. While the intent for storage deposit will be executed first, there is no guarantee that the calls emitted from it into the usdc.near
smart contract will finish by the time the withdrawal function call is made.
Intents are submitted as JSON objects written as strings in a payload object. The following is an example of a intent USDC
tokens from Alice to Bob.
The intent does not mention Alice, as the signer of the intent defines the account that performs transfer.
Finally, to create a valid, signed intent to submit to the Verifier
contract with the execute_intents
function, we put the payload above in a message string. Note that the message is the same JSON as above, but serialized as a one-liner with escaped quotes. This is very important.
Let's discuss the available intents:
Example of an intent to add a public key:
Example of an intent to remove a public key:
Example of an intent to invalidate nonces:
Example of an intent to transfer coins within the Verifier
contract from Alice's account to Bob's account:
Example of an intent to withdraw from Alice's account to Bob's account. Notice that on success, the tokens will be in usdc.near
contract under Bob's account there. The tokens have exited the Verifier
contract:
Example of an intent to perform storage deposit that will pay for storage deposit in the usdc.near smart contract. The Near token required (and specified) will be taken from alice.near
account, and paid to bob.near
in the usdc.near
contract:
This intent goes into a payload object that looks as follows. The "intents" in there contains the same intent from above, but in an array, because users can submit multiple intents to be executed as a batch in order. Keep in mind the about the order of execution.
The field "recipient" prevents replay attacks on other copies of the Verifier
on the NEAR blockchain. The exact cryptographic mechanisms for signing will be discussed in the .
There are multiple that can be submitted for execution in the Verifier
contract. Note that every intent has its own parametrization. The parameters needed to execute the intent can be seen in the linked docs. Rust object names are usually converted to in JSON. Hence, an intent like TokenDiff
becomes token_diff
.
: Given an account id in the Verifier
contract, the user can add public keys to this account. The added public key's private key can sign intents on behalf of this account, even to add new ones. Warning: Implicit account ids, by default, have their corresponding public keys added. This means if a private key is leaked for an implicit account used in intents, the user must manually rotate the public key in the Verifier.
Note that public keys can be added through transactions too. See for more information.
: Removes a public key associated with a given account.
Note that public keys can be removed through transactions too. See for more information.
: Every intent execution requires a nonce. Each account id gets (over time, while using the Verifier
) more nonces, and this ensures that nonces are not reused to avoid replay attacks. This “marks” the nonce as used.
Note that nonces can be invalidated .
: Transfer a set of tokens from the signer to a specified account id, within the intents contract.
Note that transfers can be done using .
Note that token ids are specified in Multi Token format that was discussed in .
, , , are withdraw intents to move their tokens from the Verifier
contract to an arbitrary address. More information .
: Make an storage_deposit
call for an account_id
on contract_id
. The amount
will be subtracted from user’s NEP-141 wNEAR
balance. The wNEAR
will not be refunded in any case.
: The user declares the will to have a set of changes done to set of tokens. For example, a simple trade of 100 of token A for 200 of token B, can be represented by TokenDiff
of {“A”: -100, “B”: 200} (this format is just for demonstration purposes). In general, the user can submit multiple changes with many tokens, not just token A for token B.
Example of two intents submitted from two users to be used with the Verifier's
smart contract's execute_intents
function. In the first intent, Alice declares that she is willing to lose 10 USDC
to get 10 USDT
in return. In the second intent, Bob declares their will to lose 10 USDT
and get 10 USDC
in return. As mentioned in the , there are many different ways to put these intents together for submission to the blockchain, such as in the or with third parties or any off-chain communication channel. Once a transaction is submitted calling the function execute_intents
in the Verifier's
smart contract, the Verifier
solves the TokenDiff
orders and converts them into transfers from Alice to Bob and Bob to Alice.