Skip to content

Commit

Permalink
Merge main into relayer
Browse files Browse the repository at this point in the history
  • Loading branch information
SurgeCode committed Mar 25, 2024
2 parents eed4118 + 52e81c5 commit 4d1a08c
Show file tree
Hide file tree
Showing 15 changed files with 396 additions and 74 deletions.
6 changes: 6 additions & 0 deletions docs/1.concepts/abstraction/chain-signatures.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ title: What are Chain Signatures?
sidebar_label: What are Chain Signatures?
---

:::caution

This technology is currently in `Alpha` and should only be used in a `testnet` environment.

:::

Chain signatures enable NEAR accounts, including smart contracts, to sign and execute transactions across many blockchain protocols.

This unlocks the next level of blockchain interoperability by giving ownership of diverse assets, cross-chain accounts, and data to a single NEAR account.
Expand Down
4 changes: 2 additions & 2 deletions docs/1.concepts/abstraction/relayers.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ A relayer is a simple web service that receives signed transactions from NEAR us

![relayer-overview](/docs/assets/welcome-pages/relayer-overview.png)

Relayers are a natural consequence of [NEP-366: Meta Transactions](https://github.com/near/NEPs/blob/master/neps/nep-0366.md), a special type of transaction which can be best understood as an intent.
Relayers are a natural consequence of [Meta Transactions](meta-tx.md) ([NEP-366](https://github.com/near/NEPs/blob/master/neps/nep-0366.md)), a special type of transaction that can be best understood as an intent.

The user expresses: "I want to do a specific action on chain" and signs this intent **off-chain**, but does not send it to the network. Instead, they send the intent to a `Relayer`, which wraps the message into an actual transaction, attaches the necessary funds, and sends it to the network.
The user expresses: _"I want to do a specific action on chain"_ and signs this intent **off-chain**, but does not send it to the network. Instead, they send the intent to a `Relayer`, which wraps the message into an actual transaction, attaches the necessary funds, and sends it to the network.

<details>
<summary> Technical Details </summary>
Expand Down
8 changes: 7 additions & 1 deletion docs/1.concepts/abstraction/signatures/use-case.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ title: Use cases for Chain Signatures
sidebar_label: Use cases
---

:::caution

This technology is currently in `Alpha` and should only be used in a `testnet` environment.

:::

Chain signatures enable you to implement multichain and cross-chain workflows in a simple way.
Take a look at a few possible use cases:

Expand Down Expand Up @@ -80,7 +86,7 @@ This allows easy on-boarding to decentralized apps. The accounts are initially r

## DeFi on Bitcoin (and other non-smart contract chains).

Using chain signatures, smart contracts on NEAR can control externally-owned accounts on non-smart contract chains like Bitcoin, Dogecoin, Ripple, Bittensor, Cosmos Hub, etc. This enables developers to use NEAR as a smart contract “layer” for chains that do not support this functionality natively.
Using chain signatures, smart contracts on NEAR can control externally-owned accounts on non-smart contract chains like Bitcoin, Dogecoin, XRP Ledger, Bittensor, Cosmos Hub, etc. This enables developers to use NEAR as a smart contract “layer” for chains that do not support this functionality natively.

For example, a developer can build a decentralized exchange for Bitcoin Ordinals, using a smart contract on NEAR to manage deposits (into Bitcoin addresses controlled by the contract) and to verify and execute swaps when two users agree to trade BTC for an Ordinal or BRC20 token.

Expand Down
24 changes: 12 additions & 12 deletions docs/2.develop/integrate/frontend.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ To create a wallet, simply import the `Wallet` object from the module and initia
<CodeTabs>
<Language value="🌐 JavaScript" language="ts">
<Github fname="index.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/index.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/src/index.js"
start="2" end="8" />
</Language>
</CodeTabs>
Expand Down Expand Up @@ -112,10 +112,10 @@ For this, override the `window.onload` method with a function that calls the `wa
<CodeTabs>
<Language value="🌐 JavaScript" language="ts">
<Github fname="index.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/index.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/src/index.js"
start="10" end="21" />
<Github fname="near-wallet.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/near-wallet.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/src/near-wallet.js"
start="36" end="52" />
</Language>
</CodeTabs>
Expand All @@ -133,10 +133,10 @@ Because of their read-only nature, view methods are **free** to call, and do **n
<CodeTabs>
<Language value="🌐 JavaScript" language="ts">
<Github fname="index.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/index.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/src/index.js"
start="46" end="46" />
<Github fname="near-wallet.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/near-wallet.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/src/near-wallet.js"
start="68" end="81" />
</Language>
</CodeTabs>
Expand All @@ -160,10 +160,10 @@ Signing in is as simple as requesting the `wallet` object to `signIn`, the same
<CodeTabs>
<Language value="🌐 JavaScript" language="js">
<Github fname="index.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/index.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/src/index.js"
start="25" end="26" />
<Github fname="near-wallet.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/near-wallet.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/src/near-wallet.js"
start="54" end="66" />
</Language>
</CodeTabs>
Expand All @@ -179,7 +179,7 @@ If you instantiated the `Wallet` passing an account for the `createAccessKeyFor`
<CodeTabs>
<Language value="🌐 JavaScript" language="js">
<Github fname="index.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/index.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/src/index.js"
start="8" end="8" />
</Language>
</CodeTabs>
Expand All @@ -205,10 +205,10 @@ It is important to notice that, if you ask for money to be attached in the call,
<CodeTabs>
<Language value="🌐 JavaScript" language="js">
<Github fname="index.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/index.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/src/index.js"
start="36" end="36" />
<Github fname="near-wallet.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/near-wallet.js"
url="https://github.com/near-examples/hello-near-examples/blob/main/frontend/src/near-wallet.js"
start="83" end="103" />
</Language>
</CodeTabs>
Expand All @@ -232,10 +232,10 @@ If the method invoked returned a result, you can use the transaction hash to ret
<CodeTabs>
<Language value="🌐 JavaScript" language="js">
<Github fname="index.js"
url="https://github.com/near-examples/donation-examples/blob/main/frontend/index.js"
url="https://github.com/near-examples/donation-examples/blob/main/frontend/src/index.js"
start="71" end="92" />
<Github fname="utils.js"
url="https://github.com/near-examples/donation-examples/blob/main/frontend/near-wallet.js"
url="https://github.com/near-examples/donation-examples/blob/main/frontend/src/near-wallet.js"
start="105" end="113" />
</Language>
</CodeTabs>
Expand Down
34 changes: 34 additions & 0 deletions docs/2.develop/relayers/gas-station.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ id: gas-station
title: Multichain Gas Station Contract
sidebar_label: Multichain Gas Station
---
:::caution

This technology is currently in `Alpha` and should only be used in a `testnet` environment.

:::

The [multichain gas station smart contract](https://github.com/near/multichain-gas-station-contract) accepts payments in NEAR tokens in exchange for gas funding on non-NEAR foreign chains. Part of the NEAR Multichain effort, it works in conjunction with the [MPC recovery service](https://github.com/near/mpc-recovery) to generate on-chain signatures.

Expand Down Expand Up @@ -30,6 +35,35 @@ Transaction breakdown:

Once this service and its supporting services are live, the multichain relayer server will be monitoring this gas station contract and relaying the signed transactions in the proper order as they become available, so it will not be strictly necessary for the users of this contract to ensure that the transactions are properly relayed, unless the user wishes to relay the transactions using their own RPC (e.g. to minimize latency).

## Variable Gas fees

There's a premium on the Gas Station in `NEAR` for what the gas will cost on the foreign chain to account for variation in both the exchange rate between transactions, settlement between chains, and to account for variation in gas costs until the transaction is confirmed.

This is the formula for calculating the gas fee:

`(gas_limit_of_user_transaction + 21000) * gas_price_of_user_transaction * near_tokens_per_foreign_token * 1.2`

:::note

- `21000` is the exact amount of gas necessary to transfer funds on `BSC`.
- `1.2` is an arbitrage fee: charge 20% more than market rate to discourage people from using the Gas Station as an arbitrage/DEX.

:::

## Settlement

Settlement is needed because the Gas Station contract is accumulating NEAR, while the [Paymaster accounts](multichain-server.md#paymaster) on foreign chains are spending native foreign chain gas tokens (`ETH`, `BNB`, `SOL`, etc).

Manual Settlement involves several steps:

1. Withdrawing the NEAR held in the gas station contract and swapping for a token that can be bridged.
This may be the native gas token of the foreign chain, another token like USDC that has wide bridge support, or NEAR.

2. Bridging the token from NEAR to the foreign chain.
- Here's an [overview of bridging related to NEAR](https://knotty-marsupial-f6d.notion.site/NEAR-Bridging-Guides-f4359bd35c794dc184b098f7ed00c4ce).

3. Sending the native gas tokens to the paymaster accounts on the foreign chains.
- A swap from the bridged token to the native gas token before sending to the paymaster accounts is necessary if the token that was bridged was not the foreign chain native gas token

## Contract Interactions

Expand Down
17 changes: 14 additions & 3 deletions docs/2.develop/relayers/multichain-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ title: Multichain Relayer Server
sidebar_label: Multichain Relayer Server
---

:::caution

This technology is currently in `Alpha` and should only be used in a `testnet` environment.

:::

The [Multichain Relayer Server](https://github.com/near/multichain-relayer-server) facilitates cross-chain transactions and enables Chain Abstraction.

## Overview
Expand All @@ -26,6 +32,12 @@ Below is a design diagram of the entire multichain relayer system:
- This multichain relayer server focuses on the purple/blue Multichain Relayer Core Backend Services Box in the middle and the connections to the XChain systems in the red box via RPCs.
- The XChain Settlement that's happening in the yellow box is currently manual and will be automated in the future.

## Paymaster

A paymaster represents an address on a destination chain that holds a balance of that chain’s native gas token:
- User addresses on destination chains will be funded directly from paymaster accounts.
- Partners that want to integrate with the Multichain Gas Relayer service need to create, fund, and manage paymaster accounts on the destination chains that they want to have support for.
- [Manual settlement](gas-station.md#settlement) between the [NEAR Gas Station contract](gas-station.md) and paymaster accounts are also required on a regular basis to ensure a consistent balance of funds.

## System workflow

Expand All @@ -47,9 +59,8 @@ Below is a design diagram of the entire multichain relayer system:
## Supported Chains

- BSC testnet
- BSC Mainnet (March 31 2024)
- Solana Testnet (March 31 2024)
- Solana Mainnet (March 31 2024)
- BSC Mainnet (March 27 2024)
- Ethereum Mainnet (March 27 2024)
- More chains coming soon!

:::info
Expand Down
162 changes: 162 additions & 0 deletions docs/2.develop/relayers/relayer-gas-example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
---
id: relayer-gas-example
title: Multichain Relayer and Gas Station example
sidebar_label: Relayer + Gas Station
---
import {CodeTabs, Language, Github} from "@site/src/components/codetabs"
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

:::caution

This technology is currently in `Alpha` and should only be used in a `testnet` environment.

:::

In this article you'll learn how to run end-to-end tests on the entire Multichain Relayer system.

:::info Required tools

For this tutorial, you'll need to have installed:

- [Multichain Relayer Server](https://github.com/near/multichain-relayer-server)
- [Gas Station Event indexer](https://github.com/near/gas-station-event-indexer)
- [NEAR CLI RS](https://github.com/near/near-cli-rs)

:::

## Setup

Before you start testing, set up your local environment and install the Relayer server, the Event indexer and NEAR CLI.

### Multichain Relayer server

The main function of this server is interfacing with foreign chain RPCs sending both pre-signed funding transactions to cover gas and the actual pre-signed transaction once the funding is done.

To run the [Multichain Relayer Server](https://github.com/near/multichain-relayer-server):

1. Configure the Multichain Relayer by editing the [`config.toml`](https://github.com/near/multichain-relayer-server/blob/main/config.toml) file
2. Start the multichain relayer server:
```sh
cargo run
```

:::tip

Find the Multichain Relayer server source code in [this GitHub repository](https://github.com/near/multichain-relayer-server).

:::

### Gas Station Event indexer

The event indexer picks up events emitted from the [gas station contract](gas-station.md) used for generating signed foreign chain transactions and calls the multichain relayer `/send_funding_and_user_signed_txns` endpoint locally.

To run the [Gas Station indexer](https://github.com/near/gas-station-event-indexer):

1. Ensure you have the [Multichain Relayer Server](#multichain-relayer-server) running on `localhost:3030`
2. Create and activate a Python virtual environment:
```sh
pip install requirements.txt
```

3. Update the [`config.toml`](https://github.com/near/gas-station-event-indexer/blob/main/config.toml) configuration file with appropriate values
```
network = "testnet"
# gas station contract account id
contract_id = "canhazgas.testnet"
```

4. Run the indexer:
```sh
python3 gas-station-event-indexer.py
```

:::tip

Find the Gas Station Event indexer source code in [this GitHub repository](https://github.com/near/gas-station-event-indexer).

:::

## Running tests

The gas station contract supports EIP-1559 transactions.

1. Set the transaction details of the EVM transaction you want to send in [`generate_rlp_evm_txn.py`](https://github.com/near/multichain-relayer-server/blob/5b040611f2dc6c6b405b5ec00d5102e3cc27a65c/integration_tests/generate_rlp_evm_txn.py), run the script, and save the RLP hex string output.

:::note

Python and Rust output different hex RLP encoded transactions.
- If you're using Rust, use [`generate_eip1559_rlp_hex()`](https://github.com/near/multichain-relayer-server/blob/5b040611f2dc6c6b405b5ec00d5102e3cc27a65c/tests/tests.rs#L24).
- If you're using Python, use [`generate_rlp_encoded_transaction(is_eip_1559=true)`](https://github.com/near/multichain-relayer-server/blob/5b040611f2dc6c6b405b5ec00d5102e3cc27a65c/integration_tests/generate_rlp_evm_txn.py#L7)

:::

<CodeTabs>
<Language value="Python" language="python">
<Github fname="generate_rlp_evm_txn.py"
url="https://github.com/near/multichain-relayer-server/blob/5b040611f2dc6c6b405b5ec00d5102e3cc27a65c/integration_tests/generate_rlp_evm_txn.py"
start="7" end="13" />
</Language>
<Language value="Rust" language="rust">
<Github fname="test.rs"
url="https://github.com/near/multichain-relayer-server/blob/5b040611f2dc6c6b405b5ec00d5102e3cc27a65c/tests/tests.rs"
start="24" end="33" />
</Language>
</CodeTabs>

2. Ensure the [Multichain Relayer server](#multichain-relayer-server) is configured correctly and running.

3. Ensure the [Gas Station indexer](#gas-station-event-indexer) is running locally.

4. Construct the signed transaction using the [near-cli-rs](https://github.com/near/near-cli-rs).
The receiver account ID should be the gas station contract.
You will need 2 actions if you want the gas station to cover your gas cost on the foreign chain:
- 1 action to send the NEAR equivalent
- 1 function call to the gas station.

You should transfer the amount of `NEAR` that's needed to cover gas both on NEAR and on the foreign chain.
You also need to paste in the RLP generated hex for the EVM transaction you want on the other chain generated in step 1.
When it asks you to _send_ or _display_, choose <kbd>send</kbd>.
Example below:
```sh
near contract call-function as-transaction canhazgas.testnet create_transaction json-args '{"transaction_rlp_hex":"eb80851bf08eb000825208947b965bdb7f0464843572eb2b8c17bdf27b720b14872386f26fc1000080808080","use_paymaster":true}' prepaid-gas '100.000 TeraGas' attached-deposit '0.5 NEAR' sign-as nomnomnom.testnet network-config testnet sign-with-keychain send
```
5. Get the `"id"` from the receipts from the call in step 4, and use that to call `sign_next` twice:
```sh
near contract call-function as-transaction canhazgas.testnet sign_next json-args '{"id":"16"}' prepaid-gas '300.0 Tgas' attached-deposit '0 NEAR' sign-as nomnomnom.testnet network-config testnet sign-with-keychain send
```
## Options for testing purposes
Instead of creating a signed transaction and calling the gas station contract to sign it, you can get the recently signed transactions by calling the contract while replacing the `blockheight` with a more recent block height:
```sh
near contract call-function as-read-only canhazgas.testnet list_signed_transaction_sequences_after json-args '{"block_height":"157111000"}' network-config testnet now
```
This will return something like the output below. Take an individual entry in the list of JSONs and send that as the payload of a `POST` request to the `/send_funding_and_user_signed_txns` endpoint:
```jsx
[
{
"created_by_account_id": "b807806adcb73f6aecb5ed98bb8bd7bbe7bbf8ed342596ab700ef6b050abc4c3",
"foreign_chain_id": "97",
"signed_transactions": [
"0x02f873610385174876e80085174876e80082520894c89663ac6d169bc3e2e0a99d9fe96f2e82bcc307870eebe0b40e800080c080a0712d44ba4cd7567764231e21f054c5e7d008055222820e9d5ba148ede48755f7a06e8b812d37047593fc51fce7254ea7aef89927cada729bc903cd36fa9659dce4",
"0x02f873618085174876e80085174876e80082520894ef55a8bdf4498ea0af88bc54efb29608bb25e130872aa1efb94e000080c080a017d7024fe9e32ad8da1181729fac7e6a45311c47bf59f2b5a8b5e9fe002c0617a04ad725b362cf12c6e066c5b0b7ecbbf08f5e4d0a240337e6ddc8076f0528e3e5"
]
},
...
{
"created_by_account_id": "b807806adcb73f6aecb5ed98bb8bd7bbe7bbf8ed342596ab700ef6b050abc4c3",
"foreign_chain_id": "97",
"signed_transactions": [
"0x02f873610185174876e80085174876e80082520894c89663ac6d169bc3e2e0a99d9fe96f2e82bcc307870eebe0b40e800080c001a0ff19fe769246de8483b986e5aeaa3360bfb74f238e2a91ea353dac9aad9e24a0a020485dcd2c64172b9bc058b7813646dafbf2f27d51aae388b074e514fdb6de05",
"0x02f873618085174876e80085174876e80082520894ef55a8bdf4498ea0af88bc54efb29608bb25e130872e2f6e5e14800080c001a0dac67c383e8de3211f3c5d360cc2e9a21d160711fc3f80113ac525169317e2eca07140a1d0d1528b6eaf9fac4bb1bd44c1c4f63bb956292b0211a0dad1748e2eea"
]
}
]
```
Loading

0 comments on commit 4d1a08c

Please sign in to comment.