From a0a62ff10ec2468af0f9d34fc710c0fb48a98c0e Mon Sep 17 00:00:00 2001 From: garikbesson Date: Thu, 1 Aug 2024 16:53:25 +0300 Subject: [PATCH 01/11] Update Collections page (#2146) * added Iterable Set/Map + changed code urls (temporarily) * additional changes * nested errors explanation changes * update js collections examples * updated Pagination section * additional comment about using collections in JS * fix: snippets and text --------- Co-authored-by: Guille --- .../2.smart-contracts/anatomy/collections.md | 417 +++++++++--------- 1 file changed, 211 insertions(+), 206 deletions(-) diff --git a/docs/2.build/2.smart-contracts/anatomy/collections.md b/docs/2.build/2.smart-contracts/anatomy/collections.md index 566afb6d2c9..61859ca936a 100644 --- a/docs/2.build/2.smart-contracts/anatomy/collections.md +++ b/docs/2.build/2.smart-contracts/anatomy/collections.md @@ -6,17 +6,14 @@ import {CodeTabs, Language, Github} from "@site/src/components/codetabs" import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -When deciding on data structures to use for the data of the application, it is important to understand the tradeoffs of data structures in your smart contract. - -Choosing the wrong structure can create a bottleneck as the application scales, and migrating the state to the new data structures will come at a cost. +When deciding on data structures it is important to understand their tradeoffs. Choosing the wrong structure can create a bottleneck as the application scales, and migrating the state to the new data structures will come at a cost. You can choose between two types of collections: 1. Native collections (e.g. `Array`, `Map`, `Set`), provided by the the language -2. SDK collections (e.g. `UnorderedMap`, `Vector`), provided by the NEAR SDK - -Since the SDK reads all the contract's attributes when a function is executed - and writes them back when it finishes - understanding how the SDK stores and loads both types of collections is crucial to decide which one to use. +2. SDK collections (e.g. `IterableMap`, `Vector`), provided by the NEAR SDK +Understanding how the contract stores and loads both types of collections is crucial to decide which one to use. :::tip @@ -24,9 +21,9 @@ Use native collections for small amounts of data that need to be accessed all to ::: -:::info +:::info How the State is Handled -Contracts store all their data in a `key-value` database. The SDK handles this database, and stores values [serialized in JSON or Borsh](./serialization.md) +Each time the contract is executed, the first thing it will do is to read the values and [deserialize](./serialization.md) them into memory, and after the function finishes, it will [serialize](./serialization.md) and write the values back to the database. ::: @@ -35,10 +32,10 @@ Contracts store all their data in a `key-value` database. The SDK handles this d ## Native Collections Native collections are those provided by the language: -- JS: `Array`, `Set`, `Map` -- Rust: `Vector`, `HashMap`, `Set` +- JS: `Array`, `Set`, `Map`, `Object` ... +- Rust: `Vector`, `HashMap`, `Set` ... -All entries in a native collection are serialized into a single value and stored together into the state. This means that every time a function execute, the SDK will read and deserialize all entries in the native collection. +All entries in a native collection are **serialized into a single value** and **stored together** into the state. This means that every time a function execute, the SDK will read and **deserialize all entries** in the native collection.
@@ -54,9 +51,9 @@ Native collections are useful if you are planning to store smalls amounts of dat ::: -:::warning Keep Native Collections Small +:::danger Keep Native Collections Small -As the collection grows, reading and writing it will cost more and more gas. If the collections grows too large, your contract might end up expending all its available gas in reading/writing the state, thus becoming unusable +As the native collection grows, deserializing it from memory will cost more and more gas. If the collections grows too large, your contract might expend all the gas trying to read its state, making it fail on each function call ::: @@ -64,9 +61,9 @@ As the collection grows, reading and writing it will cost more and more gas. If ## SDK Collections -The NEAR SDKs expose collections that are optimized to store large amounts of data in the contract's state. These collections are built to have an interface similar to native collections. +The NEAR SDKs expose collections that are optimized for random access of large amounts of data. SDK collections are instantiated using a "prefix", which is used as an index to split the data into chunks. This way, SDK collections can defer reading and writing to the store until needed. -SDK collections are instantiated using a "prefix", which is used as an index to split the data into chunks. This way, SDK collections can defer reading and writing to the store until needed. +These collections are built to have an interface similar to native collections.
@@ -93,32 +90,44 @@ SDK collections are useful when you are planning to store large amounts of data | SDK Collection | Native Equivalent | Description | |----------------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `Vector` | `Array` | A growable array type. The values are sharded in memory and can be used for iterable and indexable values that are dynamically sized. | -| `LookupMap` | `Map` | This structure behaves as a thin wrapper around the key-value storage available to contracts. This structure does not contain any metadata about the elements in the map, so it is not iterable. | -| `UnorderedMap` | `Map` | Similar to `LookupMap`, except that it stores additional data to be able to iterate through elements in the data structure. | | `LookupSet` | `Set` | A set, which is similar to `LookupMap` but without storing values, can be used for checking the unique existence of values. This structure is not iterable and can only be used for lookups. | | `UnorderedSet` | `Set` | An iterable equivalent of `LookupSet` which stores additional metadata for the elements contained in the set. | +| `LookupMap` | `Map` | This structure behaves as a thin wrapper around the key-value storage available to contracts. This structure does not contain any metadata about the elements in the map, so it is not iterable. | +| `UnorderedMap` | `Map` | Similar to `LookupMap`, except that it stores additional data to be able to iterate through elements in the data structure. | -:::info Note +| SDK collection | `std` equivalent | Description | +|-----------------------------------------------|-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `store::Vector` | `Vec` | A growable array type. The values are sharded in memory and can be used for iterable and indexable values that are dynamically sized. | +| store::LookupMap`` | HashMap`` | This structure behaves as a thin wrapper around the key-value storage available to contracts. This structure does not contairn any metadata about the elements in the map, so it is not iterable. | +| store::IterableMap`` | HashMap`` | Similar to `LookupMap`, except that it stores additional data to be able to iterate through elements in the data structure. | +| store::UnorderedMap`` | HashMap`` | Similar to `LookupMap`, except that it stores additional data to be able to iterate through elements in the data structure. | +| `store::LookupSet` | `HashSet` | A set, which is similar to `LookupMap` but without storing values, can be used for checking the unique existence of values. This structure is not iterable and can only be used for lookups. | +| `store::IterableSet` | `HashSet` | An iterable equivalent of `LookupSet` which stores additional metadata for the elements contained in the set. | +| `store::UnorderedSet` | `HashSet` | An iterable equivalent of `LookupSet` which stores additional metadata for the elements contained in the set. | -The `near_sdk::collections` will be moving to `near_sdk::store` and have updated APIs. If you would like to access these updated structures as they are being implemented, enable the `unstable` feature on `near-sdk`. + -::: + + +:::info Note +The `near_sdk::collections` is now deprecated in favor of `near_sdk::store`. To use `near_sdk::collections` you will have to use the [`legacy` feature](https://github.com/near-examples/storage-examples/blob/2a138a6e8915e08ce76718add3e36c04c2ea2fbb/collections-rs/legacy/Cargo.toml#L11). -| SDK collection | `std` equivalent | Description | -|----------------------------------------|------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `LazyOption` | `Option` | Optional value in storage. This value will only be read from storage when interacted with. This value will be `Some` when the value is saved in storage, and `None` if the value at the prefix does not exist. | -| `Vector` | `Vec` | A growable array type. The values are sharded in memory and can be used for iterable and indexable values that are dynamically sized. | -| LookupMap`` | HashMap`` | This structure behaves as a thin wrapper around the key-value storage available to contracts. This structure does not contain any metadata about the elements in the map, so it is not iterable. | -| UnorderedMap`` | HashMap`` | Similar to `LookupMap`, except that it stores additional data to be able to iterate through elements in the data structure. | -| TreeMap`` | BTreeMap`` | An ordered equivalent of `UnorderedMap`. The underlying implementation is based on an [AVL tree](https://en.wikipedia.org/wiki/AVL_tree). This structure should be used when a consistent order is needed or accessing the min/max keys is needed. | -| `LookupSet` | `HashSet` | A set, which is similar to `LookupMap` but without storing values, can be used for checking the unique existence of values. This structure is not iterable and can only be used for lookups. | -| `UnorderedSet` | `HashSet` | An iterable equivalent of `LookupSet` which stores additional metadata for the elements contained in the set. | +::: +| SDK collection | `std` equivalent | Description | +|----------------------------------------------------|------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `collections::Vector` | `Vec` | A growable array type. The values are sharded in memory and can be used for iterable and indexable values that are dynamically sized. | +| collections::LookupMap`` | HashMap`` | This structure behaves as a thin wrapper around the key-value storage available to contracts. This structure does not contairn any metadata about the elements in the map, so it is not iterable. | +| collections::UnorderedMap`` | HashMap`` | Similar to `LookupMap`, except that it stores additional data to be able to iterate through elements in the data structure. | +| collections::TreeMap`` | BTreeMap`` | An ordered equivalent of `UnorderedMap`. The underlying implementation is based on an [AVL tree](https://en.wikipedia.org/wiki/AVL_tree). This structure should be used when a consistent order is needed or accessing the min/max keys is needed. | +| `collections::LookupSet` | `HashSet` | A set, which is similar to `LookupMap` but without storing values, can be used for checking the unique existence of values. This structure is not iterable and can only be used for lookups. | +| `collections::UnorderedSet` | `HashSet` | An iterable equivalent of `LookupSet` which stores additional metadata for the elements contained in the set. | +| `collections::LazyOption` | `Option` | Optional value in storage. This value will only be read from storage when interacted with. This value will be `Some` when the value is saved in storage, and `None` if the value at the prefix does not exist. | @@ -131,8 +140,11 @@ The `near_sdk::collections` will be moving to `near_sdk::store` and have updated | `Vector` | βœ… | βœ… | βœ… | βœ… | | `LookupSet` | | | | | | `UnorderedSet` | βœ… | βœ… | | βœ… | +| `IterableSet` | βœ… | βœ… | | βœ… | | `LookupMap` | | | | | | `UnorderedMap` | βœ… | βœ… | | βœ… | +| `IterableMap` | βœ… | βœ… | | βœ… | +| `TreeMap` | βœ… | βœ… | βœ… | βœ… |
@@ -143,8 +155,9 @@ The `near_sdk::collections` will be moving to `near_sdk::store` and have updated | `Vector` | O(1) | O(1)\* | O(1)\*\* | O(n) | O(n) | O(n) | | `LookupSet` | O(1) | O(1) | O(1) | O(1) | N/A | N/A | | `UnorderedSet` | O(1) | O(1) | O(1) | O(1) | O(n) | O(n) | +| `IterableSet` | O(1) | O(1) | O(1) | O(1) | O(n) | O(n) | | `LookupMap` | O(1) | O(1) | O(1) | O(1) | N/A | N/A | -| `UnorderedMap` | O(1) | O(1) | O(1) | O(1) | O(n) | O(n) | +| `IterableMap` | O(1) | O(1) | O(1) | O(1) | O(n) | O(n) | | `TreeMap` | O(1) | O(log n) | O(log n) | O(log n) | O(n) | O(n) | _\* - to insert at the end of the vector using `push_back` (or `push_front` for deque)_ @@ -152,7 +165,11 @@ _\*\* - to delete from the end of the vector using `pop` (or `pop_front` for deq --- -## Collections Cookbook +## SDK Collections Cookbook + +Let's see how to use the SDK collections in practice + +
### Instantiation @@ -160,32 +177,45 @@ All structures need to be initialized using a **unique `prefix`**, which will be - + + + +:::tip + +Do not forget to use the `schema` to define how your contract's state is structured + +::: + + url="https://github.com/near-examples/storage-examples/blob/main/collections-rs/store/src/lib.rs" + start="24" end="47"/> :::tip - Notice how we use `enums` to ensure all collections have a different prefix. Moreover, `enums` are very efficient since they get serialized into a single `byte` prefix. + Notice how we use `enums` to ensure all collections have a different prefix. Another advantage of using `enums` is that they are serialized into a single `byte` prefix. ::: - + + -:::warning + :::tip -Because the values are not kept in memory and are lazily loaded from storage, it's important to make sure if a collection is replaced or removed, that the storage is cleared. In addition, it is important that if the collection is modified, the collection itself is updated in state because most collections will store some metadata. + Notice how we use `enums` to ensure all collections have a different prefix. Another advantage of using `enums` is that they are serialized into a single `byte` prefix. -::: + ::: + + + :::danger @@ -199,60 +229,94 @@ Be careful of not using the same prefix in two collections, otherwise, their sto Implements a [vector/array](https://en.wikipedia.org/wiki/Array_data_structure) which persists in the contract's storage. Please refer to the Rust and JS SDK's for a full reference on their interfaces. - - - - - - - - - + + + + + + + + + + +
-### Map +### LookupMap Implements a [map/dictionary](https://en.wikipedia.org/wiki/Associative_array) which persists in the contract's storage. Please refer to the Rust and JS SDK's for a full reference on their interfaces. - - - - - - - - - + + + + + + + +
-### Set +### UnorderedMap / IterableMap + +Implements a [map/dictionary](https://en.wikipedia.org/wiki/Associative_array) which persists in the contract's storage. Please refer to the Rust and JS SDK's for a full reference on their interfaces. + + + + + + + + + + +
+ +### LookupSet Implements a [set](https://en.wikipedia.org/wiki/Set_(abstract_data_type)) which persists in the contract's storage. Please refer to the Rust and JS SDK's for a full reference on their interfaces. - - - - - - - - - - + + + + + + + + + + +
+ +### UnorderedSet / IterableSet + +Implements a [map/dictionary](https://en.wikipedia.org/wiki/Associative_array) which persists in the contract's storage. Please refer to the Rust and JS SDK's for a full reference on their interfaces. + + + + + + + + +
@@ -260,23 +324,18 @@ Implements a [set](https://en.wikipedia.org/wiki/Set_(abstract_data_type)) which An ordered equivalent of Map. The underlying implementation is based on an [AVL](https://en.wikipedia.org/wiki/AVL_tree). You should use this structure when you need to: have a consistent order, or access the min/max keys. - - - - - - + + + + +
-### `LazyOption` +### LazyOption (Legacy) -It's a type of persistent collection that only stores a single value. -The goal is to prevent a contract from deserializing the given value until it's needed. -An example can be a large blob of metadata that is only needed when it's requested in a view call, -but not needed for the majority of contract operations. +LazyOptions are great to store large values (i.e. a wasm file), since its value will not be read from storage until it is interacted with. It acts like an `Option` that can either hold a value or not and also requires a unique prefix (a key in this case) like other persistent collections. @@ -287,90 +346,26 @@ Compared to other collections, `LazyOption` only allows you to initialize the va ## Nesting Collections -It is possible to nest collections. When nesting SDK collections, remember to **assign different prefixes to all collections** (including the nested ones). +When nesting SDK collections, be careful to **use different prefixes** for all collections, including the nested ones. - While you can create nested maps, you first need to construct or deconstruct the structure from state. This is a temporary solution that will soon be automatically handled by the SDK. - - ```ts - import { NearBindgen, call, view, near, UnorderedMap } from "near-sdk-js"; - - @NearBindgen({}) - class StatusMessage { - records: UnorderedMap; - constructor() { - this.records = new UnorderedMap("a"); - } - - @call({}) - set_status({ message, prefix }: { message: string; prefix: string }) { - let account_id = near.signerAccountId(); - - const inner: any = this.records.get("b" + prefix); - const inner_map: UnorderedMap = inner - ? UnorderedMap.deserialize(inner) - : new UnorderedMap("b" + prefix); - - inner_map.set(account_id, message); - - this.records.set("b" + prefix, inner_map); - } - - @view({}) - get_status({ account_id, prefix }: { account_id: string; prefix: string }) { - const inner: any = this.records.get("b" + prefix); - const inner_map: UnorderedMap = inner - ? UnorderedMap.deserialize(inner) - : new UnorderedMap("b" + prefix); - return inner_map.get(account_id); - } - } - ``` + - In Rust the simplest way to avoid collisions between nested collections is by using `enums` + - ```rust - use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize}; - use near_sdk::collections::{UnorderedMap, UnorderedSet}; - use near_sdk::{env, near, AccountId, BorshStorageKey, CryptoHash}; - - #[near(contract_state)] - pub struct Contract { - pub accounts: UnorderedMap>, - } - - impl Default for Contract { - fn default() -> Self { - Self { - accounts: UnorderedMap::new(StorageKeys::Accounts), - } - } - } - - #[near(serializers = [borsh])] - pub enum StorageKeys { - Accounts, - SubAccount { account_hash: CryptoHash }, - } - - #[near] - impl Contract { - pub fn get_tokens(&self, account_id: &AccountId) -> Vec { - let tokens = self.accounts.get(account_id).unwrap_or_else(|| { - UnorderedSet::new(StorageKeys::SubAccount { - account_hash: env::sha256_array(account_id.as_bytes()), - }) - }); - tokens.to_vec() - } - } - ``` + :::tip + + Notice how we use `enums` that take a `String` argument to ensure all collections have a different prefix + + ::: @@ -384,13 +379,6 @@ Because the values are not kept in memory and are lazily loaded from storage, it Some error-prone patterns to avoid that cannot be restricted at the type level are: - - - - - - - @@ -446,9 +434,9 @@ assert!( // as reads, and the writes are performed on [`Drop`](https://doc.rust-lang.org/std/ops/trait.Drop.html) // so if the collection is kept in static memory or something like `std::mem::forget` is used, // the changes will not be persisted. -use near_sdk::store::LookupSet; +use near_sdk::store::IterableSet; -let mut m: LookupSet = LookupSet::new(b"l"); +let mut m: IterableSet = IterableSet::new(b"l"); m.insert(1); assert!(m.contains(&1)); @@ -456,7 +444,7 @@ assert!(m.contains(&1)); // m.flush(); std::mem::forget(m); -m = LookupSet::new(b"l"); +m = IterableSet::new(b"l"); assert!(!m.contains(&1)); ``` @@ -470,7 +458,7 @@ Some issues for more context: - https://github.com/near/near-sdk-rs/issues/560 - https://github.com/near/near-sdk-rs/issues/703 -The following cases are the most commonly encountered bugs that cannot be restricted at the type level: +The following cases are the most commonly encountered bugs that cannot be restricted at the type level (only relevant for `near_sdk::collections`, not `near_sdk::store`): ```rust use near_sdk::borsh::{self, BorshSerialize}; @@ -502,8 +490,7 @@ let n = root.get(&1).unwrap(); assert!(n.is_empty()); assert!(n.contains(&"test".to_string())); -// Bug 2 (only relevant for `near_sdk::collections`, not `near_sdk::store`): Nested -// collection is modified without updating the collection itself in the outer collection. +// Bug 2: Nested collection is modified without updating the collection itself in the outer collection. // // This is fixed at the type level in `near_sdk::store` because the values are modified // in-place and guarded by regular Rust borrow-checker rules. @@ -527,35 +514,53 @@ assert!(n.contains(&"some value".to_string())); ## Pagination -Persistent collections such as `UnorderedMap`, `UnorderedSet` and `Vector` may +Persistent collections such as `IterableMap/UnorderedMap`, `IterableSet/UnorderedSet` and `Vector` may contain more elements than the amount of gas available to read them all. In order to expose them all through view calls, we can use pagination. -This can be done using iterators with [`Skip`](https://doc.rust-lang.org/std/iter/struct.Skip.html) and [`Take`](https://doc.rust-lang.org/std/iter/struct.Take.html). This will only load elements from storage within the range. -Example of pagination for `UnorderedMap`: -```rust -#[near(contract_state)] -#[derive(PanicOnDefault)] -pub struct Contract { - pub status_updates: UnorderedMap, -} + + + With JavaScript this can be done using iterators with [`toArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/toArray) and [`slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice). -#[near] -impl Contract { - /// Retrieves multiple elements from the `UnorderedMap`. - /// - `from_index` is the index to start from. - /// - `limit` is the maximum number of elements to return. - pub fn get_updates(&self, from_index: usize, limit: usize) -> Vec<(AccountId, String)> { - self.status_updates - .iter() - .skip(from_index) - .take(limit) - .collect() - } -} -``` + ```ts + /// Returns multiple elements from the `UnorderedMap`. + /// - `from_index` is the index to start from. + /// - `limit` is the maximum number of elements to return. + @view({}) + get_updates({ from_index, limit }: { from_index: number, limit:number }) { + return this.status_updates.toArray().slice(from_index, limit); + } + ``` + + + + With Rust this can be done using iterators with [`Skip`](https://doc.rust-lang.org/std/iter/struct.Skip.html) and [`Take`](https://doc.rust-lang.org/std/iter/struct.Take.html). This will only load elements from storage within the range. + + ```rust + #[near(contract_state)] + #[derive(PanicOnDefault)] + pub struct Contract { + pub status_updates: IterableMap, + } + + #[near] + impl Contract { + /// Retrieves multiple elements from the `IterableMap`. + /// - `from_index` is the index to start from. + /// - `limit` is the maximum number of elements to return. + pub fn get_updates(&self, from_index: usize, limit: usize) -> Vec<(AccountId, String)> { + self.status_updates + .iter() + .skip(from_index) + .take(limit) + .collect() + } + } + ``` + + --- From 8939d68b3b8c006fa0272670dcf993aa9b07c722 Mon Sep 17 00:00:00 2001 From: matiasbenary Date: Thu, 1 Aug 2024 14:03:32 -0300 Subject: [PATCH 02/11] fix: hide on logo when used in an iframe (#2193) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: hide on logo when used in an iframe * fix: build check * fix: build check * fix: build check * fix: build check * fix: build check --------- Co-authored-by: DamiΓ‘n Parrino --- website/src/theme/Navbar/Logo/index.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/website/src/theme/Navbar/Logo/index.js b/website/src/theme/Navbar/Logo/index.js index 0ab73ab1715..d85776fb19c 100644 --- a/website/src/theme/Navbar/Logo/index.js +++ b/website/src/theme/Navbar/Logo/index.js @@ -1,13 +1,11 @@ import React from 'react'; import Logo from '@theme/Logo'; -import BrowserOnly from '@docusaurus/BrowserOnly'; +import useIsBrowser from '@docusaurus/useIsBrowser'; export default function NavbarLogo() { - + const isBrowser = useIsBrowser(); // if embedded in an iframe, do not show the logo - - {() => { if (window.location !== window.parent.location) return null; }} - + if (isBrowser && typeof window !== 'undefined' && window.self !== window.top) return null; return ( Date: Mon, 5 Aug 2024 07:50:21 -0400 Subject: [PATCH 03/11] docs: added info about new status codes that can be returned by `jsonrpc` (#2195) --- docs/5.api/rpc/access-keys.md | 27 ++++++++++++++ docs/5.api/rpc/block-chunk.md | 17 +++++++++ docs/5.api/rpc/contracts.md | 52 +++++++++++++++++++++++++++ docs/5.api/rpc/gas.md | 4 +++ docs/5.api/rpc/maintenance-windows.md | 2 ++ docs/5.api/rpc/network.md | 8 +++++ docs/5.api/rpc/protocol.md | 5 +++ docs/5.api/rpc/transactions.md | 28 +++++++++++++++ 8 files changed, 143 insertions(+) diff --git a/docs/5.api/rpc/access-keys.md b/docs/5.api/rpc/access-keys.md index e7c5cc3a4bd..652f421a8fa 100644 --- a/docs/5.api/rpc/access-keys.md +++ b/docs/5.api/rpc/access-keys.md @@ -132,6 +132,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ error.name ERROR_CAUSE
error.cause.name + Status Code Reason Solution @@ -140,6 +141,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
    @@ -150,6 +152,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ INVALID_ACCOUNT + 200 The requested account_id is invalid
      @@ -159,6 +162,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ UNKNOWN_ACCOUNT + 200 The requested account_id has not been found while viewing since the account has not been created or has been already deleted
        @@ -169,6 +173,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ UNKNOWN_ACCESS_KEY + 200 The requested public_key has not been found while viewing since the public key has not been created or has been already deleted
          @@ -179,6 +184,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ UNAVAILABLE_SHARD + 200 The node was unable to found the requested data because it does not track the shard where data is present
            @@ -188,6 +194,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ NO_SYNCED_BLOCKS + 200 The node is still syncing and the requested block is not in the database yet
              @@ -199,6 +206,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                @@ -210,6 +218,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                  @@ -448,6 +457,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ error.name ERROR_CAUSE
                  error.cause.name + Status Code Reason Solution @@ -456,6 +466,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                    @@ -466,6 +477,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ INVALID_ACCOUNT + 200 The requested account_id is invalid
                      @@ -475,6 +487,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ UNKNOWN_ACCOUNT + 200 The requested account_id has not been found while viewing since the account has not been created or has been already deleted
                        @@ -485,6 +498,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ UNAVAILABLE_SHARD + 200 The node was unable to find the requested data because it does not track the shard where data is present
                          @@ -494,6 +508,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ NO_SYNCED_BLOCKS + 200 The node is still syncing and the requested block is not in the database yet
                            @@ -505,6 +520,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                              @@ -516,6 +532,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                @@ -669,6 +686,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER error.name ERROR_CAUSE
                                error.cause.name + Status Code Reason Solution @@ -677,6 +695,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                  @@ -687,6 +706,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER NOT_SYNCED_YET + 200 The node is still syncing and the requested block is not in the database yet
                                    @@ -698,6 +718,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                      @@ -709,6 +730,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                        @@ -862,6 +884,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER error.name ERROR_CAUSE
                                        error.cause.name + Status Code Reason Solution @@ -870,6 +893,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                          @@ -880,6 +904,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER NOT_SYNCED_YET + 200 The node is still syncing and the requested block is not in the database yet
                                            @@ -891,6 +916,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                              @@ -902,6 +928,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                diff --git a/docs/5.api/rpc/block-chunk.md b/docs/5.api/rpc/block-chunk.md index 77abf5e5ad2..217b6d03cd0 100644 --- a/docs/5.api/rpc/block-chunk.md +++ b/docs/5.api/rpc/block-chunk.md @@ -283,6 +283,7 @@ Here is the exhaustive list of the error variants that can be returned by `block error.name ERROR_CAUSE
                                                error.cause.name + Status Code Reason Solution @@ -291,6 +292,7 @@ Here is the exhaustive list of the error variants that can be returned by `block HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                                  @@ -301,6 +303,7 @@ Here is the exhaustive list of the error variants that can be returned by `block NOT_SYNCED_YET + 200 The node is still syncing and the requested block is not in the database yet
                                                    @@ -312,6 +315,7 @@ Here is the exhaustive list of the error variants that can be returned by `block REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                      @@ -323,6 +327,7 @@ Here is the exhaustive list of the error variants that can be returned by `block INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                        @@ -532,6 +537,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER error.name ERROR_CAUSE
                                                        error.cause.name + Status Code Reason Solution @@ -540,6 +546,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                                          @@ -550,6 +557,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER NOT_SYNCED_YET + 200 The node is still syncing and the requested block is not in the database yet
                                                            @@ -561,6 +569,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                              @@ -572,6 +581,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                @@ -737,6 +747,7 @@ Here is the exhaustive list of the error variants that can be returned by `chunk error.name ERROR_CAUSE
                                                                error.cause.name + Status Code Reason Solution @@ -745,6 +756,7 @@ Here is the exhaustive list of the error variants that can be returned by `chunk HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                                                  @@ -755,6 +767,7 @@ Here is the exhaustive list of the error variants that can be returned by `chunk UNKNOWN_CHUNK + 200 The requested chunk can't be found in a database
                                                                    @@ -765,6 +778,7 @@ Here is the exhaustive list of the error variants that can be returned by `chunk INVALID_SHARD_ID + 200 Provided shard_id does not exist
                                                                      @@ -774,6 +788,7 @@ Here is the exhaustive list of the error variants that can be returned by `chunk NOT_SYNCED_YET + 200 The node is still syncing and the requested chunk is not in the database yet
                                                                        @@ -785,6 +800,7 @@ Here is the exhaustive list of the error variants that can be returned by `chunk REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                          @@ -796,6 +812,7 @@ Here is the exhaustive list of the error variants that can be returned by `chunk INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                            diff --git a/docs/5.api/rpc/contracts.md b/docs/5.api/rpc/contracts.md index a240ffb0dd9..689f2c4a30e 100644 --- a/docs/5.api/rpc/contracts.md +++ b/docs/5.api/rpc/contracts.md @@ -123,6 +123,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ error.name ERROR_CAUSE
                                                                            error.cause.name + Status Code Reason Solution @@ -131,6 +132,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                                                              @@ -141,6 +143,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ INVALID_ACCOUNT + 200 The requested account_id is invalid
                                                                                @@ -150,6 +153,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ UNKNOWN_ACCOUNT + 200 The requested account_id has not been found while viewing since the account has not been created or has been already deleted
                                                                                  @@ -160,6 +164,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ UNAVAILABLE_SHARD + 200 The node was unable to find the requested data because it does not track the shard where data is present
                                                                                    @@ -169,6 +174,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ NO_SYNCED_BLOCKS + 200 The node is still syncing and the requested block is not in the database yet
                                                                                      @@ -180,6 +186,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                        @@ -191,6 +198,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                          @@ -344,6 +352,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER error.name ERROR_CAUSE
                                                                                          error.cause.name + Status Code Reason Solution @@ -352,6 +361,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                                                                            @@ -362,6 +372,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER NOT_SYNCED_YET + 200 The node is still syncing and the requested block is not in the database yet
                                                                                              @@ -373,6 +384,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                @@ -384,6 +396,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                  @@ -508,6 +521,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ error.name ERROR_CAUSE
                                                                                                  error.cause.name + Status Code Reason Solution @@ -516,6 +530,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                                                                                    @@ -526,6 +541,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ INVALID_ACCOUNT + 200 The requested account_id is invalid
                                                                                                      @@ -535,6 +551,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ UNKNOWN_ACCOUNT + 200 The requested account_id has not been found while viewing since the account has not been created or has been already deleted
                                                                                                        @@ -545,6 +562,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ NO_CONTRACT_CODE + 200 The account does not have any contract deployed on it
                                                                                                          @@ -555,6 +573,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ UNAVAILABLE_SHARD + 200 The node was unable to find the requested data because it does not track the shard where data is present
                                                                                                            @@ -564,6 +583,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ NO_SYNCED_BLOCKS + 200 The node is still syncing and the requested block is not in the database yet
                                                                                                              @@ -575,6 +595,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                                @@ -586,6 +607,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                  @@ -900,6 +922,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ error.name ERROR_CAUSE
                                                                                                                  error.cause.name + Status Code Reason Solution @@ -908,6 +931,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                                                                                                    @@ -918,6 +942,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ INVALID_ACCOUNT + 200 The requested account_id is invalid
                                                                                                                      @@ -927,6 +952,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ UNKNOWN_ACCOUNT + 200 The requested account_id has not been found while viewing since the account has not been created or has been already deleted
                                                                                                                        @@ -937,6 +963,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ NO_CONTRACT_CODE + 200 The account does not have any contract deployed on it
                                                                                                                          @@ -947,6 +974,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ TOO_LARGE_CONTRACT_STATE + 200 The requested contract state is too large to be returned from this node (the default limit is 50kb of state size)
                                                                                                                            @@ -957,6 +985,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ UNAVAILABLE_SHARD + 200 The node was unable to find the requested data because it does not track the shard where data is present
                                                                                                                              @@ -966,6 +995,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ NO_SYNCED_BLOCKS + 200 The node is still syncing and the requested block is not in the database yet
                                                                                                                                @@ -977,6 +1007,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                                                  @@ -988,6 +1019,7 @@ Here is the exhaustive list of the error variants that can be returned by `view_ INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                    @@ -1139,6 +1171,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER error.name ERROR_CAUSE
                                                                                                                                    error.cause.name + Status Code Reason Solution @@ -1147,6 +1180,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                                                                                                                      @@ -1157,6 +1191,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER NOT_SYNCED_YET + 200 The node is still syncing and the requested block is not in the database yet
                                                                                                                                        @@ -1168,6 +1203,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                                                          @@ -1179,6 +1215,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                            @@ -1313,6 +1350,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER error.name ERROR_CAUSE
                                                                                                                                            error.cause.name + Status Code Reason Solution @@ -1321,6 +1359,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                                                                                                                              @@ -1331,6 +1370,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER NOT_SYNCED_YET + 200 The node is still syncing and the requested block is not in the database yet
                                                                                                                                                @@ -1342,6 +1382,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                                                                  @@ -1353,6 +1394,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                    @@ -1538,6 +1580,7 @@ Here is the exhaustive list of the error variants that can be returned by `call_ error.name ERROR_CAUSE
                                                                                                                                                    error.cause.name + Status Code Reason Solution @@ -1546,6 +1589,7 @@ Here is the exhaustive list of the error variants that can be returned by `call_ HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                                                                                                                                      @@ -1556,6 +1600,7 @@ Here is the exhaustive list of the error variants that can be returned by `call_ INVALID_ACCOUNT + 200 The requested account_id is invalid
                                                                                                                                                        @@ -1565,6 +1610,7 @@ Here is the exhaustive list of the error variants that can be returned by `call_ UNKNOWN_ACCOUNT + 200 The requested account_id has not been found while viewing since the account has not been created or has been already deleted
                                                                                                                                                          @@ -1575,6 +1621,7 @@ Here is the exhaustive list of the error variants that can be returned by `call_ NO_CONTRACT_CODE + 200 The requested contract_code has not been found while viewing
                                                                                                                                                            @@ -1585,6 +1632,7 @@ Here is the exhaustive list of the error variants that can be returned by `call_ CONTRACT_EXECUTION_ERROR + 200 The execution of the view function call failed (crashed, run out of the default 200 TGas limit, etc)
                                                                                                                                                              @@ -1594,6 +1642,7 @@ Here is the exhaustive list of the error variants that can be returned by `call_ UNAVAILABLE_SHARD + 200 The node was unable to find the requested data because it does not track the shard where data is present
                                                                                                                                                                @@ -1603,6 +1652,7 @@ Here is the exhaustive list of the error variants that can be returned by `call_ NO_SYNCED_BLOCKS + 200 The node is still syncing and the requested block is not in the database yet
                                                                                                                                                                  @@ -1614,6 +1664,7 @@ Here is the exhaustive list of the error variants that can be returned by `call_ REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                                                                                    @@ -1625,6 +1676,7 @@ Here is the exhaustive list of the error variants that can be returned by `call_ INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                                      diff --git a/docs/5.api/rpc/gas.md b/docs/5.api/rpc/gas.md index 604e8a2f282..7a887152386 100644 --- a/docs/5.api/rpc/gas.md +++ b/docs/5.api/rpc/gas.md @@ -167,6 +167,7 @@ Here is the exhaustive list of the error variants that can be returned by `gas_p error.name ERROR_CAUSE
                                                                                                                                                                      error.cause.name + Status Code Reason Solution @@ -175,6 +176,7 @@ Here is the exhaustive list of the error variants that can be returned by `gas_p HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                                                                                                                                                        @@ -186,6 +188,7 @@ Here is the exhaustive list of the error variants that can be returned by `gas_p REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                                                                                          @@ -197,6 +200,7 @@ Here is the exhaustive list of the error variants that can be returned by `gas_p INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                                            diff --git a/docs/5.api/rpc/maintenance-windows.md b/docs/5.api/rpc/maintenance-windows.md index ba1af597404..1664151f7a7 100644 --- a/docs/5.api/rpc/maintenance-windows.md +++ b/docs/5.api/rpc/maintenance-windows.md @@ -109,6 +109,7 @@ Here is the exhaustive list of the error variants that can be returned by `maint error.name ERROR_CAUSE
                                                                                                                                                                            error.cause.name + Status Code Reason Solution @@ -117,6 +118,7 @@ Here is the exhaustive list of the error variants that can be returned by `maint INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                                              diff --git a/docs/5.api/rpc/network.md b/docs/5.api/rpc/network.md index c3f4060afb0..48ea415472f 100644 --- a/docs/5.api/rpc/network.md +++ b/docs/5.api/rpc/network.md @@ -282,6 +282,7 @@ Here is the exhaustive list of the error variants that can be returned by `statu error.name ERROR_CAUSE
                                                                                                                                                                              error.cause.name + Status Code Reason Solution @@ -290,6 +291,7 @@ Here is the exhaustive list of the error variants that can be returned by `statu INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                                                @@ -405,6 +407,7 @@ Here is the exhaustive list of the error variants that can be returned by `netwo error.name ERROR_CAUSE
                                                                                                                                                                                error.cause.name + Status Code Reason Solution @@ -413,6 +416,7 @@ Here is the exhaustive list of the error variants that can be returned by `netwo INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                                                  @@ -1356,6 +1360,7 @@ Here is the exhaustive list of the error variants that can be returned by `valid error.name ERROR_CAUSE
                                                                                                                                                                                  error.cause.name + Status Code Reason Solution @@ -1364,6 +1369,7 @@ Here is the exhaustive list of the error variants that can be returned by `valid HANDLER_ERROR UNKNOWN_EPOCH + 200 An epoch for the provided block can't be found in a database
                                                                                                                                                                                    @@ -1376,6 +1382,7 @@ Here is the exhaustive list of the error variants that can be returned by `valid REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                                                                                                      @@ -1387,6 +1394,7 @@ Here is the exhaustive list of the error variants that can be returned by `valid INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                                                        diff --git a/docs/5.api/rpc/protocol.md b/docs/5.api/rpc/protocol.md index e12188276a0..24d883d9377 100644 --- a/docs/5.api/rpc/protocol.md +++ b/docs/5.api/rpc/protocol.md @@ -323,6 +323,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER error.name ERROR_CAUSE
                                                                                                                                                                                        error.cause.name + Status Code Reason Solution @@ -331,6 +332,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                                                          @@ -633,6 +635,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER error.name ERROR_CAUSE
                                                                                                                                                                                          error.cause.name + Status Code Reason Solution @@ -641,6 +644,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER HANDLER_ERROR UNKNOWN_BLOCK + 200 The requested block has not been produced yet or it has been garbage-collected (cleaned up to save space on the RPC node)
                                                                                                                                                                                            @@ -652,6 +656,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                                                              diff --git a/docs/5.api/rpc/transactions.md b/docs/5.api/rpc/transactions.md index 65fe3f16e9b..8bd08b2e0ef 100644 --- a/docs/5.api/rpc/transactions.md +++ b/docs/5.api/rpc/transactions.md @@ -180,6 +180,7 @@ Here is the exhaustive list of the error variants that can be returned by `broad error.name ERROR_CAUSE
                                                                                                                                                                                              error.cause.name + Status Code Reason Solution @@ -188,6 +189,7 @@ Here is the exhaustive list of the error variants that can be returned by `broad HANDLER_ERROR INVALID_TRANSACTION + 200 An error happened during transaction execution
                                                                                                                                                                                                @@ -199,6 +201,7 @@ Here is the exhaustive list of the error variants that can be returned by `broad TIMEOUT_ERROR + 408 Transaction was routed, but has not been recorded on chain in 10 seconds.
                                                                                                                                                                                                  @@ -211,6 +214,7 @@ Here is the exhaustive list of the error variants that can be returned by `broad REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                                                                                                                    @@ -222,6 +226,7 @@ Here is the exhaustive list of the error variants that can be returned by `broad INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                                                                      @@ -416,6 +421,7 @@ Here is the exhaustive list of the error variants that can be returned by `tx` m error.name ERROR_CAUSE
                                                                                                                                                                                                      error.cause.name + Status Code Reason Solution @@ -424,6 +430,7 @@ Here is the exhaustive list of the error variants that can be returned by `tx` m HANDLER_ERROR INVALID_TRANSACTION + 200 An error happened during transaction execution
                                                                                                                                                                                                        @@ -433,6 +440,7 @@ Here is the exhaustive list of the error variants that can be returned by `tx` m UNKNOWN_TRANSACTION + 200 The requested transaction is not available on the node since it might have not been recorded on the chain yet or has been garbage-collected
                                                                                                                                                                                                          @@ -444,6 +452,7 @@ Here is the exhaustive list of the error variants that can be returned by `tx` m TIMEOUT_ERROR + 408 It was unable to wait for the transaction status for reasonable time
                                                                                                                                                                                                            @@ -455,6 +464,7 @@ Here is the exhaustive list of the error variants that can be returned by `tx` m REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                                                                                                                              @@ -466,6 +476,7 @@ Here is the exhaustive list of the error variants that can be returned by `tx` m INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                                                                                @@ -794,6 +805,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER error.name ERROR_CAUSE
                                                                                                                                                                                                                error.cause.name + Status Code Reason Solution @@ -802,6 +814,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER HANDLER_ERROR INVALID_TRANSACTION + 200 An error happened during transaction execution
                                                                                                                                                                                                                  @@ -811,6 +824,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER UNKNOWN_TRANSACTION + 200 The requested transaction is not available on the node since it might have not been recorded on the chain yet or has been garbage-collected
                                                                                                                                                                                                                    @@ -822,6 +836,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER TIMEOUT_ERROR + 408 It was unable to wait for the transaction status for reasonable time
                                                                                                                                                                                                                      @@ -833,6 +848,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                                                                                                                                        @@ -844,6 +860,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                                                                                          @@ -961,6 +978,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER error.name ERROR_CAUSE
                                                                                                                                                                                                                          error.cause.name + Status Code Reason Solution @@ -969,6 +987,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER HANDLER_ERROR UNKNOWN_RECEIPT + 200 The receipt with the given receipt_id was never observed on the node
                                                                                                                                                                                                                            @@ -980,6 +999,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                                                                                                                                              @@ -991,6 +1011,7 @@ Here is the exhaustive list of the error variants that can be returned by `EXPER INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                                                                                                @@ -1126,6 +1147,7 @@ Here is the exhaustive list of the error variants that can be returned by `broad error.name ERROR_CAUSE
                                                                                                                                                                                                                                error.cause.name + Status Code Reason Solution @@ -1134,6 +1156,7 @@ Here is the exhaustive list of the error variants that can be returned by `broad REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                                                                                                                                                  @@ -1303,6 +1326,7 @@ Here is the exhaustive list of the error variants that can be returned by `broad error.name ERROR_CAUSE
                                                                                                                                                                                                                                  error.cause.name + Status Code Reason Solution @@ -1311,6 +1335,7 @@ Here is the exhaustive list of the error variants that can be returned by `broad HANDLER_ERROR INVALID_TRANSACTION + 200 An error happened during transaction execution
                                                                                                                                                                                                                                    @@ -1322,6 +1347,7 @@ Here is the exhaustive list of the error variants that can be returned by `broad TIMEOUT_ERROR + 408 Transaction was routed, but has not been recorded on chain in 10 seconds.
                                                                                                                                                                                                                                      @@ -1334,6 +1360,7 @@ Here is the exhaustive list of the error variants that can be returned by `broad REQUEST_VALIDATION_ERROR PARSE_ERROR + 400 Passed arguments can't be parsed by JSON RPC server (missing arguments, wrong format, etc.)
                                                                                                                                                                                                                                        @@ -1345,6 +1372,7 @@ Here is the exhaustive list of the error variants that can be returned by `broad INTERNAL_ERROR INTERNAL_ERROR + 500 Something went wrong with the node itself or overloaded
                                                                                                                                                                                                                                          From db67c88961bfdfff9539a87977b84f76bddbe898 Mon Sep 17 00:00:00 2001 From: Evgeny Kuzyakov <470453+evgenykuzyakov@users.noreply.github.com> Date: Mon, 5 Aug 2024 09:45:54 -0700 Subject: [PATCH 04/11] Update providers.md (#2197) --- docs/5.api/rpc/providers.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/5.api/rpc/providers.md b/docs/5.api/rpc/providers.md index da371d7af3e..adebcf997fb 100644 --- a/docs/5.api/rpc/providers.md +++ b/docs/5.api/rpc/providers.md @@ -25,7 +25,7 @@ If you want to use a custom RPC provider with NEAR Wallet Selector, [check this | [BlockPi](https://chains.blockpi.io/#/near) | `https://public-rpc.blockpi.io/http/near` | | [dRPC](https://drpc.org/) | `https://near.drpc.org` | | [fast-near web4](https://github.com/vgrichina/fast-near) | `https://rpc.web4.near.page` | -| [FASTNEAR Free](https://twitter.com/fast_near/status/1779578631318368269) | `https://free.rpc.fastnear.com` | +| [FASTNEAR](https://fastnear.com) | `https://free.rpc.fastnear.com` | | [Gateway.fm](https://gateway.fm/) | `https://rpc.near.gateway.fm/` | | [GetBlock](https://getblock.io/nodes/near/) | `https://getblock.io/nodes/near/` | | [Lava Network](https://www.lavanet.xyz/get-started/near) | `https://near.lava.build` | @@ -43,6 +43,7 @@ If you want to use a custom RPC provider with NEAR Wallet Selector, [check this | -------------------------------------------------------------------------- | ------------------------------------------------------------ | | [NEAR](setup.md) | `https://rpc.testnet.near.org` | | [Pagoda](https://www.pagoda.co/console) | `https://rpc.testnet.pagoda.co` | +| [FASTNEAR](https://fastnear.com) | `https://test.rpc.fastnear.com` | ## RPC Failover From 32b5ca6e2aee0a34d76ee091f0112d2f65145d16 Mon Sep 17 00:00:00 2001 From: Kendall Cole Date: Wed, 7 Aug 2024 12:21:25 -0700 Subject: [PATCH 05/11] Update chain signatures content for mainnet (#2198) * Update chain-signatures.md * Update chain-signatures.md --- docs/1.concepts/abstraction/chain-signatures.md | 6 +++--- docs/2.build/1.chain-abstraction/chain-signatures.md | 8 +++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/1.concepts/abstraction/chain-signatures.md b/docs/1.concepts/abstraction/chain-signatures.md index 5a1dc7b3195..1ce25f29975 100644 --- a/docs/1.concepts/abstraction/chain-signatures.md +++ b/docs/1.concepts/abstraction/chain-signatures.md @@ -13,7 +13,7 @@ This unlocks the next level of blockchain interoperability by giving ownership o _Diagram of a chain signature in NEAR_ :::caution -This technology is currently in `alpha` and should only be used in a `testnet` environment. +This technology is currently in `beta` and should be used carefully and with audits on `mainnet`. ::: --- @@ -72,10 +72,10 @@ The essence of Multi-Party Computation (MPC) is to enable independent parties to NEAR's MPC service is comprised of several independent nodes, **none of which can sign by itself**, but instead create **signature-shares** that are **aggregated through multiple rounds** to **jointly** sign a transaction. -This service continuously listens for signature requests (i.e. users calling the `sign` method on the `multichain` smart contract) and when a call is detected the MPC service: +This service continuously listens for signature requests (i.e. users calling the `sign` method on the `v1.signer` smart contract) and when a call is detected the MPC service: 1. Asks its nodes to jointly derive a signature for the `payload` using the account identified by the `path` - 2. Once complete, call the `multichain` contract to store the resulting `Signature` + 2. Once complete, call the `v1.signer` contract to store the resulting `Signature` :::info A Custom MPC Service Generally, MPC signing services work by sharing a master key, which needs to be re-created each time a node joins or leaves. diff --git a/docs/2.build/1.chain-abstraction/chain-signatures.md b/docs/2.build/1.chain-abstraction/chain-signatures.md index 73d68b8f4f0..cbe40980c77 100644 --- a/docs/2.build/1.chain-abstraction/chain-signatures.md +++ b/docs/2.build/1.chain-abstraction/chain-signatures.md @@ -31,7 +31,7 @@ There are five steps to create a Chain Signature: 1. [Deriving the Foreign Address](#1-deriving-the-foreign-address) - Construct the address that will be controlled on the target blockchain 2. [Creating a Transaction](#2-creating-the-transaction) - Create the transaction or message to be signed -3. [Requesting a Signature](#3-requesting-the-signature) - Call the NEAR `multichain` contract requesting it to sign the transaction +3. [Requesting a Signature](#3-requesting-the-signature) - Call the NEAR `v1.signer` contract requesting it to sign the transaction 4. [Reconstructing the Signature](#4-reconstructing-the-signature) - Reconstruct the signature from the MPC service's response 5. [Relaying the Signed Transaction](#5-relaying-the-signature) - Send the signed transaction to the destination chain for execution @@ -48,6 +48,12 @@ If you want to try things out, these are the smart contracts available on `testn ::: +:::info MPC mainnet contracts + +- `v1.signer`: [MPC signer](https://github.com/near/mpc/tree/v0.2.0/contract) contract, latest release, made up of 8 MPC nodes + +::: + --- ## 1. Deriving the Foreign Address From 2053ee26f1437870c20afc9ffd63bea01954109d Mon Sep 17 00:00:00 2001 From: Guille Date: Thu, 8 Aug 2024 15:09:25 +0200 Subject: [PATCH 06/11] Landing pages for Chain Abstraction Services (#2200) * added landing pages for ca services * added canhazgas mainnet * added image --- .../chain-signatures-getting-started.md | 75 +++++++++++++++++++ .../1.chain-abstraction/chain-signatures.md | 5 +- .../multichain-gas-relayer/gas-station.md | 2 +- .../multichain-gas-relayer/getting-started.md | 60 +++++++++++++++ .../multichain-server.md | 2 +- .../relayer-gas-example.md | 14 ++-- website/sidebars.js | 18 ++++- 7 files changed, 161 insertions(+), 15 deletions(-) create mode 100644 docs/2.build/1.chain-abstraction/chain-signatures-getting-started.md create mode 100644 docs/2.build/1.chain-abstraction/multichain-gas-relayer/getting-started.md diff --git a/docs/2.build/1.chain-abstraction/chain-signatures-getting-started.md b/docs/2.build/1.chain-abstraction/chain-signatures-getting-started.md new file mode 100644 index 00000000000..bc76f04ba3b --- /dev/null +++ b/docs/2.build/1.chain-abstraction/chain-signatures-getting-started.md @@ -0,0 +1,75 @@ +--- +id: chain-signatures-getting-started +title: Getting Started with Chain Signatures +hide_table_of_contents: true +--- + +Chain Signatures is a groundbreaking technology built on NEAR that enables NEAR accounts, including smart contracts, to sign and execute transactions across multiple blockchains. This innovation leverages Multi-Party Computation (MPC) and a distributed network of node operators to create joint signatures from arbitrary payloads, allowing NEAR users to control external blockchain accounts. + +![img](https://pages.near.org/wp-content/uploads/2024/02/acct-abstraction-blog-1.png) + +This technology enhances blockchain interoperability, giving ownership of diverse assets, cross-chain accounts, and data to a single NEAR account. + +--- + +## How Does It Work? + +Chain Signatures operates through a series of steps to enable seamless cross-chain transactions: + +1. **Deriving Foreign Addresses:** + * Chain Signatures uses derivation paths to represent accounts on foreign blockchains. + * The NEAR account’s name and the derivation path are used to mathematically [derive a unique address](https://docs.near.org/concepts/abstraction/chain-signatures\#derivation-paths-one-account-multiple-chains) for the user on the foreign blockchain. +2. **Creating the Transaction:** + * The client constructs the hash of the transaction to be signed, which varies by the target blockchain. +3. **Requesting the Signature:** + * A NEAR account or smart contract calls the sign method of the MPC smart contract ([v1.signer](https://nearblocks.io/address/v1.signer)) to sign a payload. +4. **Relaying the Signature:** + * The client reconstructs the valid transaction using the signature and broadcasts it to the destination blockchain. + +This process eliminates the need for traditional bridges and enables developers to build innovative cross-chain DeFi applications with seamless user experiences. + +--- + +## Use Cases + +1. **DeFi on Bitcoin (and other chain without smart contracts)** + * Chain signatures allow NEAR smart contract to program assets on Bitcoin + * Build lending, swaps, runes launchpads, passkey-based Bitcoin wallets, and more +2. **Chain agnostic applications** + * Since chain signatures can sign transactions for all blockchains, developers can support every single chain with just one smart contract + * Multichain DEXs, lending protocols, oracles, derivatives, and more +3. **Multichain account abstraction** + * Users can control assets on all chains with just their NEAR account, and can utilize account abstraction features on any chain including passkeys, key rotation, etc + * Using the multichain gas relayer, users can pay for gas fees on any chain using USDC +4. **Privacy** + * Chain signatures can be used to encrypt and decrypt information in a programmatic way + * This enables privacy applications, and even decrypting information based on ownership of assets/NFTs + +--- + +## How to Get Started? + +1. **Familiarize Yourself with Chain Signatures:** + * Understand the [basics of Chain Signatures](https://docs.near.org/concepts/abstraction/chain-signatures) and how they simplify blockchain interactions. + * Review the technical [explainer](https://near.org/blog/unlocking-web3-usability-with-account-aggregation). +2. **Explore the Use Cases:** + * Review [examples of use cases for Chain Signatures](https://pages.near.org/blog/unlocking-multichain-web3-with-near-chain-signatures/), such as Multichain DAO, Multichain NFT Minter, and Bitcoin Runes Airdrop. +3. **Access Resources and Documentation:** + * Visit the [Chain Signatures documentation](https://docs.near.org/build/chain-abstraction/chain-signatures) for detailed technical information and code snippets. + * Check out the [Linktree for Chain Signatures](https://linktr.ee/chainsignatures) for various resources, including demos and tutorials. +4. **Try the Demos:** + * Use the [command-line-based demo](https://github.com/near-examples/chainsig-script) to derive accounts and send transactions on Bitcoin, Ethereum, Doge, and Ripple. + * Check out the [web app demo](https://github.com/near-examples/near-multichain/tree/main). +5. **Engage with the Community:** + * Join the [Chain Abstraction developers’ channel on Telegram](https://t.me/chain\_abstraction) to connect with other developers and get support. + +--- + +## Where to Learn More? + +To dive deeper into Chain Signatures and its applications, you can explore the following resources: + +* **Technical Blogs and Deep Dives:** + * Read [high-level use cases](https://pages.near.org/blog/unlocking-multichain-web3-with-near-chain-signatures) and technical [explainer](https://near.org/blog/unlocking-web3-usability-with-account-aggregation) posts on the NEAR blog. +* **Community and Support:** + * Engage with the NEAR community on social media platforms like Twitter and participate in discussions to stay updated on the latest developments. \ No newline at end of file diff --git a/docs/2.build/1.chain-abstraction/chain-signatures.md b/docs/2.build/1.chain-abstraction/chain-signatures.md index cbe40980c77..6755a7f3f84 100644 --- a/docs/2.build/1.chain-abstraction/chain-signatures.md +++ b/docs/2.build/1.chain-abstraction/chain-signatures.md @@ -38,20 +38,19 @@ There are five steps to create a Chain Signature: ![chain-signatures](/docs/assets/welcome-pages/chain-signatures-overview.png) _Diagram of a chain signature in NEAR_ -:::info MPC testnet contracts +:::info MPC Contracts If you want to try things out, these are the smart contracts available on `testnet`: - `v1.signer-prod.testnet`: [MPC signer](https://github.com/near/mpc/tree/v0.2.0/contract) contract, latest release, made up of 8 MPC nodes - `canhazgas.testnet`: [Multichain Gas Station](multichain-gas-relayer/gas-station.md) contract -- `nft.kagi.testnet`: [NFT Chain Key](nft-keys.md) contract ::: :::info MPC mainnet contracts - `v1.signer`: [MPC signer](https://github.com/near/mpc/tree/v0.2.0/contract) contract, latest release, made up of 8 MPC nodes - +- `canhazgas.near`: [Multichain Gas Station](multichain-gas-relayer/gas-station.md) contract ::: --- diff --git a/docs/2.build/1.chain-abstraction/multichain-gas-relayer/gas-station.md b/docs/2.build/1.chain-abstraction/multichain-gas-relayer/gas-station.md index b8d1d1255d5..841cb6133fc 100644 --- a/docs/2.build/1.chain-abstraction/multichain-gas-relayer/gas-station.md +++ b/docs/2.build/1.chain-abstraction/multichain-gas-relayer/gas-station.md @@ -119,7 +119,7 @@ Users who wish to get transactions signed and relayed by this contract and its a If you want to try things out, this smart contract is available on: - testnet: `canhazgas.testnet` -- mainnet: `TBD` +- mainnet: `canhazgas.near` ::: diff --git a/docs/2.build/1.chain-abstraction/multichain-gas-relayer/getting-started.md b/docs/2.build/1.chain-abstraction/multichain-gas-relayer/getting-started.md new file mode 100644 index 00000000000..459baa1f1bd --- /dev/null +++ b/docs/2.build/1.chain-abstraction/multichain-gas-relayer/getting-started.md @@ -0,0 +1,60 @@ +--- +id: getting-started +title: "Multichain Gas Relayer: Getting Started Guide" +hide_table_of_contents: true +--- + +The Multichain Gas Relayer provides gas abstraction for foreign chains outside of NEAR. This system, in conjunction with NEAR Chain Signatures, allows NEAR users to transact on other blockchains and pay for gas using NEAR, USDC, USDT, or other NEAR-based tokens from a single NEAR account. + +![img](https://pages.near.org/wp-content/uploads/2024/02/acct-abstraction-blog-1.png) + +Chain Signatures lets users manage remote accounts and transact on any blockchain from a single NEAR account. The Multichain Gas Relayer further simplifies this process by eliminating the need for users to acquire native gas tokens to transact on other chains. + + +--- + +## Why did NEAR create the Multichain Gas Relayer? + +NEAR's mission is to build blockchain infrastructure for Chain Abstracted applications. Chain abstraction aims to make blockchain technology more user-friendly by simplifying interactions. A key step in achieving this is reducing the complexity of paying for transaction gas across different blockchains. Users should be able to pay for cross-chain transactions with a single asset or have the gas fees fully sponsored on their behalf. + +--- + +## How does it work? + +The Multichain Gas Relayer has 3 core components: + +1. **Gas Station Smart Contract**: A smart contract on NEAR that manages the creation, signing, of transactions to foreign chains. It also handles gas fee calculations and collects NEAR tokens for gas payments on foreign chains. +2. **Multichain Relayer Server**: This server coordinates the relaying of transactions between NEAR and other blockchains. It listens for signed transaction payloads and submits them to the appropriate foreign chain RPCs. +3. **Chain Signatures**: A network of distributed Multi-Party Computation (MPC) signers that cooperatively sign transactions. This ensures secure transaction signing and validation on the NEAR blockchain before relaying to foreign chains. + +### System Workflow + +1. **Transaction Creation**: Users initiate a transaction on NEAR, specifying the foreign chain transaction and attaching NEAR tokens to cover gas fees on the foreign chain. This transaction is sent to the Gas Station Contract. +2. **Transaction Signing**: The Gas Station Contract invokes Chain Signatures MPC signing service to sign the transaction. This step may require multiple calls due to gas limitations on NEAR, especially for complex transactions. +3. **Event Emission and Indexing**: Once the transactions are signed, the Gas Station Contract emits an event. The Gas Station Event Indexer picks up this event and triggers the Multichain Relayer Server to relay the signed transactions. +4. **Relaying Transactions**: The Multichain Relayer Server first sends a funding transaction to ensure the user’s account on the foreign chain has sufficient gas. Once confirmed, it sends the user’s originally intended signed transaction to the foreign chain for execution. + +--- + +## Example Real-World Flow + +* Alice has an alice.near account that maps to a remote Optimism (OP) address, 0xabc +* Alice wants to interact with a Farcaster application on OP using her NEAR account, but she prefers to pay for gas with assets she has on hand, specifically USDT +* Alice initiates an on-chain action on Farcaster from her NEAR account. She sends the transaction to a gas station smart contract, including the OP transaction payload in the arguments and attaching the necessary USDT amount for the cross-chain gas payment +* The transaction bundle is sent to the NEAR gas station contract, which then forwards it to the NEAR MPC signing service. This bundle includes (1) the transaction to fund the user's 0xabc address with the ETH needed for gas, and (2) the user's original transaction to take action on the Farcaster application +* The MPC service will sign both transactions and forward the signed transactions back to the gas station contract +* The relayer operator will observe the events (signed transactions) emitted from the gas station contract and submit them to the Optimism network. This process starts by initiating a fund transfer from a treasury paymaster account on Optimism that holds ETH. The paymaster account will transfer ETH to the user's 0xabc address, equivalent to the USDT originally sent by the user +* Then the relayer will submit the final transaction, and the originally intended Farcaster transaction will be executed from the user's 0xabc address, using ETH to cover the gas + +--- + +## What chains are supported? + +The NEAR Multichain Gas Relayer supports cross-chain gas abstraction on Base, Optimism, Arbitrum and Binance Smart Chain, and Ethereum. These chains were selected based on multiple factors including interest from key partners, low gas fees, and fast finality for transactions. Support for EDDSA chains like Solana will be coming soon in conjunction with EDDSA support for NEAR chain signatures. + +--- + +## Where can I go to learn more? + +* Visit our [docs](https://docs.near.org/build/chain-abstraction/multichain-gas-relayer/overview) to learn more about how to integrate the Multichain Gas Relayer into your product +* Join the NEAR Chain Abstraction [developer group](https://t.me/chain\_abstraction) on Telegram to ask questions and discuss ideas with other developers. \ No newline at end of file diff --git a/docs/2.build/1.chain-abstraction/multichain-gas-relayer/multichain-server.md b/docs/2.build/1.chain-abstraction/multichain-gas-relayer/multichain-server.md index e0c018b7529..9b9f826593d 100644 --- a/docs/2.build/1.chain-abstraction/multichain-gas-relayer/multichain-server.md +++ b/docs/2.build/1.chain-abstraction/multichain-gas-relayer/multichain-server.md @@ -47,7 +47,7 @@ For independent deployments of gas station contracts, generally, nonce synchroni 1. The wallet sends a NEAR transaction to the gas station contract that contains 2 actions: 1. A transfer of `NEAR` (or FT Transfer in the future) to cover gas on the foreign chain 2. A `create_transaction` function call to the gas station contract `canhazgas.testnet` containing the unsigned foreign chain transaction to be signed by the MPC signing service, assuming the unsigned transaction passes validation. - > (note: `mainnet` contract address TBD) + > (note: `mainnet` contract address is `canhazgas.near`) 2. The Gas Station Contract calls the MPC signing service to sign both a funding transaction, which ensures the user's foreign chain account has sufficient gas to execute the desired transaction, and signs the unsigned foreign chain transaction. 3. Upon receipt of both the signed transactions, the Gas Station Contract emits an event which is picked up by the indexer, which then calls the `/send_funding_and_user_signed_txns` with the 2 signed transactions from the indexer. 4. The multichain relayer server sends the funding transaction to the foreign chain RPC to fund the user's account with gas. diff --git a/docs/2.build/1.chain-abstraction/multichain-gas-relayer/relayer-gas-example.md b/docs/2.build/1.chain-abstraction/multichain-gas-relayer/relayer-gas-example.md index abfd78660ce..5441db3499f 100644 --- a/docs/2.build/1.chain-abstraction/multichain-gas-relayer/relayer-gas-example.md +++ b/docs/2.build/1.chain-abstraction/multichain-gas-relayer/relayer-gas-example.md @@ -70,7 +70,7 @@ To run the [Gas Station indexer](https://github.com/near/gas-station-event-index make install ``` -3. Update the [`config.toml`](https://github.com/near/gas-station-event-indexer/blob/main/config.toml) configuration file with appropriate values +3. Update the [`config.toml`](https://github.com/near/gas-station-event-indexer/blob/main/config.toml) configuration file with appropriate values (use `canhazgas.near` for mainnet) ``` network = "testnet" # gas station contract account id @@ -135,7 +135,7 @@ The following instructions are only need to be called once to initialize the acc mint json-args {} prepaid-gas '100.0 Tgas' attached-deposit '0 NEAR' \ sign-as .testnet network-config testnet sign-with-keychain send ``` -3. Approve the Gas Station for this Token +3. Approve the Gas Station for this Token (use or use `canhazgas.near` for mainnet): ```shell near contract call-function as-transaction v2.nft.kagi.testnet \ ckt_approve_call json-args '{"token_id":"","account_id":"canhazgas.testnet","msg":""}' \ @@ -145,7 +145,7 @@ The following instructions are only need to be called once to initialize the acc ### Manual test steps -1. Get paymaster info for the chain you want to send to from the gas station contract, then optionally manually set nonces: +1. Get paymaster info for the chain you want to send to from the gas station contract, then optionally manually set nonces (use `canhazgas.near` for mainnet): ```shell near contract call-function as-transaction canhazgas.testnet \ get_paymasters json-args '{"chain_id": ""}' \ @@ -165,7 +165,7 @@ The following instructions are only need to be called once to initialize the acc ] ------------------------------------ ``` - 1. You may need to manually set the nonce for the paymaster to be able to send the transaction: + 1. You may need to manually set the nonce for the paymaster to be able to send the transaction (use `canhazgas.near` for mainnet): ```shell near contract call-function as-transaction canhazgas.testnet \ get_paymasters json-args '{"chain_id": ""}' \ @@ -215,7 +215,7 @@ Python and Rust output different hex RLP encoded transactions. 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 send. - For example: + For example (use `canhazgas.near` for mainnet): ```shell near contract call-function as-transaction canhazgas.testnet \ create_transaction json-args '{"transaction_rlp_hex":"eb80851bf08eb000825208947b965bdb7f0464843572eb2b8c17bdf27b720b14872386f26fc1000080808080","use_paymaster":true,"token_id":""}' \ @@ -232,7 +232,7 @@ Python and Rust output different hex RLP encoded transactions. } ------------------------------------ ``` -6. Get the `"id"` from the receipts from the result in the previous step, and use that to call `sign_next` twice: +6. Get the `"id"` from the receipts from the result in the previous step, and use that to call `sign_next` twice (use `canhazgas.near` for mainnet): ```shell near contract call-function as-transaction canhazgas.testnet \ sign_next json-args '{"id":""}' \ @@ -253,7 +253,7 @@ Python and Rust output different hex RLP encoded transactions. ### Optional 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: +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 (use `canhazgas.near` for mainnet): ```sh near contract call-function as-read-only canhazgas.testnet list_signed_transaction_sequences_after json-args '{"block_height":"157111000"}' network-config testnet now diff --git a/website/sidebars.js b/website/sidebars.js index d03fcef679a..7b467d2126d 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -88,7 +88,13 @@ const sidebar = { ] }, { - "Chain Signatures": [ + "type": "category", + "label": "Chain Signatures", + "link": { + "type": "doc", + "id": "build/chain-abstraction/chain-signatures-getting-started" + }, + "items": [ "concepts/abstraction/chain-signatures", 'build/chain-abstraction/chain-signatures', 'build/chain-abstraction/nft-chain-keys', @@ -96,7 +102,13 @@ const sidebar = { }, // 'build/chain-abstraction/wallet', { - "Multichain Gas Relayer": [ + "type": "category", + "label": "Multichain Gas Relayer", + "link": { + "type": "doc", + "id": "build/chain-abstraction/multichain-gas-relayer/getting-started" + }, + "items": [ "build/chain-abstraction/multichain-gas-relayer/overview", "build/chain-abstraction/multichain-gas-relayer/gas-station", "build/chain-abstraction/multichain-gas-relayer/multichain-server", @@ -281,7 +293,7 @@ const sidebar = { }, { "Lake Framework": [ - "concepts/advanced/near-lake-framework", + "concepts/advanced/near-lake-framework", "build/data-infrastructure/lake-framework/near-lake", "build/data-infrastructure/lake-framework/near-lake-state-changes-indexer", "build/data-infrastructure/lake-framework/migrating-to-near-lake-framework", From 9e20a15a08f893d05e4c805e7ccaccb8f2d5d22d Mon Sep 17 00:00:00 2001 From: Guille Date: Thu, 8 Aug 2024 15:26:12 +0200 Subject: [PATCH 07/11] Ca landing pages (#2201) * added landing pages for ca services * added canhazgas mainnet * added image * cs-folder --- .../{ => chain-signatures}/chain-signatures.md | 6 +++--- .../getting-started.md} | 2 +- website/sidebars.js | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) rename docs/2.build/1.chain-abstraction/{ => chain-signatures}/chain-signatures.md (94%) rename docs/2.build/1.chain-abstraction/{chain-signatures-getting-started.md => chain-signatures/getting-started.md} (99%) diff --git a/docs/2.build/1.chain-abstraction/chain-signatures.md b/docs/2.build/1.chain-abstraction/chain-signatures/chain-signatures.md similarity index 94% rename from docs/2.build/1.chain-abstraction/chain-signatures.md rename to docs/2.build/1.chain-abstraction/chain-signatures/chain-signatures.md index 6755a7f3f84..b4bfdd16a7c 100644 --- a/docs/2.build/1.chain-abstraction/chain-signatures.md +++ b/docs/2.build/1.chain-abstraction/chain-signatures/chain-signatures.md @@ -43,21 +43,21 @@ _Diagram of a chain signature in NEAR_ If you want to try things out, these are the smart contracts available on `testnet`: - `v1.signer-prod.testnet`: [MPC signer](https://github.com/near/mpc/tree/v0.2.0/contract) contract, latest release, made up of 8 MPC nodes -- `canhazgas.testnet`: [Multichain Gas Station](multichain-gas-relayer/gas-station.md) contract +- `canhazgas.testnet`: [Multichain Gas Station](../multichain-gas-relayer/gas-station.md) contract ::: :::info MPC mainnet contracts - `v1.signer`: [MPC signer](https://github.com/near/mpc/tree/v0.2.0/contract) contract, latest release, made up of 8 MPC nodes -- `canhazgas.near`: [Multichain Gas Station](multichain-gas-relayer/gas-station.md) contract +- `canhazgas.near`: [Multichain Gas Station](../multichain-gas-relayer/gas-station.md) contract ::: --- ## 1. Deriving the Foreign Address -Chain Signatures use [`derivation paths`](../../1.concepts/abstraction/chain-signatures.md#one-account-multiple-chains) to represent accounts on the target blockchain. The external address to be controlled can be deterministically derived from: +Chain Signatures use [`derivation paths`](../../../1.concepts/abstraction/chain-signatures.md#one-account-multiple-chains) to represent accounts on the target blockchain. The external address to be controlled can be deterministically derived from: - The NEAR address (e.g., `example.near`, `example.testnet`, etc.) - A derivation path (a string such as `ethereum-1`, `ethereum-2`, etc.) diff --git a/docs/2.build/1.chain-abstraction/chain-signatures-getting-started.md b/docs/2.build/1.chain-abstraction/chain-signatures/getting-started.md similarity index 99% rename from docs/2.build/1.chain-abstraction/chain-signatures-getting-started.md rename to docs/2.build/1.chain-abstraction/chain-signatures/getting-started.md index bc76f04ba3b..b94bdfdf7b2 100644 --- a/docs/2.build/1.chain-abstraction/chain-signatures-getting-started.md +++ b/docs/2.build/1.chain-abstraction/chain-signatures/getting-started.md @@ -1,5 +1,5 @@ --- -id: chain-signatures-getting-started +id: getting-started title: Getting Started with Chain Signatures hide_table_of_contents: true --- diff --git a/website/sidebars.js b/website/sidebars.js index 7b467d2126d..8f0522a6c3a 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -92,12 +92,12 @@ const sidebar = { "label": "Chain Signatures", "link": { "type": "doc", - "id": "build/chain-abstraction/chain-signatures-getting-started" + "id": "build/chain-abstraction/chain-signatures/getting-started" }, "items": [ "concepts/abstraction/chain-signatures", - 'build/chain-abstraction/chain-signatures', - 'build/chain-abstraction/nft-chain-keys', + 'build/chain-abstraction/chain-signatures/chain-signatures', + // 'build/chain-abstraction/nft-chain-keys', ] }, // 'build/chain-abstraction/wallet', From 7e3caf98b0bd8047aa6ea2ce874fe3aa7a88a257 Mon Sep 17 00:00:00 2001 From: Guille Date: Thu, 8 Aug 2024 18:05:35 +0200 Subject: [PATCH 08/11] Beautify Landing Pages (#2202) * added landing pages for ca services * added canhazgas mainnet * added image * cs-folder * beautify docs * fix: link --- .../chain-signatures/chain-signatures.md | 20 +++--- .../chain-signatures/getting-started.md | 62 ++++++++++++------ .../multichain-gas-relayer/getting-started.md | 51 ++++++++------ .../multichain-gas-relayer/overview.md | 2 +- .../welcome-pages/multi-chain-gas-diagram.png | Bin 0 -> 169870 bytes 5 files changed, 85 insertions(+), 50 deletions(-) create mode 100644 website/static/docs/assets/welcome-pages/multi-chain-gas-diagram.png diff --git a/docs/2.build/1.chain-abstraction/chain-signatures/chain-signatures.md b/docs/2.build/1.chain-abstraction/chain-signatures/chain-signatures.md index b4bfdd16a7c..78a78b5088b 100644 --- a/docs/2.build/1.chain-abstraction/chain-signatures/chain-signatures.md +++ b/docs/2.build/1.chain-abstraction/chain-signatures/chain-signatures.md @@ -61,8 +61,7 @@ Chain Signatures use [`derivation paths`](../../../1.concepts/abstraction/chain- - The NEAR address (e.g., `example.near`, `example.testnet`, etc.) - A derivation path (a string such as `ethereum-1`, `ethereum-2`, etc.) -- The MPC service's public key - - `secp256k1:4NfTiv3UsGahebgTaHyD9vF8KYKMBnfd6kh94mK6xv8fGBiJB8TBtFMP5WWXz6B89Ac1fbpzPwAvoyQebemHFwx3` +- The MPC service's public key (see the tip bellow for the MPC service public keys) We provide code to derive the address, as it's a complex process that involves multiple steps of hashing and encoding: @@ -81,21 +80,22 @@ We provide code to derive the address, as it's a complex process that involves m -:::info +:::tip -The same NEAR account and path will always produce the same address on the target blockchain. +We recommend hardcoding the derivation paths in your application to ensure the signature request is made to the correct account -- `example.near` + `ethereum-1` = `0x1b48b83a308ea4beb845db088180dc3389f8aa3b` -- `example.near` + `ethereum-2` = `0x99c5d3025dc736541f2d97c3ef3c90de4d221315` +- **v1.signer-prod.testnet** (testnet): `secp256k1:4NfTiv3UsGahebgTaHyD9vF8KYKMBnfd6kh94mK6xv8fGBiJB8TBtFMP5WWXz6B89Ac1fbpzPwAvoyQebemHFwx3` + +- **v1.signer** (mainnet): `secp256k1:3tFRbMqmoa6AAALMrEFAYCEoHcqKxeW38YptwowBVBtXK1vo36HDbUWuR6EZmoK4JcH6HDkNMGGqP1ouV7VZUWya` ::: -:::tip +:::info -We recommend hardcoding the derivation paths in your application to ensure the signature request is made to the correct account +The same NEAR account and path will always produce the same address on the target blockchain. -#### v1.signer-prod.testnet -`secp256k1:4NfTiv3UsGahebgTaHyD9vF8KYKMBnfd6kh94mK6xv8fGBiJB8TBtFMP5WWXz6B89Ac1fbpzPwAvoyQebemHFwx3` +- `example.near` + `ethereum-1` = `0x1b48b83a308ea4beb845db088180dc3389f8aa3b` +- `example.near` + `ethereum-2` = `0x99c5d3025dc736541f2d97c3ef3c90de4d221315` ::: diff --git a/docs/2.build/1.chain-abstraction/chain-signatures/getting-started.md b/docs/2.build/1.chain-abstraction/chain-signatures/getting-started.md index b94bdfdf7b2..ace96e3b6e1 100644 --- a/docs/2.build/1.chain-abstraction/chain-signatures/getting-started.md +++ b/docs/2.build/1.chain-abstraction/chain-signatures/getting-started.md @@ -1,37 +1,63 @@ --- id: getting-started title: Getting Started with Chain Signatures -hide_table_of_contents: true --- -Chain Signatures is a groundbreaking technology built on NEAR that enables NEAR accounts, including smart contracts, to sign and execute transactions across multiple blockchains. This innovation leverages Multi-Party Computation (MPC) and a distributed network of node operators to create joint signatures from arbitrary payloads, allowing NEAR users to control external blockchain accounts. +Chain Signatures is a groundbreaking technology built on NEAR that enables all accounts, including smart contracts, to sign and execute transactions across multiple blockchains. ![img](https://pages.near.org/wp-content/uploads/2024/02/acct-abstraction-blog-1.png) -This technology enhances blockchain interoperability, giving ownership of diverse assets, cross-chain accounts, and data to a single NEAR account. +This innovation leverages Multi-Party Computation (MPC) and a distributed network of node operators to create joint signatures from arbitrary payloads, allowing NEAR users to control external blockchain accounts. + +Chain Signatures enhances blockchain interoperability, giving ownership of diverse assets, cross-chain accounts, and data to a single NEAR account. --- -## How Does It Work? +## How does it work? + +When a NEAR account - could be a user or a **smart contract** - wants to interact with a foreign blockchain, it just need to follow four simple steps. + +#### 1. Deriving Foreign Addresses + +Chain Signatures uses [derivation paths](../../../1.concepts/abstraction/chain-signatures.md#derivation-paths-one-account-multiple-chains) to represent accounts on foreign blockchains + +The NEAR account’s name and the derivation path are used to mathematically derive a unique address for the user on the foreign blockchain + +
                                                                                                                                                                                                                                          + + Derivation Paths + +A NEAR account will always derive the same address on the foreign blockchain using the same derivation path + +Notice that, since the foreign address is derived from the NEAR account name, it is not possible for another NEAR account to control the same address -Chain Signatures operates through a series of steps to enable seamless cross-chain transactions: +
                                                                                                                                                                                                                                          -1. **Deriving Foreign Addresses:** - * Chain Signatures uses derivation paths to represent accounts on foreign blockchains. - * The NEAR account’s name and the derivation path are used to mathematically [derive a unique address](https://docs.near.org/concepts/abstraction/chain-signatures\#derivation-paths-one-account-multiple-chains) for the user on the foreign blockchain. -2. **Creating the Transaction:** - * The client constructs the hash of the transaction to be signed, which varies by the target blockchain. -3. **Requesting the Signature:** - * A NEAR account or smart contract calls the sign method of the MPC smart contract ([v1.signer](https://nearblocks.io/address/v1.signer)) to sign a payload. -4. **Relaying the Signature:** - * The client reconstructs the valid transaction using the signature and broadcasts it to the destination blockchain. -This process eliminates the need for traditional bridges and enables developers to build innovative cross-chain DeFi applications with seamless user experiences. +#### 2. Creating the Transaction + +The client constructs the foreign transaction to be signed, which varies depending on the target blockchain + +#### 3. Requesting the Signature + +A NEAR account or contract calls the sign method of the MPC smart contract ([v1.signer](https://nearblocks.io/address/v1.signer)) to sign the transaction and waits while our MPC service generates the signature + +#### 4. Relaying the Signature + +Once the signature is ready, the client reconstructs the signed transaction using the signature and broadcasts it to the destination blockchain + +:::tip + +Using Chain Signatures, developers can build cross-chain DeFi applications with seamless user experiences, eliminating the need for traditional bridges. This process eliminates the need for traditional bridges and enables developers to build innovative cross-chain DeFi applications with seamless user experiences. + +::: --- ## Use Cases +Chain Signatures can be used to build a wide range of applications that leverage blockchain interoperability. Here are some examples: + 1. **DeFi on Bitcoin (and other chain without smart contracts)** * Chain signatures allow NEAR smart contract to program assets on Bitcoin * Build lending, swaps, runes launchpads, passkey-based Bitcoin wallets, and more @@ -69,7 +95,5 @@ This process eliminates the need for traditional bridges and enables developers To dive deeper into Chain Signatures and its applications, you can explore the following resources: -* **Technical Blogs and Deep Dives:** - * Read [high-level use cases](https://pages.near.org/blog/unlocking-multichain-web3-with-near-chain-signatures) and technical [explainer](https://near.org/blog/unlocking-web3-usability-with-account-aggregation) posts on the NEAR blog. -* **Community and Support:** - * Engage with the NEAR community on social media platforms like Twitter and participate in discussions to stay updated on the latest developments. \ No newline at end of file +- **Technical Blogs and Deep Dives:** Read [high-level use cases](https://pages.near.org/blog/unlocking-multichain-web3-with-near-chain-signatures) and technical [explainer](https://near.org/blog/unlocking-web3-usability-with-account-aggregation) posts on the NEAR blog +* **Community and Support:** Engage with the NEAR community on social media platforms like Twitter and participate in discussions to stay updated on the latest developments diff --git a/docs/2.build/1.chain-abstraction/multichain-gas-relayer/getting-started.md b/docs/2.build/1.chain-abstraction/multichain-gas-relayer/getting-started.md index 459baa1f1bd..fb7feca4e55 100644 --- a/docs/2.build/1.chain-abstraction/multichain-gas-relayer/getting-started.md +++ b/docs/2.build/1.chain-abstraction/multichain-gas-relayer/getting-started.md @@ -1,60 +1,71 @@ --- id: getting-started title: "Multichain Gas Relayer: Getting Started Guide" -hide_table_of_contents: true --- -The Multichain Gas Relayer provides gas abstraction for foreign chains outside of NEAR. This system, in conjunction with NEAR Chain Signatures, allows NEAR users to transact on other blockchains and pay for gas using NEAR, USDC, USDT, or other NEAR-based tokens from a single NEAR account. +[Chain Signatures](../chain-signatures/getting-started.md) lets users manage remote accounts and transact on any blockchain from a single NEAR account. The Multichain Gas Relayer further simplifies this process by eliminating the need for users to acquire the tokens needed in the foreign chain to execute their transactions. ![img](https://pages.near.org/wp-content/uploads/2024/02/acct-abstraction-blog-1.png) -Chain Signatures lets users manage remote accounts and transact on any blockchain from a single NEAR account. The Multichain Gas Relayer further simplifies this process by eliminating the need for users to acquire native gas tokens to transact on other chains. +In other words, the Multichain Gas Relayer provides gas abstraction for foreign chains, allowing NEAR accounts to pay for the gas needed in the target chain using our native token (NEAR) and fungible tokens (e.g. USDC and USDT). --- -## Why did NEAR create the Multichain Gas Relayer? +## Why a Multichain Gas Relayer? -NEAR's mission is to build blockchain infrastructure for Chain Abstracted applications. Chain abstraction aims to make blockchain technology more user-friendly by simplifying interactions. A key step in achieving this is reducing the complexity of paying for transaction gas across different blockchains. Users should be able to pay for cross-chain transactions with a single asset or have the gas fees fully sponsored on their behalf. +NEAR's mission is to build blockchain infrastructure for Chain Abstracted applications. Chain abstraction aims to make blockchain technology more user-friendly by simplifying interactions. + +A key step in achieving this is reducing the complexity of paying for transaction gas across different blockchains. Users should be able to pay for cross-chain transactions with a single asset or have the gas fees fully sponsored on their behalf. --- -## How does it work? +## How Does it Work? The Multichain Gas Relayer has 3 core components: -1. **Gas Station Smart Contract**: A smart contract on NEAR that manages the creation, signing, of transactions to foreign chains. It also handles gas fee calculations and collects NEAR tokens for gas payments on foreign chains. -2. **Multichain Relayer Server**: This server coordinates the relaying of transactions between NEAR and other blockchains. It listens for signed transaction payloads and submits them to the appropriate foreign chain RPCs. -3. **Chain Signatures**: A network of distributed Multi-Party Computation (MPC) signers that cooperatively sign transactions. This ensures secure transaction signing and validation on the NEAR blockchain before relaying to foreign chains. +1. **Gas Station Smart Contract**: A smart contract on NEAR that manages the creation, signing, of transactions to foreign chains. It also handles gas fee calculations and collects NEAR tokens for gas payments on foreign chains + +2. **Multichain Relayer Server**: This server coordinates the relaying of transactions between NEAR and other blockchains. It listens for signed transaction payloads and submits them to the appropriate foreign chain RPCs + +3. **Chain Signatures**: A network of distributed Multi-Party Computation (MPC) signers that cooperatively sign transactions. This ensures secure transaction signing and validation on the NEAR blockchain before relaying to foreign chains + +#### System Workflow -### System Workflow +![chain-signatures](/docs/assets/welcome-pages/multi-chain-gas-diagram.png) +_Diagram of a chain signature in NEAR with gas being covered by the Relayer_ -1. **Transaction Creation**: Users initiate a transaction on NEAR, specifying the foreign chain transaction and attaching NEAR tokens to cover gas fees on the foreign chain. This transaction is sent to the Gas Station Contract. -2. **Transaction Signing**: The Gas Station Contract invokes Chain Signatures MPC signing service to sign the transaction. This step may require multiple calls due to gas limitations on NEAR, especially for complex transactions. -3. **Event Emission and Indexing**: Once the transactions are signed, the Gas Station Contract emits an event. The Gas Station Event Indexer picks up this event and triggers the Multichain Relayer Server to relay the signed transactions. -4. **Relaying Transactions**: The Multichain Relayer Server first sends a funding transaction to ensure the user’s account on the foreign chain has sufficient gas. Once confirmed, it sends the user’s originally intended signed transaction to the foreign chain for execution. +1. **Transaction Creation**: An account sends a transaction to the Gas Station Contract, specifying the foreign chain transaction and attaching NEAR tokens to cover gas fees on the foreign chain. + +2. **Transaction Signing**: The Gas Station Contract invokes Chain Signatures MPC signing service to sign the transaction. This step may require multiple calls due to gas limitations on NEAR, especially for complex transactions + +3. **Event Emission and Indexing**: Once the transactions are signed, the Gas Station Contract emits an event. The Gas Station Event Indexer picks up this event and triggers the Multichain Relayer Server to relay the signed transactions + +4. **Relaying Transactions**: The Multichain Relayer Server first sends a funding transaction to ensure the user’s account on the foreign chain has sufficient gas. Once confirmed, it sends the user’s originally intended signed transaction to the foreign chain for execution --- ## Example Real-World Flow -* Alice has an alice.near account that maps to a remote Optimism (OP) address, 0xabc +* Alice has an `alice.near` account that maps to a remote Optimism (OP) address, `0xabc` * Alice wants to interact with a Farcaster application on OP using her NEAR account, but she prefers to pay for gas with assets she has on hand, specifically USDT * Alice initiates an on-chain action on Farcaster from her NEAR account. She sends the transaction to a gas station smart contract, including the OP transaction payload in the arguments and attaching the necessary USDT amount for the cross-chain gas payment -* The transaction bundle is sent to the NEAR gas station contract, which then forwards it to the NEAR MPC signing service. This bundle includes (1) the transaction to fund the user's 0xabc address with the ETH needed for gas, and (2) the user's original transaction to take action on the Farcaster application +* The transaction bundle is sent to the NEAR gas station contract, which then forwards it to the NEAR MPC signing service. This bundle includes (1) the transaction to fund the user's `0xabc` address with the ETH needed for gas, and (2) the user's original transaction to take action on the Farcaster application * The MPC service will sign both transactions and forward the signed transactions back to the gas station contract -* The relayer operator will observe the events (signed transactions) emitted from the gas station contract and submit them to the Optimism network. This process starts by initiating a fund transfer from a treasury paymaster account on Optimism that holds ETH. The paymaster account will transfer ETH to the user's 0xabc address, equivalent to the USDT originally sent by the user -* Then the relayer will submit the final transaction, and the originally intended Farcaster transaction will be executed from the user's 0xabc address, using ETH to cover the gas +* The relayer operator will observe the events (signed transactions) emitted from the gas station contract and submit them to the Optimism network. This process starts by initiating a fund transfer from a treasury paymaster account on Optimism that holds ETH. The paymaster account will transfer ETH to the user's `0xabc` address, equivalent to the USDT originally sent by the user +* Then the relayer will submit the final transaction, and the originally intended Farcaster transaction will be executed from the user's `0xabc` address, using ETH to cover the gas --- ## What chains are supported? -The NEAR Multichain Gas Relayer supports cross-chain gas abstraction on Base, Optimism, Arbitrum and Binance Smart Chain, and Ethereum. These chains were selected based on multiple factors including interest from key partners, low gas fees, and fast finality for transactions. Support for EDDSA chains like Solana will be coming soon in conjunction with EDDSA support for NEAR chain signatures. +Currently, the Multichain Gas Relayer supports [Base](https://www.base.org/), [Optimism](https://www.optimism.io/), [Arbitrum](https://arbitrum.io/) and [Binance Smart Chain](https://www.bnbchain.org/en/bnb-smart-chain), and [Ethereum](https://ethereum.org/en/). + +These chains were selected based on multiple factors including interest from key partners, low gas fees, and fast finality for transactions. Support for EDDSA chains like [Solana](https://solana.com/) will be coming soon in conjunction with EDDSA support for NEAR chain signatures. --- ## Where can I go to learn more? -* Visit our [docs](https://docs.near.org/build/chain-abstraction/multichain-gas-relayer/overview) to learn more about how to integrate the Multichain Gas Relayer into your product +* Visit our [docs](./overview.md) to learn more about how to integrate the Multichain Gas Relayer into your product * Join the NEAR Chain Abstraction [developer group](https://t.me/chain\_abstraction) on Telegram to ask questions and discuss ideas with other developers. \ No newline at end of file diff --git a/docs/2.build/1.chain-abstraction/multichain-gas-relayer/overview.md b/docs/2.build/1.chain-abstraction/multichain-gas-relayer/overview.md index 199324ba8a6..e5187dfbec7 100644 --- a/docs/2.build/1.chain-abstraction/multichain-gas-relayer/overview.md +++ b/docs/2.build/1.chain-abstraction/multichain-gas-relayer/overview.md @@ -28,7 +28,7 @@ This section provides an overview of the system design, including the main compo 2. [**Gas Station Contract**](gas-station.md): A smart contract on NEAR that manages the creation, signing, and relaying of transactions to foreign chains. It also handles gas fee calculations and collects NEAR tokens for gas payments on foreign chains. -3. [**MPC Signing Service**](../chain-signatures.md): A network of trusted Multi-Party Computation (MPC) signers that cooperatively sign transactions. This ensures secure transaction signing and validation on the NEAR blockchain before relaying to foreign chains. +3. [**MPC Signing Service**](../chain-signatures/chain-signatures.md): A network of trusted Multi-Party Computation (MPC) signers that cooperatively sign transactions. This ensures secure transaction signing and validation on the NEAR blockchain before relaying to foreign chains. ### Technical Diagram diff --git a/website/static/docs/assets/welcome-pages/multi-chain-gas-diagram.png b/website/static/docs/assets/welcome-pages/multi-chain-gas-diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..0be6e21339ec2e65ac6078f48f226612210dad2a GIT binary patch literal 169870 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 T6DBJH{w&O_e!jWa^X&ft7t(9U literal 0 HcmV?d00001 From 923b60aad25e3137e38c5913d8536fc1ac0bed7b Mon Sep 17 00:00:00 2001 From: Guille Date: Thu, 8 Aug 2024 20:01:06 +0200 Subject: [PATCH 09/11] removed beta message (#2203) --- docs/1.concepts/abstraction/chain-signatures.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/1.concepts/abstraction/chain-signatures.md b/docs/1.concepts/abstraction/chain-signatures.md index 1ce25f29975..d56d5b21bca 100644 --- a/docs/1.concepts/abstraction/chain-signatures.md +++ b/docs/1.concepts/abstraction/chain-signatures.md @@ -12,10 +12,6 @@ This unlocks the next level of blockchain interoperability by giving ownership o ![chain-signatures](/docs/assets/welcome-pages/chain-signatures-overview.png) _Diagram of a chain signature in NEAR_ -:::caution -This technology is currently in `beta` and should be used carefully and with audits on `mainnet`. -::: - --- ## How It Works From 2a91c1b9d82048cc372c06f5e3a6f4491751baec Mon Sep 17 00:00:00 2001 From: Jan Malinowski <149345204+jancionear@users.noreply.github.com> Date: Fri, 9 Aug 2024 22:23:24 +0200 Subject: [PATCH 10/11] document the new `ReceiptValidationError::ReceiptSizeExceeded` (#2194) * document the new `ReceiptValidationError::ReceiptSizeExceeded` * Extend the comment about ReceiptSizeExceeded --- docs/6.integrations/errors/error-implementation.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/6.integrations/errors/error-implementation.md b/docs/6.integrations/errors/error-implementation.md index 7e511c6abe4..803bd37c68f 100644 --- a/docs/6.integrations/errors/error-implementation.md +++ b/docs/6.integrations/errors/error-implementation.md @@ -441,6 +441,13 @@ pub enum ReceiptValidationError { NumberInputDataDependenciesExceeded { number_of_input_data_dependencies: u64, limit: u64 }, /// An error occurred while validating actions of an ActionReceipt. ActionsValidation(ActionsValidationError), + /// Receipt is bigger than the limit. + /// ReceiptSizeExceeded means that there was a receipt above the size limit (currently 4MiB). + /// NEAR will refuse to execute receipts that are above the size limit. + /// The most likely source of such receipts would be cross-contract calls with a lot of large actions + /// (contract deployment, function call with large args, etc). + /// This error means that the user has to adjust their contract to generate smaller receipts. + ReceiptSizeExceeded { size: u64, limit: u64 }, } ``` @@ -466,6 +473,9 @@ ReceiptValidationError::NumberInputDataDependenciesExceeded { number_of_input_da "The number of input data dependencies {} exceeded the limit {} in an ActionReceipt" ReceiptValidationError::ActionsValidation(e) + +ReceiptValidationError::ReceiptSizeExceeded { size, limit } +"The size of the receipt exceeded the limit: {} > {}", ``` From f0a9fb89a0b5e57a4ae92f6f0c03c5e5aec15698 Mon Sep 17 00:00:00 2001 From: Reza Rahemtola Date: Mon, 12 Aug 2024 15:22:14 +0200 Subject: [PATCH 11/11] fix: Some typos (#2206) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: Some typos * Update docs/2.build/1.chain-abstraction/wallet.md --------- Co-authored-by: DamiΓ‘n Parrino --- docs/1.concepts/3.advanced/indexers.md | 2 +- docs/1.concepts/web3/blockchain.md | 2 +- docs/1.concepts/web3/near.md | 2 +- docs/1.concepts/web3/nfts.md | 4 ++-- docs/2.build/1.chain-abstraction/fastauth-sdk.md | 4 ++-- docs/2.build/1.chain-abstraction/meta-transactions.md | 2 +- docs/2.build/1.chain-abstraction/wallet.md | 4 ++-- .../2.smart-contracts/testing/kurtosis-localnet.md | 4 ++-- docs/2.build/5.primitives/ft.md | 2 +- .../lake-data-structures/state_change.mdx | 3 +-- .../lake-data-structures/transaction.mdx | 2 +- .../lake-framework/migrating-to-near-lake-framework.md | 2 +- .../lake-framework/running-near-lake/credentials.md | 2 +- docs/4.tools/cli-rs.md | 4 ++-- docs/4.tools/near-api-js/quick-reference.md | 2 +- docs/pagoda/alerts/setup.md | 2 +- docs/pagoda/alerts/webhooks.md | 8 ++++---- docs/pagoda/rpc/intro.md | 2 +- docs/pagoda/rpc/setup.md | 2 +- docs/pagoda/rpc/stats.md | 2 +- 20 files changed, 28 insertions(+), 29 deletions(-) diff --git a/docs/1.concepts/3.advanced/indexers.md b/docs/1.concepts/3.advanced/indexers.md index e634f60dcb4..350d0b1196e 100644 --- a/docs/1.concepts/3.advanced/indexers.md +++ b/docs/1.concepts/3.advanced/indexers.md @@ -88,4 +88,4 @@ We hope this article gives you an understanding of the Indexer concept. Also, we ## What's next? We encourage you to learn more about the [Lake Indexer project](/build/data-infrastructure/lake-framework/near-lake). Please, proceed to [Tutorials](/build/data-infrastructure/lake-framework/near-lake-state-changes-indexer) section to learn how to build an indexer on practice. -Alternatively, there are a few other third-party indexers that are tightly integrated with the NEAR ecosystem. You can review all of your data sourcing options (including The Graph, Pagoda, Pipespeak, and SubQuery) under [data tools](/concepts/data-flow/data-storage#data-tools). +Alternatively, there are a few other third-party indexers that are tightly integrated with the NEAR ecosystem. You can review all of your data sourcing options (including The Graph, Pagoda, Pikespeak, and SubQuery) under [data tools](/concepts/data-flow/data-storage#data-tools). diff --git a/docs/1.concepts/web3/blockchain.md b/docs/1.concepts/web3/blockchain.md index 65fb7839f3d..aedd5c37411 100644 --- a/docs/1.concepts/web3/blockchain.md +++ b/docs/1.concepts/web3/blockchain.md @@ -153,7 +153,7 @@ There are a lot of blockchains out there and it might be hard to choose the most Historically, the first blockchain to introduce smart contracts was Ethereum. However, as the number of users grew, transaction speed and cost skyrocketed, and it became apparent that it couldn't handle the demand. So, a number of [scaling solutions](https://ethereum.org/en/developers/docs/scaling/) appeared - [layer 2 chains](https://ethereum.org/en/developers/docs/scaling/#layer-2-scaling), [sidechains](https://ethereum.org/en/developers/docs/scaling/sidechains/), and [plasma chains](https://ethereum.org/en/developers/docs/scaling/plasma/). However, they all use some kind of workarounds with their own unique drawbacks. Ethereum tries to fix the core problem and redesign its network - like switching to a Proof-of-stake consensus, which is ongoing for quite a long time, but exact timeline when all of the problems will be fixed is very unclear. -Meanwhile, a new generation of blockchains started to appear. They learned from the Etherium mistakes, and designed them from ground-up to be fast, cheap and scalable. +Meanwhile, a new generation of blockchains started to appear. They learned from the Ethereum mistakes, and designed them from ground-up to be fast, cheap and scalable. Choosing the right one is by no means an easy task, but for us we found the [NEAR](https://near.org/) blockchain to be an ideal solution, because of the following properties: - Transactions are cheap and very fast. - Designed to be extremely scalable from the beginning. This means we can count that transaction cost and speed will remain stable in the future. diff --git a/docs/1.concepts/web3/near.md b/docs/1.concepts/web3/near.md index 8fd15f32247..31974c7c2f4 100644 --- a/docs/1.concepts/web3/near.md +++ b/docs/1.concepts/web3/near.md @@ -148,7 +148,7 @@ As an alternative to building your own indexer with a database and an API server By now, we should be familiar with necessary concepts to start developing WEB 3.0 applications, so let’s explore the development tools available. -First of all, we need a development and testing environment. Of course, we could theoraticaly perform development and testing on the main blockchain network, but this would not be cheap. For this reason, NEAR provides [several networks](../../1.concepts/basics/networks.md) that can be used during development: +First of all, we need a development and testing environment. Of course, we could theoretically perform development and testing on the main blockchain network, but this would not be cheap. For this reason, NEAR provides [several networks](../../1.concepts/basics/networks.md) that can be used during development: - testnet - public NEAR network which is identical to mainnet and can be used for free. - localnet - you can deploy your personal NEAR network on your own environment. Because it’s owned by you, data and code can be kept private during development. More info on how you can run your own node can be [found here](https://near-nodes.io/validator/running-a-node). Alternatively, you can bootstrap an entire testing infrastructure in Docker on your local machine using Kurtosis - [guide is here](../../2.build/2.smart-contracts/testing/kurtosis-localnet.md). - workspaces - you can start your own local network to perform e2e testing. More info [here](../../2.build/2.smart-contracts/testing/integration-test.md). diff --git a/docs/1.concepts/web3/nfts.md b/docs/1.concepts/web3/nfts.md index 37b3b3b20d3..984a802ac7b 100644 --- a/docs/1.concepts/web3/nfts.md +++ b/docs/1.concepts/web3/nfts.md @@ -325,7 +325,7 @@ In the blockchain world, creation of new NFTs is usually called minting. And as -* Users can mint them directly. This can be done by either allowing creation of NFTs from scratch, or by using more complex processes, like breeding or upgrading. The most famous example of such process is breeding in [CrytoKitties](https://www.cryptokitties.co/) game - new NFTs are created by combining existing ones. With this approach users usually have to pay to cover the storage and gas cost of NFTs creation. +* Users can mint them directly. This can be done by either allowing creation of NFTs from scratch, or by using more complex processes, like breeding or upgrading. The most famous example of such process is breeding in [CryptoKitties](https://www.cryptokitties.co/) game - new NFTs are created by combining existing ones. With this approach users usually have to pay to cover the storage and gas cost of NFTs creation. * NFTs can be distributed by the developer to a set of users - it is usually called [NFTs airdrop](https://www.investopedia.com/terms/a/airdrop-cryptocurrency.asp). Most often this is used as a marketing strategy to kickstart NFTs usage in applications. Storage and gas costs in this case are covered by developers. * NFTs can be bought on a market or obtained from the lootbox. Depending on an exact strategy, costs can either be paid by a user or by developer. Also, in this case NFTs sometimes can be minted on-demand, to avoid paying upfront costs. @@ -516,7 +516,7 @@ Implementing an own Marketplace contract is more involved since there is no stan * [Basic marketplace example](../../3.tutorials/nfts/8-marketplace.md) * [Paras ](https://paras.id/)marketplace contract - [source](https://github.com/ParasHQ/paras-marketplace-contract/tree/master/paras-marketplace-contract/src). -As for third-party solutions, the most complete one is [Mintibase](https://www.mintbase.io/), which provides a full suite of components for NFTs integration - including contracts, indexer, API and a web client: +As for third-party solutions, the most complete one is [Mintbase](https://www.mintbase.io/), which provides a full suite of components for NFTs integration - including contracts, indexer, API and a web client: diff --git a/docs/2.build/1.chain-abstraction/fastauth-sdk.md b/docs/2.build/1.chain-abstraction/fastauth-sdk.md index b01a8e8a7dc..dfa58e4e6ed 100644 --- a/docs/2.build/1.chain-abstraction/fastauth-sdk.md +++ b/docs/2.build/1.chain-abstraction/fastauth-sdk.md @@ -75,7 +75,7 @@ service cloud.firestore { - Press the gear button next to "Project Overview", and go to "Project settings" - Under "Your apps", click on the `` button - Set the app nickname as `issuer-gcp` and hit "Register app" -- You should see the code needed for initilization and authentication of Firestore, such as: +- You should see the code needed for initialization and authentication of Firestore, such as: ```js // Import the functions you need from the SDKs you need import { initializeApp } from "firebase/app"; @@ -253,7 +253,7 @@ const onCLick = () => selector.then((selector: any) => selector.wallet('fast-aut }),); ``` -Wehenever the user tries to login, call `onClick`. +Whenever the user tries to login, call `onClick`. ### Getting added to the MPC recovery service diff --git a/docs/2.build/1.chain-abstraction/meta-transactions.md b/docs/2.build/1.chain-abstraction/meta-transactions.md index 7167cca077a..5816879abc2 100644 --- a/docs/2.build/1.chain-abstraction/meta-transactions.md +++ b/docs/2.build/1.chain-abstraction/meta-transactions.md @@ -86,7 +86,7 @@ In this method we are creating an arbitrary smart contract call, instantiating a As mentioned in the above note in order to be able to relay on the client side it's necessary to have access to signing transactions directly on the client. Luckily leveraging the near biometric library it's possible to do so in a non custodial way. -By calling this method and passing in the URL for the account creation endpoint (mentioned in the server section) as well as the `accoundId` everything is handled under the hood to successfully create an account. +By calling this method and passing in the URL for the account creation endpoint (mentioned in the server section) as well as the `accountId` everything is handled under the hood to successfully create an account. diff --git a/docs/2.build/1.chain-abstraction/wallet.md b/docs/2.build/1.chain-abstraction/wallet.md index 9843cec2f06..e85b42351bc 100644 --- a/docs/2.build/1.chain-abstraction/wallet.md +++ b/docs/2.build/1.chain-abstraction/wallet.md @@ -10,7 +10,7 @@ You'll also learn how to ensure that a signature on one chain is not used to tak ### Key derivation -When signing using [chain signatures](./chain-signatures.md) each account has an unlimited number of keys. Each key's public key is derived from the account name and the key extension which is an arbitrary string. +When signing using [chain signatures](./chain-signatures/chain-signatures.md) each account has an unlimited number of keys. Each key's public key is derived from the account name and the key extension which is an arbitrary string. User's keys can be described as follow: @@ -94,7 +94,7 @@ In the following examples, the messages are coming from the user's wallet fronte - [Using a personal Bitcoin key](#using-a-personal-bitcoin-key) - [Using a personal EVM key to sign a Binance transaction](#using-a-personal-evm-key-to-sign-a-binance-transaction) - [Using an untyped domain key](#using-an-untyped-domain-key) -- [Using another domains Bitcoin key](#using-another-domains-bitcoin-key) +- [Using another domain's Bitcoin key](#using-another-domains-bitcoin-key) :::tip Wallet developers should follow this user flow format. diff --git a/docs/2.build/2.smart-contracts/testing/kurtosis-localnet.md b/docs/2.build/2.smart-contracts/testing/kurtosis-localnet.md index 1c5c72d6fc3..a958378a90b 100644 --- a/docs/2.build/2.smart-contracts/testing/kurtosis-localnet.md +++ b/docs/2.build/2.smart-contracts/testing/kurtosis-localnet.md @@ -622,9 +622,9 @@ Once you've logged in, you can sign a message with an optional donation. --- -## Managing NEAR Pacakages +## Managing NEAR Packages -The Kurtosis NEAR Pacakages you create will continue to run on your local machine for as long as your Docker engine is running. This package runs inside of a Kurtosis "enclave" which is an environment isolated from both your computer and other enclaves. In practice, this means that you can have multiple independent local NEAR clusters running on your machine simply by rerunning the script we executed from the [setup instructions](#setup). +The Kurtosis NEAR Packages you create will continue to run on your local machine for as long as your Docker engine is running. This package runs inside of a Kurtosis "enclave" which is an environment isolated from both your computer and other enclaves. In practice, this means that you can have multiple independent local NEAR clusters running on your machine simply by rerunning the script we executed from the [setup instructions](#setup). ### View Package Status diff --git a/docs/2.build/5.primitives/ft.md b/docs/2.build/5.primitives/ft.md index 3ce1811eda0..cd9eb8d1a78 100644 --- a/docs/2.build/5.primitives/ft.md +++ b/docs/2.build/5.primitives/ft.md @@ -33,7 +33,7 @@ import CLICreateToken from "./ft/near-cli/create.md" import SmartContractSendToken from "./ft/smart-contract/send.md" import SmartContractAttachTokenToCall from "./ft/smart-contract/attach-to-call.md" -Besides the native NEAR token, NEAR accounts have access to a [multitude of tokens](https://guide.ref.finance/developers-1/cli-trading#query-whitelisted-tokens) to use thoughtout the ecosystem. Moreover, it is even possible for users to create their own fungible tokens. +Besides the native NEAR token, NEAR accounts have access to a [multitude of tokens](https://guide.ref.finance/developers-1/cli-trading#query-whitelisted-tokens) to use throughout the ecosystem. Moreover, it is even possible for users to create their own fungible tokens. In contrast with the NEAR native token, fungible token (FT) are **not stored** in the user's account. In fact, each FT lives in **their own contract** which is in charge of doing **bookkeeping**. This is, the contract keeps track of how many tokens each user has, and handles transfers internally. diff --git a/docs/2.build/6.data-infrastructure/lake-data-structures/state_change.mdx b/docs/2.build/6.data-infrastructure/lake-data-structures/state_change.mdx index 1af0fdcb5d9..4554f436e5c 100644 --- a/docs/2.build/6.data-infrastructure/lake-data-structures/state_change.mdx +++ b/docs/2.build/6.data-infrastructure/lake-data-structures/state_change.mdx @@ -11,7 +11,7 @@ import TabItem from '@theme/TabItem'; ## Definition -This entitiy from `nearcore` describes how account's state has changed and the reason +This entity from `nearcore` describes how account's state has changed and the reason ## `StateChangeWithCauseView` @@ -101,4 +101,3 @@ export type StateChange = { - diff --git a/docs/2.build/6.data-infrastructure/lake-data-structures/transaction.mdx b/docs/2.build/6.data-infrastructure/lake-data-structures/transaction.mdx index 093fec57137..34f941f9679 100644 --- a/docs/2.build/6.data-infrastructure/lake-data-structures/transaction.mdx +++ b/docs/2.build/6.data-infrastructure/lake-data-structures/transaction.mdx @@ -10,7 +10,7 @@ import TabItem from '@theme/TabItem'; ## Definition -Transaction is the main way of interraction between a user and a blockchain. Transaction contains: +Transaction is the main way of interaction between a user and a blockchain. Transaction contains: - Signer account ID - Receiver account ID - Actions diff --git a/docs/2.build/6.data-infrastructure/lake-framework/migrating-to-near-lake-framework.md b/docs/2.build/6.data-infrastructure/lake-framework/migrating-to-near-lake-framework.md index 44e00dda479..a954186dd4d 100644 --- a/docs/2.build/6.data-infrastructure/lake-framework/migrating-to-near-lake-framework.md +++ b/docs/2.build/6.data-infrastructure/lake-framework/migrating-to-near-lake-framework.md @@ -499,7 +499,7 @@ We are posting the complete diffs for the reference - /// Specify a custom download URL for the genesis file. - #[clap(long)] - pub download_genesis_url: Option, -- /// Download the verified NEAR config file automtically. +- /// Download the verified NEAR config file automatically. - #[clap(long)] - pub download_config: bool, - /// Specify a custom download URL for the config file. diff --git a/docs/2.build/6.data-infrastructure/lake-framework/running-near-lake/credentials.md b/docs/2.build/6.data-infrastructure/lake-framework/running-near-lake/credentials.md index 9c9e6ce033e..666bcca61d8 100644 --- a/docs/2.build/6.data-infrastructure/lake-framework/running-near-lake/credentials.md +++ b/docs/2.build/6.data-infrastructure/lake-framework/running-near-lake/credentials.md @@ -30,7 +30,7 @@ aws_secret_access_key= [AWS docs: Configuration and credential file settings](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) -#### Environment varibales +#### Environment variables Alternatively, you can provide your AWS credentials via environment variables with constant names: diff --git a/docs/4.tools/cli-rs.md b/docs/4.tools/cli-rs.md index baa8f452d33..4b5cfd7c842 100644 --- a/docs/4.tools/cli-rs.md +++ b/docs/4.tools/cli-rs.md @@ -66,7 +66,7 @@ You'll get redirected to `wallet.testnet.near.org`. Once there, grant authorizat If you're on Mac you'll have the option to use the [Mac Keychain](https://support.apple.com/guide/keychain-access/what-is-keychain-access-kyca1083/mac) option. -Either storage option is fine. Using the legacy storage option will save a file in your root directory in a hidden folder called `./near-credentials`. This storage option is compatable with the `near-cli` tool (a cli tool without the guided prompts but similar functionality). +Either storage option is fine. Using the legacy storage option will save a file in your root directory in a hidden folder called `./near-credentials`. This storage option is compatible with the `near-cli` tool (a cli tool without the guided prompts but similar functionality). **Good Job!** Now you can use `near-cli-rs` to it's full capacity. @@ -129,7 +129,7 @@ Operate Transactions | Option | Description | | ---------------------- | --------------------------- | | `view-status` | View a transaction status | -| `construct-tansaction` | Construct a new transaction | +| `construct-transaction` | Construct a new transaction | ### Config diff --git a/docs/4.tools/near-api-js/quick-reference.md b/docs/4.tools/near-api-js/quick-reference.md index 333df1e91f8..d8de49d4789 100644 --- a/docs/4.tools/near-api-js/quick-reference.md +++ b/docs/4.tools/near-api-js/quick-reference.md @@ -245,7 +245,7 @@ const provider = new FailoverRpcProvider(jsonProviders); await connect({ networkId: 'mainnet', provider: provider, - // this isn't used if `provider` is specified, but is still required for backward compativility + // this isn't used if `provider` is specified, but is still required for backward compatibility nodeUrl: 'https://rpc.mainnet.near.org', }); ``` diff --git a/docs/pagoda/alerts/setup.md b/docs/pagoda/alerts/setup.md index 4219694557c..83ed926be7d 100644 --- a/docs/pagoda/alerts/setup.md +++ b/docs/pagoda/alerts/setup.md @@ -42,7 +42,7 @@ Follow the steps above to begin setting-up telegram alerts. When selecting the d ### Private Message Alerts -1. On the device that is logged into the telegram aclick "Open Telegram" or scan the QR code. +1. On the device that is logged into the telegram click "Open Telegram" or scan the QR code. diff --git a/docs/pagoda/alerts/webhooks.md b/docs/pagoda/alerts/webhooks.md index 7a7d9f47425..61c82ebc2dc 100644 --- a/docs/pagoda/alerts/webhooks.md +++ b/docs/pagoda/alerts/webhooks.md @@ -140,7 +140,7 @@ copy that entire line and head on over to console.pagoda.co ## Step 5: Integrating Webhook into Pagoda Console -Once at console.pagoda.co, you should be greeted by the log-in page. Select the Non-funcable Token (NFT) project to start exploring the NFT contract +Once at console.pagoda.co, you should be greeted by the log-in page. Select the Non-fungible Token (NFT) project to start exploring the NFT contract @@ -181,12 +181,12 @@ But for now, we'll keep it easy and select any Successful Action. We're almost done! Under destination select webhooks. Now that webhook we created earlier go ahead and copy and paste it into here. Then hit "Create" :::tip -Don't forget to remove the `{}` around the name of your event! `ifttt.com/trigger/...`, not `ifftt.com/{trigger}/...` +Don't forget to remove the `{}` around the name of your event! `ifttt.com/trigger/...`, not `ifttt.com/{trigger}/...` ::: -Remember to hit the "+ Create Alert" button on this page... +Remember to hit the "+ Create Alert" button on this page... @@ -210,6 +210,6 @@ Select the `new_default_metadata` function (we are choosing this one because we And that's it! You've just triggered something in the real world with an event that happened on the NEAR Blockchain. Hopefully this inspires you to create your own webhook using IFTTT and the Pagoda Console. -We'd love to see what you create! Tag [@PagodaPlatform](https://twitter.com/PagodaPlatform) on Twitter with a novel implementation of a webhhook and trigger and we might retweet it. +We'd love to see what you create! Tag [@PagodaPlatform](https://twitter.com/PagodaPlatform) on Twitter with a novel implementation of a webhook and trigger and we might retweet it. Happy hacking! diff --git a/docs/pagoda/rpc/intro.md b/docs/pagoda/rpc/intro.md index 1e252efddab..6fc91453125 100644 --- a/docs/pagoda/rpc/intro.md +++ b/docs/pagoda/rpc/intro.md @@ -19,7 +19,7 @@ The Pagoda RPC provides you with instant access to maintenance free, scalable NE Developers can interact with on-chain data and send different types of transactions to the network by utilizing the RPC endpoints. -In addition to the powerful node infrastructure, we also created the Pagoda RPC Stats page so that you can have visibility into your RPC usage and performances and take control of your project from the infrastructure level. What’s more? You can subscribe to the alerts from our Status page so that you can follow the health of Pagoda RPC real time. All accesible via [Pagoda Console](https://console.pagoda.co/). +In addition to the powerful node infrastructure, we also created the Pagoda RPC Stats page so that you can have visibility into your RPC usage and performances and take control of your project from the infrastructure level. What’s more? You can subscribe to the alerts from our Status page so that you can follow the health of Pagoda RPC real time. All accessible via [Pagoda Console](https://console.pagoda.co/). ## Setup diff --git a/docs/pagoda/rpc/setup.md b/docs/pagoda/rpc/setup.md index 493500a7b61..486a5577247 100644 --- a/docs/pagoda/rpc/setup.md +++ b/docs/pagoda/rpc/setup.md @@ -37,7 +37,7 @@ With a dedicated API key, developers are able to: - Access higher request throughput and increased concurrent requests - Query data from [Enhanced APIs](api.md), gaining access to free processed data for NFT, FT and NEAR balances, ownership, and metadata -- Utlize dedicated, individualized usage metrics +- Utilize dedicated, individualized usage metrics ### Test your API keys diff --git a/docs/pagoda/rpc/stats.md b/docs/pagoda/rpc/stats.md index 1f80b174c3a..e780bd9693a 100644 --- a/docs/pagoda/rpc/stats.md +++ b/docs/pagoda/rpc/stats.md @@ -28,7 +28,7 @@ Aggregated key metrics available at the top of the dashboard are ## Set a Time Period -Data is sent with UTC time to the browser and the browser adjusts to the user’s timezon. +Data is sent with UTC time to the browser and the browser adjusts to the user’s timezone. - Last 15 Minutes is the last complete 15 minutes. This updates every few seconds. - Last 1 Hour is the last fully completed hour; from 00 to 59 minutes and 59 seconds.