# Account Changes Source: https://docs.near.org/api-reference/account-changes /openapi.json post /EXPERIMENTAL_changes [Deprecated] Returns changes for a given account, contract or contract code for given block height or hash. Consider using changes instead. # Active Validators Source: https://docs.near.org/api-reference/active-validators /openapi.json post /validators Queries active validators on the network. Returns details and the state of validation on the blockchain. # Block Changes Source: https://docs.near.org/api-reference/block-changes /openapi.json post /EXPERIMENTAL_changes_in_block [Deprecated] Returns changes in block for given block height or hash over all transactions for all the types. Includes changes like account_touched, access_key_touched, data_touched, contract_code_touched. Consider using block_effects instead # Block Details Source: https://docs.near.org/api-reference/block-details /openapi.json post /block Returns block details for given height or hash # Block Effects Source: https://docs.near.org/api-reference/block-effects /openapi.json post /block_effects Returns changes in block for given block height or hash over all transactions for all the types. Includes changes like account_touched, access_key_touched, data_touched, contract_code_touched. # Broadcast Transaction Source: https://docs.near.org/api-reference/broadcast-transaction /openapi.json post /broadcast_tx_commit [Deprecated] Sends a transaction and waits until transaction is fully complete. (Has a 10 second timeout). Consider using send_tx instead. # Broadcast Transaction Async Source: https://docs.near.org/api-reference/broadcast-transaction-async /openapi.json post /broadcast_tx_async [Deprecated] Sends a transaction and immediately returns transaction hash. Consider using send_tx instead. # Call View Function Source: https://docs.near.org/api-reference/call-view-function /openapi.json post /EXPERIMENTAL_call_function Calls a view function on a contract and returns the result. # Chunk Details Source: https://docs.near.org/api-reference/chunk-details /openapi.json post /chunk Returns details of a specific chunk. You can run a block details query to get a valid chunk hash. # Client Configuration Source: https://docs.near.org/api-reference/client-configuration /openapi.json post /client_config Queries client node configuration # Congestion Level Source: https://docs.near.org/api-reference/congestion-level /openapi.json post /EXPERIMENTAL_congestion_level Queries the congestion level of a shard. More info about congestion [here](https://near.github.io/nearcore/architecture/how/receipt-congestion.html?highlight=congestion#receipt-congestion) # Fetch Receipt Source: https://docs.near.org/api-reference/fetch-receipt /openapi.json post /EXPERIMENTAL_receipt Fetches a receipt by its ID (as is, without a status or execution outcome) # Gas Price Source: https://docs.near.org/api-reference/gas-price /openapi.json post /gas_price Returns gas price for a specific block_height or block_hash. Using [null] will return the most recent block's gas price. # Genesis Config Source: https://docs.near.org/api-reference/genesis-config /openapi.json post /EXPERIMENTAL_genesis_config [Deprecated] Get initial state and parameters for the genesis block. Consider genesis_config instead. # Genesis Configuration Source: https://docs.near.org/api-reference/genesis-configuration /openapi.json post /genesis_config Get initial state and parameters for the genesis block # Light Client Block Proof Source: https://docs.near.org/api-reference/light-client-block-proof /openapi.json post /EXPERIMENTAL_light_client_block_proof Returns the proofs for a transaction execution. # Light Client Proof Source: https://docs.near.org/api-reference/light-client-proof /openapi.json post /EXPERIMENTAL_light_client_proof Returns the proofs for a transaction execution. # List Access Keys Source: https://docs.near.org/api-reference/list-access-keys /openapi.json post /EXPERIMENTAL_view_access_key_list Returns all access keys for a given account. # Maintenance Windows Source: https://docs.near.org/api-reference/maintenance-windows /openapi.json post /EXPERIMENTAL_maintenance_windows [Deprecated] Returns the future windows for maintenance in current epoch for the specified account. In the maintenance windows, the node will not be block producer or chunk producer. Consider using maintenance_windows instead. # Network Info Source: https://docs.near.org/api-reference/network-info /openapi.json post /network_info Queries the current state of node network connections. This includes information about active peers, transmitted data, known producers, etc. # Network Query Source: https://docs.near.org/api-reference/network-query /openapi.json post /query This module allows you to make generic requests to the network. The `RpcQueryRequest` struct takes in a [`BlockReference`](https://docs.rs/near-primitives/0.12.0/near_primitives/types/enum.BlockReference.html) and a [`QueryRequest`](https://docs.rs/near-primitives/0.12.0/near_primitives/views/enum.QueryRequest.html). The `BlockReference` enum allows you to specify a block by `Finality`, `BlockId` or `SyncCheckpoint`. The `QueryRequest` enum provides multiple variants for performing the following actions: - View an account's details - View a contract's code - View the state of an account - View the `AccessKey` of an account - View the `AccessKeyList` of an account - Call a function in a contract deployed on the network. # Next Light Client Block Source: https://docs.near.org/api-reference/next-light-client-block /openapi.json post /next_light_client_block Returns the next light client block. # Node Health Source: https://docs.near.org/api-reference/node-health /openapi.json post /health Returns the current health status of the RPC node the client connects to. # Node Status Source: https://docs.near.org/api-reference/node-status /openapi.json post /status Requests the status of the connected RPC node. This includes information about sync status, nearcore node version, protocol version, the current set of validators, etc. # Ordered Validators Source: https://docs.near.org/api-reference/ordered-validators /openapi.json post /EXPERIMENTAL_validators_ordered Returns the current epoch validators ordered in the block producer order with repetition. This endpoint is solely used for bridge currently and is not intended for other external use cases. # Protocol Config Source: https://docs.near.org/api-reference/protocol-config /openapi.json post /EXPERIMENTAL_protocol_config A configuration that defines the protocol-level parameters such as gas/storage costs, limits, feature flags, other settings # Send Transaction Source: https://docs.near.org/api-reference/send-transaction /openapi.json post /send_tx Sends transaction. Returns the guaranteed execution status and the results the blockchain can provide at the moment. # Split Storage Info Source: https://docs.near.org/api-reference/split-storage-info /openapi.json post /EXPERIMENTAL_split_storage_info Contains the split storage information. More info on split storage [here](https://near-nodes.io/archival/split-storage-archival) # Transaction Result Source: https://docs.near.org/api-reference/transaction-result /openapi.json post /tx Queries status of a transaction by hash and returns the final transaction result. # Transaction Status Source: https://docs.near.org/api-reference/transaction-status /openapi.json post /EXPERIMENTAL_tx_status Queries status of a transaction by hash, returning the final transaction result and details of all receipts. # View Access Key Source: https://docs.near.org/api-reference/view-access-key /openapi.json post /EXPERIMENTAL_view_access_key Returns information about a single access key for given account. # View Account Source: https://docs.near.org/api-reference/view-account /openapi.json post /EXPERIMENTAL_view_account Returns information about an account for given account_id. # View Contract Code Source: https://docs.near.org/api-reference/view-contract-code /openapi.json post /EXPERIMENTAL_view_code Returns the contract code (Wasm binary) deployed to the account. # View Contract State Source: https://docs.near.org/api-reference/view-contract-state /openapi.json post /EXPERIMENTAL_view_state Returns the state (key-value pairs) of a contract based on the key prefix. # Block / Chunk Source: https://docs.near.org/api/rpc/block-chunk Learn how to retrieve details about blocks and chunks from the NEAR RPC API. The RPC API enables you to query the network and get details about specific blocks or chunks. ## Quick Reference | Method | Description | Parameters | | --------------------------------- | ------------------------------------------------------- | ------------------------------------- | | [`block`](#block-details) | Get block details by height, hash, or finality | `finality` OR `block_id` | | [`block_effects`](#block-effects) | Get changes in a specific block | `finality` OR `block_id` | | [`chunk`](#chunk-details) | Get chunk details by chunk\_id or block\_id + shard\_id | `chunk_id` OR `block_id` + `shard_id` | *** ## Block Details Queries network and returns block for given height or hash. You can also use `finality` param to return latest block details. **Note**: You may choose to search by a specific block *or* finality, you cannot choose both. * **method**: `block` * **params**: `finality` OR `block_id` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "block", "params": { "finality": "final" } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://test.rpc.fastnear.com", }); const response = await provider.block({ finality: 'final', }); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://rpc.testnet.near.org \ jsonrpc=2.0 \ id=dontcare \ method=block \ params:='{"finality": "final"}' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "block", "params": { "block_id": 187310138 } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://archival-rpc.testnet.near.org", }); const response = await provider.block({ blockId: 187310138, }); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://archival-rpc.testnet.near.org \ jsonrpc=2.0 \ id=dontcare \ method=block \ params:='{"block_id": 187310138}' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "block", "params": { "block_id": "6RWmTYhXCzjMjoY3Mz1rfFcnBm8E6XeDDbFEPUA4sv1w" } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://archival-rpc.testnet.near.org", }); const response = await provider.block({ blockId: '6RWmTYhXCzjMjoY3Mz1rfFcnBm8E6XeDDbFEPUA4sv1w', }); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://archival-rpc.testnet.near.org \ jsonrpc=2.0 \ id=dontcare \ method=block \ params:='{"block_id": "6RWmTYhXCzjMjoY3Mz1rfFcnBm8E6XeDDbFEPUA4sv1w"}' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "result": { "author": "node2", "chunks": [ { "chunk_hash": "CzPafxtJmM1FnRoasKWAVhceJzZzkz9RKUBQQ4kY9V1v", "shard_id": 0, "gas_limit": 1000000000000000, "gas_used": 0, "height_created": 187310138, "height_included": 187310138 } ], "header": { "hash": "6RWmTYhXCzjMjoY3Mz1rfFcnBm8E6XeDDbFEPUA4sv1w", "height": 187310138, "timestamp": 1739254177539033760, "gas_price": "100000000", "latest_protocol_version": 73 } }, "id": "dontcare" } ``` *** ## Block Effects Returns changes in a block for given block height or hash. Includes changes like `account_touched`, `access_key_touched`, `data_touched`, `contract_code_touched`. * **method**: `block_effects` * **params**: `finality` OR `block_id` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "block_effects", "params": { "finality": "final" } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://test.rpc.fastnear.com", }); const response = await provider.blockChanges({ finality: 'final', }); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://rpc.testnet.near.org \ jsonrpc=2.0 \ id=dontcare \ method=block_effects \ params:='{"finality": "final"}' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "block_effects", "params": { "block_id": 187310138 } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://archival-rpc.testnet.near.org", }); const response = await provider.blockChanges({ blockId: 187310138, }); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://archival-rpc.testnet.near.org \ jsonrpc=2.0 \ id=dontcare \ method=block_effects \ params:='{"block_id": 187310138}' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "block_effects", "params": { "block_id": "6RWmTYhXCzjMjoY3Mz1rfFcnBm8E6XeDDbFEPUA4sv1w" } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://archival-rpc.testnet.near.org", }); const response = await provider.blockChanges({ blockId: '6RWmTYhXCzjMjoY3Mz1rfFcnBm8E6XeDDbFEPUA4sv1w', }); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://archival-rpc.testnet.near.org \ jsonrpc=2.0 \ id=dontcare \ method=block_effects \ params:='{"block_id": "6RWmTYhXCzjMjoY3Mz1rfFcnBm8E6XeDDbFEPUA4sv1w"}' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "result": { "block_hash": "6RWmTYhXCzjMjoY3Mz1rfFcnBm8E6XeDDbFEPUA4sv1w", "block_effects": [ { "account_id": "account.rpc-examples.testnet", "type": "account_touched" }, { "account_id": "ping-account.testnet", "type": "account_touched" }, { "account_id": "account.rpc-examples.testnet", "type": "access_key_touched" }, { "account_id": "dev2-nsp.testnet", "type": "data_touched" } ] }, "id": "dontcare" } ``` *** ## Chunk Details Returns details of a specific chunk. You can run a [block details](#block-details) query to get a valid chunk hash. * **method**: `chunk` * **params**: `chunk_id` OR `block_id` + `shard_id` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "chunk", "params": { "chunk_id": "CzPafxtJmM1FnRoasKWAVhceJzZzkz9RKUBQQ4kY9V1v" } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://archival-rpc.testnet.near.org", }); const response = await provider.chunk( 'CzPafxtJmM1FnRoasKWAVhceJzZzkz9RKUBQQ4kY9V1v', ); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://archival-rpc.testnet.near.org \ jsonrpc=2.0 \ id=dontcare \ method=chunk \ params:='{"chunk_id": "CzPafxtJmM1FnRoasKWAVhceJzZzkz9RKUBQQ4kY9V1v"}' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "chunk", "params": { "block_id": 187310138, "shard_id": 0 } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://archival-rpc.testnet.near.org", }); const response = await provider.chunk([187310138, 0]); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://archival-rpc.testnet.near.org \ jsonrpc=2.0 \ id=dontcare \ method=chunk \ params:='{"block_id": 187310138, "shard_id": 0}' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "result": { "author": "kiln.pool.f863973.m0", "header": { "chunk_hash": "CzPafxtJmM1FnRoasKWAVhceJzZzkz9RKUBQQ4kY9V1v", "shard_id": 0, "gas_limit": 1000000000000000, "gas_used": 0, "height_created": 187310138, "height_included": 187310138 }, "receipts": [], "transactions": [ { "hash": "J3KbUXF9YPu2eGnbDCACxGvmMDZMdP7acGYhVLHGu9y2", "signer_id": "account.rpc-examples.testnet", "receiver_id": "contract.rpc-examples.testnet" } ] }, "id": "dontcare" } ``` *** ## Error Handling | Error Code | Description | Solution | | ------------------ | ------------------------------------ | ------------------------------------------------------ | | `UNKNOWN_BLOCK` | Block not found or garbage-collected | Check block validity; use archival node for old blocks | | `UNKNOWN_CHUNK` | Chunk not found in database | Verify chunk ID; use archival node for old chunks | | `INVALID_SHARD_ID` | Shard ID does not exist | Provide valid shard ID for existing shard | | `NOT_SYNCED_YET` | Node still syncing | Wait for sync completion or use different node | | `PARSE_ERROR` | Invalid request parameters | Check parameter format and completeness | | `INTERNAL_ERROR` | Server-side issue | Retry request or try different RPC endpoint | # Accounts / Contracts Source: https://docs.near.org/api/rpc/contracts Learn to query information from accounts and contracts using the NEAR RPC API. The RPC API enables you to view details about accounts and contracts as well as perform contract calls. ## Quick Reference | Method | Purpose | | ------------------------------------------------------ | ---------------------------------- | | [`view_account`](#view-account) | Get basic account information | | [`view_account_changes`](#view-account-changes) | Monitor account state changes | | [`view_code`](#view-contract-code) | Get deployed contract WASM code | | [`view_state`](#view-contract-state) | Get contract storage data | | [`data_changes`](#view-contract-state-changes) | Monitor contract state changes | | [`contract_code_changes`](#view-contract-code-changes) | Monitor contract deployments | | [`call_function`](#call-a-contract-function) | Execute read-only contract methods | *** ## View Account Returns basic account information. * **method**: `query` * **params**: `request_type: view_account`, `finality` OR `block_id`, `account_id` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "query", "params": { "request_type": "view_account", "finality": "final", "account_id": "account.rpc-examples.testnet" } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://test.rpc.fastnear.com" }); const response = await provider.query({ request_type: 'view_account', finality: 'final', account_id: 'account.rpc-examples.testnet', }); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://rpc.testnet.near.org \ jsonrpc=2.0 id=dontcare method=query \ params:='{"request_type":"view_account","finality":"final","account_id":"account.rpc-examples.testnet"}' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "result": { "amount": "999788200694421800000000", "block_hash": "56xEo2LorUFVNbkFhCncFSWNiobdp1kzm14nZ47b5JVW", "block_height": 187440904, "code_hash": "11111111111111111111111111111111", "locked": "0", "storage_usage": 410 }, "id": "dontcare" } ``` *** ## View Account Changes Returns account changes from transactions in a given account. * **method**: `changes` * **params**: `changes_type: account_changes`, `account_ids`, `finality` OR `block_id` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "changes", "params": { "changes_type": "account_changes", "account_ids": ["contract.rpc-examples.testnet"], "block_id": 187310139 } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://archival-rpc.testnet.near.org" }); const response = await provider.accountChanges( ['contract.rpc-examples.testnet'], { blockId: 187310139 } ); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://archival-rpc.testnet.near.org \ jsonrpc=2.0 id=dontcare method=changes \ params:='{"changes_type":"account_changes","account_ids":["contract.rpc-examples.testnet"],"block_id":187310139}' ``` *** ## View Contract Code Returns the contract code (Wasm binary) deployed to the account. The returned code is encoded in base64. * **method**: `query` * **params**: `request_type: view_code`, `finality` OR `block_id`, `account_id` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "query", "params": { "request_type": "view_code", "finality": "final", "account_id": "contract.rpc-examples.testnet" } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://test.rpc.fastnear.com" }); const response = await provider.query({ request_type: 'view_code', finality: 'final', account_id: 'contract.rpc-examples.testnet', }); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://rpc.testnet.near.org \ jsonrpc=2.0 id=dontcare method=query \ params:='{"request_type":"view_code","finality":"final","account_id":"contract.rpc-examples.testnet"}' ``` *** ## View Contract State Returns the state (key-value pairs) of a contract based on a key prefix (base64 encoded). Pass an empty string for `prefix_base64` to return the entire state. * **method**: `query` * **params**: `request_type: view_state`, `finality` OR `block_id`, `account_id`, `prefix_base64` By default, RPC nodes only return up to **50kB** of contract state. If the contract's state exceeds this limit, the query will return an error. To query larger state, use an archival node and paginate with `prefix_base64`. ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "query", "params": { "request_type": "view_state", "finality": "final", "account_id": "contract.rpc-examples.testnet", "prefix_base64": "" } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://test.rpc.fastnear.com" }); const response = await provider.query({ request_type: 'view_state', finality: 'final', account_id: 'contract.rpc-examples.testnet', prefix_base64: '', }); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://rpc.testnet.near.org \ jsonrpc=2.0 id=dontcare method=query \ params:='{"request_type":"view_state","finality":"final","account_id":"contract.rpc-examples.testnet","prefix_base64":""}' ``` *** ## View Contract State Changes Returns state change details of a contract based on a key prefix (base64 encoded). * **method**: `changes` * **params**: `changes_type: data_changes`, `account_ids`, `key_prefix_base64`, `finality` OR `block_id` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "changes", "params": { "changes_type": "data_changes", "account_ids": ["contract.rpc-examples.testnet"], "key_prefix_base64": "", "block_id": 187310139 } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://archival-rpc.testnet.near.org" }); const response = await provider.contractStateChanges( ['contract.rpc-examples.testnet'], { blockId: 187310139 }, '' ); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://archival-rpc.testnet.near.org \ jsonrpc=2.0 id=dontcare method=changes \ params:='{"changes_type":"data_changes","account_ids":["contract.rpc-examples.testnet"],"key_prefix_base64":"","block_id":187310139}' ``` *** ## View Contract Code Changes Returns code changes made when deploying a contract. Change is returned as a base64 encoded WASM file. * **method**: `changes` * **params**: `changes_type: contract_code_changes`, `account_ids`, `finality` OR `block_id` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "changes", "params": { "changes_type": "contract_code_changes", "account_ids": ["contract.rpc-examples.testnet"], "block_id": 187309439 } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://archival-rpc.testnet.near.org" }); const response = await provider.contractCodeChanges( ['contract.rpc-examples.testnet'], { blockId: 187309439 } ); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://archival-rpc.testnet.near.org \ jsonrpc=2.0 id=dontcare method=changes \ params:='{"changes_type":"contract_code_changes","account_ids":["contract.rpc-examples.testnet"],"block_id":187309439}' ``` *** ## Call a Contract Function Allows you to call a contract method as a view function (read-only). * **method**: `query` * **params**: `request_type: call_function`, `finality` OR `block_id`, `account_id`, `method_name`, `args_base64` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "query", "params": { "request_type": "call_function", "finality": "final", "account_id": "contract.rpc-examples.testnet", "method_name": "get_greeting", "args_base64": "" } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://test.rpc.fastnear.com" }); const response = await provider.query({ request_type: 'call_function', finality: 'final', account_id: 'contract.rpc-examples.testnet', method_name: 'get_greeting', args_base64: '', }); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://rpc.testnet.near.org \ jsonrpc=2.0 id=dontcare method=query \ params:='{"request_type":"call_function","finality":"final","account_id":"contract.rpc-examples.testnet","method_name":"get_greeting","args_base64":""}' ``` *** ## Error Handling | Error Code | Description | Solution | | ----------------------- | ------------------------------ | ------------------------------------------- | | `UnknownAccount` | Account does not exist | Check account ID spelling | | `InvalidAccount` | Invalid account format | Use valid account ID (e.g., `account.near`) | | `UnknownBlock` | Block not found | Use a valid block hash or height | | `GarbageCollectedBlock` | Block too old | Use archival node or more recent block | | `NoContractCode` | No contract deployed | Verify the account has a deployed contract | | `MethodNotFound` | Contract method does not exist | Check method name and contract ABI | | `InvalidArgs` | Invalid method arguments | Verify args format and encoding | # Gas Source: https://docs.near.org/api/rpc/gas Query gas prices for specific blocks or hashes using the NEAR RPC API. The RPC API enables you to query the gas price for a specific block or hash. ## Quick Reference | Parameter | Type | Description | | -------------- | -------- | -------------------------------------------- | | `block_height` | `number` | Specific block height to query gas price for | | `block_hash` | `string` | Specific block hash to query gas price for | | `null` | `null` | Returns gas price for the latest block | *** ## Gas Price Returns gas price for a specific `block_height` or `block_hash`. Using `[null]` will return the most recent block's gas price. * **method**: `gas_price` * **params**: `[block_height]`, `["block_hash"]`, or `[null]` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "gas_price", "params": [null] } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://test.rpc.fastnear.com", }); const response = await provider.gasPrice(null); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://rpc.testnet.near.org \ jsonrpc=2.0 \ id=dontcare \ method=gas_price \ params:='[null]' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "gas_price", "params": [187310138] } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://archival-rpc.testnet.near.org", }); const response = await provider.gasPrice(187310138); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://archival-rpc.testnet.near.org \ jsonrpc=2.0 \ id=dontcare \ method=gas_price \ params:='[187310138]' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "gas_price", "params": ["6RWmTYhXCzjMjoY3Mz1rfFcnBm8E6XeDDbFEPUA4sv1w"] } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://archival-rpc.testnet.near.org", }); const response = await provider.gasPrice( '6RWmTYhXCzjMjoY3Mz1rfFcnBm8E6XeDDbFEPUA4sv1w', ); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://archival-rpc.testnet.near.org \ jsonrpc=2.0 \ id=dontcare \ method=gas_price \ params:='["6RWmTYhXCzjMjoY3Mz1rfFcnBm8E6XeDDbFEPUA4sv1w"]' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "result": { "gas_price": "100000000" } } ``` # Protocol Call Reference Source: https://docs.near.org/api/rpc/introduction Overview of tools and methods for interacting with the NEAR Protocol. NEAR Protocol provides multiple ways to interact with the network — from low-level JSON-RPC calls to visual explorers and wallets. ## Tools Browse transactions, accounts, blocks, and contracts on mainnet and testnet. Create and manage NEAR accounts, send tokens, and interact with dApps. ## RPC API NEAR exposes a JSON-RPC 2.0 API for programmatic access to the network. All requests are `POST` to a provider endpoint, with the method name encoded in the URL path. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -X POST https://rpc.mainnet.near.org/status \ -H "Content-Type: application/json" \ -d '{}' ``` See [RPC Providers](/api/rpc/providers) for the full list of public endpoints. ## Available Methods | Category | Methods | | ----------------------------------------- | -------------------------------------------------------------------------------------- | | [**Transactions**](/api/rpc/transactions) | `send_tx`, `tx`, `EXPERIMENTAL_tx_status`, `broadcast_tx_async`, `broadcast_tx_commit` | | **Blocks & Chunks** | `block`, `chunk`, `block_effects`, `changes` | | **Accounts & Keys** | `query` (view account, code, state, access keys, call function) | | **Network** | `status`, `health`, `network_info`, `validators` | | **Gas & Config** | `gas_price`, `genesis_config`, `EXPERIMENTAL_protocol_config` | | **Light Client** | `light_client_proof`, `next_light_client_block` | Explore the full interactive reference in the sidebar, or start with [RPC Providers](/api/rpc/providers) to configure your endpoint. # Protocol Source: https://docs.near.org/api/rpc/protocol Learn how to retrieve the genesis and current protocol configurations using the NEAR RPC API. The RPC API enables you to retrieve the current genesis and protocol configuration. ## Quick Reference | Method | Parameters | Description | | -------------------------------------------------- | ------------------------ | ----------------------------------------------------------- | | [`genesis_config`](#genesis-config) | *none* | Returns current genesis configuration | | [`EXPERIMENTAL_protocol_config`](#protocol-config) | `finality` OR `block_id` | Returns protocol configuration for latest or specific block | *** ## Genesis Config Returns current genesis configuration. * **method**: `genesis_config` * **params**: *none* ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "genesis_config" } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://test.rpc.fastnear.com", }); const response = await provider.experimental_protocolConfig({ sync_checkpoint: 'genesis', }); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://rpc.testnet.near.org \ jsonrpc=2.0 \ id=dontcare \ method=genesis_config ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "result": { "chain_id": "testnet", "epoch_length": 43200, "gas_limit": 1000000000000000, "genesis_height": 42376888, "genesis_time": "2020-07-31T03:39:42.911378Z", "min_gas_price": "5000", "num_block_producer_seats": 200, "protocol_version": 29, "total_supply": "2089646653180081825096998107194444" }, "id": "dontcare" } ``` *** ## Protocol Config Returns most recent protocol configuration or a specific queried block. Useful for finding current storage and transaction costs. * **method**: `EXPERIMENTAL_protocol_config` * **params**: `finality` OR `block_id` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "EXPERIMENTAL_protocol_config", "params": { "finality": "final" } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://test.rpc.fastnear.com", }); const response = await provider.experimental_protocolConfig({ finality: "final" }); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://rpc.testnet.near.org \ jsonrpc=2.0 \ id=dontcare \ method=EXPERIMENTAL_protocol_config \ params:='{"finality": "final"}' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "result": { "chain_id": "testnet", "epoch_length": 43200, "gas_limit": 1000000000000000, "protocol_version": 73, "runtime_config": { "storage_amount_per_byte": "10000000000000000000", "transaction_costs": { "action_receipt_creation_config": { "execution": 108059500000, "send_not_sir": 108059500000, "send_sir": 108059500000 } } } }, "id": "dontcare" } ``` *** ## Best Practices * Use `finality: "final"` for most recent confirmed protocol configuration * Use specific `block_id` when you need protocol config for a particular block * Cache protocol configuration results as they change infrequently * Use the protocol config to calculate current storage and transaction costs # RPC Providers Source: https://docs.near.org/api/rpc/providers List of public RPC endpoints for the NEAR Protocol. NEAR Protocol exposes a JSON-RPC API for interacting with the network. You can use any of the providers below or run your own node. ## RPC Providers FastNear maintains a [comprehensive dashboard](https://grafana.fastnear.com/public-dashboards/577b37c6cfe84b2bae23af471d27cade) with response times for most of the available endpoints. ### Mainnet | Provider | Endpoint | Public Endpoint | Archival Node | Free Tier | Paid Plan | | ----------------------------------------------------------------------- | ----------------------------------------------- | :-------------: | :-----------: | :-------------------: | :-------: | | [FASTNEAR](https://fastnear.com) | `https://free.rpc.fastnear.com` | ✅ | Paid Only | ✅ | ✅ | | [NEAR](https://near.org) | `https://archival-rpc.mainnet.near.org` | ✅ | ✅ | Severely rate limited | ❌ | | [1RPC](https://1rpc.io) | `https://1rpc.io/near` | ✅ | ❌ | ✅ | ✅ | | [All That Node](https://www.allthatnode.com/protocol/near.dsrv) | N/A | ❌ | ✅ | ✅ | ✅ | | [Ankr](https://www.ankr.com/rpc/near/) | `https://rpc.ankr.com/near` | ❌ | ❌ | ✅ | ✅ | | [BlockPI Network](https://blockpi.io/chain/near) | `https://near.blockpi.network/v1/rpc/public` | ✅ | ❌ | ✅ | ✅ | | [dRPC](https://drpc.org/chainlist/near-mainnet-rpc) | `https://near.drpc.org` | ✅ | ❌ | ✅ | ✅ | | [GetBlock](https://getblock.io/nodes/near/) | `https://go.getblock.io/{api-key}` | ❌ | ❌ | ✅ | ✅ | | [Intear RPC](https://intea.rs/) | `https://rpc.intea.rs` | ✅ | ❌ | ✅ | ❌ | | [Lava Network](https://www.lavanet.xyz/lava-public-rpc) | N/A | ❌ | ✅ | ❌ | ✅ | | [Lavender.Five Nodes](https://www.lavenderfive.com/tools/near/overview) | N/A | ❌ | ❌ | ✅ | ✅ | | [NodeReal](https://nodereal.io/api-marketplace/near-rpc) | `https://near-mainnet.nodereal.io/v1/{api-key}` | ❌ | ❌ | ✅ | ✅ | | [NOWNodes](https://nownodes.io/near) | `https://near.nownodes.io/{api-key}` | ❌ | ❌ | ✅ | ✅ | | [QuickNode](https://www.quicknode.com/chains/near) | N/A | ❌ | ✅ | ✅ | ✅ | | [Shitzu](https://shitzuapes.xyz/) | `https://rpc.shitzuapes.xyz` | ✅ | ❌ | ✅ | ❌ | | [Tatum](https://tatum.io/chain/near/) | N/A | ❌ | ❌ | ✅ | ✅ | | [ZAN](https://zan.top/service/apikeys) | `https://api.zan.top/node/v1/near/mainnet/` | ✅ | ❌ | ✅ | ✅ | | [Zeeve](https://www.zeeve.io/blockchain-protocols/deploy-near-node/) | N/A | ❌ | ✅ | ❌ | ✅ | ### Testnet | Provider | Endpoint | Public Endpoint | Archival Node | Free Tier | Paid Plan | | -------------------------------------------------------------------- | --------------------------------------------- | :-------------: | :-----------: | :-------------------: | :-------: | | [FASTNEAR](https://fastnear.com) | `https://test.rpc.fastnear.com` | ✅ | Paid Only | ✅ | ✅ | | [NEAR](https://near.org) | `https://archival-rpc.testnet.near.org` | ✅ | ✅ | Severely rate limited | ❌ | | [All That Node](https://www.allthatnode.com/protocol/near.dsrv) | N/A | ❌ | ✅ | ✅ | ✅ | | [dRPC](https://drpc.org/chainlist/near-testnet-rpc) | `https://near-testnet.drpc.org` | ✅ | ❌ | ✅ | ✅ | | [Intear RPC](https://intea.rs/) | `https://testnet-rpc.intea.rs` | ✅ | ❌ | ✅ | ❌ | | [Lava Network](https://www.lavanet.xyz/lava-public-rpc) | N/A | ❌ | ✅ | ❌ | ✅ | | [QuickNode](https://www.quicknode.com/chains/near) | N/A | ❌ | ✅ | ✅ | ✅ | | [Tatum](https://tatum.io/chain/near/) | N/A | ❌ | ❌ | ✅ | ✅ | | [ZAN](https://zan.top/service/apikeys) | `https://api.zan.top/node/ws/v1/near/testnet` | ❌ | ❌ | ✅ | ✅ | | [Zeeve](https://www.zeeve.io/blockchain-protocols/deploy-near-node/) | N/A | ❌ | ❌ | ❌ | ✅ | ## Making requests All endpoints accept JSON-RPC 2.0 `POST` requests. The NEAR RPC uses a non-standard format where the method name is encoded in the URL path rather than the request body. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -X POST https://rpc.mainnet.near.org/status \ -H "Content-Type: application/json" \ -d '{}' ``` ## Run your own node To run a local RPC node, follow the [NEAR node documentation](https://near-nodes.io/rpc/hardware-rpc). Testnet tokens have no real value and can be obtained from the [NEAR Faucet](/getting-started/faucet). # Transactions Source: https://docs.near.org/api/rpc/transactions Send transactions and query their status using the NEAR RPC API. The RPC API exposes several methods for broadcasting signed transactions and tracking their execution. All transaction methods accept a base64-encoded `signed_tx_base64` payload. Status methods accept either the same payload or a `tx_hash` + `sender_account_id` pair. ## Quick Reference | Method | Purpose | | ------------------------------------------------------------- | --------------------------------------------------------------- | | [`send_tx`](#send-transaction) | Broadcast a signed transaction and wait for the result | | [`tx`](#transaction-status) | Get the status of a previously broadcast transaction | | [`EXPERIMENTAL_tx_status`](#transaction-status-with-receipts) | Like `tx`, but also returns receipt details | | [`EXPERIMENTAL_receipt`](#receipt-by-id) | Fetch a single receipt by id | | [`broadcast_tx_async`](#broadcast-async) | Broadcast and return immediately with the transaction hash | | [`broadcast_tx_commit`](#broadcast-commit) | Broadcast and wait until the transaction is included in a block | Prefer `send_tx` and `tx` for new integrations. The `broadcast_tx_async` and `broadcast_tx_commit` methods are kept for backward compatibility but offer less control over when the call returns. *** ## The `wait_until` Field `send_tx` and `tx` accept an optional `wait_until` field that controls **how long the RPC waits before returning a response**. Each value waits for a stricter execution milestone than the previous one — pick the lowest level that satisfies your use case so you don't pay extra latency. | Value | Returns when… | Typical use | | --------------------------------- | ------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | | `NONE` | The transaction is queued but not yet included in a block. | Fire-and-forget broadcasts where you only need the hash. | | `INCLUDED` | The transaction is included in a block (the block may not be finalized). | UI optimism: you want to confirm the tx hit the chain. | | `EXECUTED_OPTIMISTIC` *(default)* | Included + all non-refund receipts have executed (blocks may still not be finalized). | Default for most apps — you can read the result. | | `INCLUDED_FINAL` | Included in a *finalized* block. | You need finality but don't care about receipts. | | `EXECUTED` | Finalized + all non-refund receipts executed. | Strong correctness without waiting for refund receipts. | | `FINAL` | Finalized + all receipts (including refunds) finalized. | Accounting and cross-chain settlement, where refund-tracking matters. | If the field is omitted, the RPC behaves as if `EXECUTED_OPTIMISTIC` was passed. ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "send_tx", "params": { "signed_tx_base64": "DwAAAHNlbmRlci50ZXN0bmV0...", "wait_until": "FINAL" } } ``` Higher `wait_until` levels can take several seconds. If your client has a short timeout, prefer `INCLUDED` or `EXECUTED_OPTIMISTIC` and poll `tx` for the stricter level. *** ## Send Transaction Broadcasts a signed transaction and waits for the requested execution milestone before returning. * **method**: `send_tx` * **params**: `signed_tx_base64`, optional `wait_until` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "send_tx", "params": { "signed_tx_base64": "DwAAAHNlbmRlci50ZXN0bmV0...", "wait_until": "EXECUTED_OPTIMISTIC" } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://test.rpc.fastnear.com" }); const response = await provider.sendTransactionUntil( signedTransaction, 'EXECUTED_OPTIMISTIC', ); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} http POST https://rpc.testnet.near.org \ jsonrpc=2.0 id=dontcare method=send_tx \ params:='{"signed_tx_base64":"DwAAAHNlbmRlci50ZXN0bmV0...","wait_until":"EXECUTED_OPTIMISTIC"}' ``` *** ## Transaction Status Returns the status of a previously submitted transaction. * **method**: `tx` * **params**: either `signed_tx_base64`, or `tx_hash` + `sender_account_id`. Optional `wait_until`. ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "jsonrpc": "2.0", "id": "dontcare", "method": "tx", "params": { "tx_hash": "6zgh2u9DqHHiXzdy9ouTP7oGky2T4nugbhqsK7wQHnZS", "sender_account_id": "sender.testnet", "wait_until": "FINAL" } } ``` ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { JsonRpcProvider } from "near-api-js"; const provider = new JsonRpcProvider({ url: "https://test.rpc.fastnear.com" }); const response = await provider.txStatus( '6zgh2u9DqHHiXzdy9ouTP7oGky2T4nugbhqsK7wQHnZS', 'sender.testnet', 'FINAL', ); ``` *** ## Transaction Status with Receipts `EXPERIMENTAL_tx_status` returns the same payload as `tx` plus the full set of receipts produced by the transaction. Useful when debugging cross-contract calls. * **method**: `EXPERIMENTAL_tx_status` * **params**: same as `tx` *** ## Receipt by Id Fetches a single receipt by its id. * **method**: `EXPERIMENTAL_receipt` * **params**: `receipt_id` *** ## Broadcast Async Broadcasts a signed transaction and returns immediately with the transaction hash. Equivalent to `send_tx` with `wait_until: "NONE"`. * **method**: `broadcast_tx_async` * **params**: a single positional string — the base64-encoded signed transaction. *** ## Broadcast Commit Broadcasts a signed transaction and waits for it to be included in a block. Equivalent to `send_tx` with `wait_until: "EXECUTED_OPTIMISTIC"`. * **method**: `broadcast_tx_commit` * **params**: a single positional string — the base64-encoded signed transaction. *** ## Error Handling | Error Code | Description | Solution | | --------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | | `INVALID_TRANSACTION` | The signed transaction failed validation. | Re-sign with the correct nonce, block hash, and signer key. | | `EXPIRED_TRANSACTION` | The reference block hash is too old. | Refresh `block_hash` and re-sign. | | `TIMEOUT_ERROR` | The chosen `wait_until` level was not reached before the RPC's deadline. | Lower `wait_until` and poll `tx`, or use an archival/dedicated provider. | | `UNKNOWN_TRANSACTION` | No record of the requested transaction hash. | Verify the hash and `sender_account_id`. | | `INVALID_SIGNATURE` | The signature does not match the signer's key. | Sign again with the matching access key. | # What are Chain Signatures? Source: https://docs.near.org/chain-abstraction/chain-signatures Learn how Chain Signatures enable NEAR accounts to sign and execute transactions across multiple blockchains using Multi-Party Computation for secure cross-chain operations. Chain signatures enable NEAR accounts, including smart contracts, to sign and execute transactions across many blockchain protocols. This unlocks the next level of blockchain interoperability by giving ownership of diverse assets, cross-chain accounts, and data to every single NEAR account. chain-signatures *Diagram of a chain signature in NEAR* While you can sign transactions for any network using Eddsa or Ecdsa keys, each chain signs transactions differently. Our example [implementation](./chain-signatures/implementation) shows you how to sign transactions for: Bitcoin, Solana, Cosmos, XRP, Aptos, Sui and EVM networks (Ethereum, Base, BNB Chain, Avalanche, Polygon, Arbitrum, and more). ## Benefits Integration with Chain Signatures brings many benefits to Web3 developers: * Single Account, Multi-Chain Operations: Developers can manage interactions with external blockchains from one NEAR account. This simplifies key management and reduces the need for multiple wallets or addresses, enhancing user experience and security. * Reduced Overhead in Cross-Chain Development: Chain Signatures eliminate the complexity of managing transactions across different blockchains. Developers can write smart contracts on NEAR that directly sign for cross-chain transactions, cutting down on code redundancy and potential points of failure. * Secure Transaction Signing: Using [Multi-Party Computation (MPC)](#multi-party-computation-service), developers gain access to a decentralized signing process for multi-chain transactions. This means no single entity controls the signing key, reducing risks associated with centralized custodianship. Keep in mind that Chain Signatures is a “one way” solution to sign and execute outbound transactions happening on other blockchains. If you're looking to access states on external blockchains, you should check out Omnibridge. ## Interoperability NEAR's chain abstraction stack allows developers to leverage powerful interoperability options across different blockchains. Developers can execute their business logic and deploy smart contracts on NEAR’s scalable blockchain infrastructure, while maintaining control over external accounts (such as Bitcoin, Ethereum, Base) and assets natively. This integrated approach combines external blockchain assets with NEAR’s scalability, enabling the development of native dApps that offer superior performance and an optimized user experience. By combining the strengths of different ecosystems, NEAR Protocol unlocks an array of transformative possibilities without compromising on decentralization or scalability. ## Use Cases The Chain Signatures architecture provides a decentralized method to interact with multiple blockchains from one NEAR account. With Chain Signatures, blockchain use cases expands to new levels. ### Bitcoin DeFi Developers can build decentralized finance (DeFi) applications on NEAR, such as decentralized exchanges (DEXs), lending platforms, or yield farming protocols, while directly leveraging Bitcoin liquidity. The business logic resides on NEAR, while BTC is used for actual payments. #### Examples * Atomic Swaps: Facilitate trustless, instant exchanges between Bitcoin and other cryptocurrencies, enhancing liquidity and reducing counterparty risk. * Receive Bitcoin payments with a native transfer to a Chain Signature derived account. * Use Chain Signatures to control the payment flow and execute Bitcoin transactions, such as locking or transferring assets. * Use smart contracts on NEAR to encapsulate business logic such as interest calculations, borrowing, order processing, reward distribution, and repayments. ### Cross-Chain NFT Platforms Developers can create a NFT marketplace on NEAR where users purchase NFTs using external cryptocurrencies such as Bitcoin. The marketplace could handle: * BTC payments via Chain Signatures and Omnibridge. * NFT minting and trading logic on NEAR. (*NFTs could also be minted on multiple blockchains thanks to Chain Signatures*) *** ## How It Works Controlling accounts and their assets on other blockchain platforms is made possible thanks to the interaction between three elements: 1. [**Derivation Paths**](#derivation-paths-one-account-multiple-chains) - A deterministic way to derive foreign addresses from one NEAR account 2. [**Multichain Smart Contract**](#multichain-smart-contract) - Receives requests to sign a transaction for other blockchains 3. [**Multiparty Computation Service**](#multi-party-computation-service) - Third-party service providing signatures to the contract Chain Signatures *Chain signatures flow* ### Derivation Paths: One Account, Multiple Chains Chain Signatures link NEAR accounts to addresses in other blockchain using [Additive Key Derivation](https://eprint.iacr.org/2021/1330) (a simple mechanism for deriving many subkeys from a single master key). These keys are generated using `derivation paths` (or `paths` for short). A `derivation path` is simply a string (e.g. `ethereum-1`, `ethereum-2`, etc) that in conjunction with the NEAR account derives a unique address on the target blockchain. For example, we can derive multiple Ethereum addresses from `example.near` by using different paths: 1. `example.near` + `ethereum-1` = `0x1b48b83a308ea4beb845db088180dc3389f8aa3b` 2. `example.near` + `ethereum-2` = `0x99c5d3025dc736541f2d97c3ef3c90de4d221315` 3. `example.near` + `...` = `0x...` It is important to note that this allows us to discover the **public address** of the foreign account that we can control. To actually control the foreign account, we need to request signatures from the MPC service. In practice, the external address is deterministically derived using the NEAR address (`example.near`), the path (`ethereum-1`) and the MPC service's public key ### Multichain Smart Contract A deployed multichain smart contract ([v1.signer](https://nearblocks.io/address/v1.signer)) is used to request signatures for transactions on other blockchains. This contract has [a `sign` method](https://github.com/near/mpc/blob/01f33ed0a2a2c4c24ef49a2f36df3b20aa400816/libs/chain-signatures/contract/src/lib.rs#L242) that takes these three parameters: 1. The `payload` (transaction or transaction hash) to be signed for the target blockchain. 2. The `path` that identifies the account to be used to sign the transaction. 3. The `domain_id` as an integer that identifies the signature scheme to be used for generating the signature. Currently this can be `0` for Secp256k1 or `1` for Ed25519. For example, a user could request a signature to `send 0.1 ETH to 0x060f1...` **(transaction)** using the `ethereum-1` account **(path)** with `0` (Secp256k1) as **domain ID**. After a request is made, the `sign` method will yield execution waiting while the [MPC signing service](#multi-party-computation-service) signs the transaction. Once the signature is ready, the contract resumes computation and returns it to the user. This signature is a valid signed transaction that can be readily sent to the target blockchain to be executed. The `sign` method currently supports both Secp256k1 and Ed25519 signature schemes which enables signing transactions for the vast majority of the well-known blockchains including Bitcoin, Ethereum, Solana, BNB chain, Ton, or Stellar. In the future, the MPC participants can add more signature schemes via the `vote_add_domains` method. ### Multi-Party Computation Service The essence of Multi-Party Computation (MPC) is to enable independent parties to perform shared computations on private information without revealing secrets to each other. In practice, this system can be used with blockchain platforms to safely sign a transaction on behalf of a user without ever having to expose a private key. 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. Currently, the service is composed of 8 independent nodes. However the set of participating nodes can be extended with the `vote_new_parameters` method of the `v1.signer` smart contract if enough active nodes vote for it. 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 `v1.signer` contract to store the resulting `Signature` **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. NEAR's MPC service allows for nodes to safely join and leave, without needing to re-derive a master key. Want to learn more about the mathematics that enable MPC? [**Check this awesome article**](https://www.zellic.io/blog/mpc-from-scratch/). *** ## Concluding Remarks Chain Signatures are a powerful tool that allows NEAR accounts to control accounts on other blockchains. This is a fundamental step towards enabling true ownership of cross-chain data and assets. For the user, the process is made completely **on chain**, since they only need to make a call to a smart contract and wait for the response. Thanks to `derivation paths`, a single NEAR account can control **multiple accounts** on different blockchains, and thanks to the MPC service, the user can be sure that **nobody but themselves** can request signatures for those accounts. # Signing Transactions Source: https://docs.near.org/chain-abstraction/chain-signatures/implementation Learn how to sign transactions across multiple blockchains. Chain signatures enable NEAR accounts, including smart contracts, to sign and execute transactions across many blockchain protocols. This unlocks the next level of blockchain interoperability by giving ownership of diverse assets, cross-chain accounts, and data to a single NEAR account. While you can sign transactions for any network using Eddsa or Ecdsa keys, each chain signs transactions differently. Our example implementation shows you how to sign transactions for: Bitcoin, Solana, Cosmos, XRP, Aptos, Sui and EVM networks (Ethereum, Base, BNB Chain, Avalanche, Polygon, Arbitrum, and more). *** ## Create a Chain Signature There are five steps to create a Chain Signature: 1. [Deriving the Foreign Address](#1-deriving-the-foreign-address) - Derive 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 MPC contract requesting it to sign the transaction. 4. [Formatting the Signature](#4-formatting-the-signature) - Format the signature from the MPC contract and add it to the transaction. 5. [Relaying the Signed Transaction](#5-relaying-the-signed-transaction) - Send the signed transaction to the destination chain for execution. chain-signatures *Diagram of a chain signature in NEAR* The [chainsig.js](https://github.com/NearDeFi/chainsig.js) library provides a convenient interface for completing each of these steps. For building transactions inside of NEAR smart contracts written in Rust, you can use the [Omni Transaction](https://github.com/near/omni-transaction-rs) library to easily build transactions for different blockchains (like Bitcoin and Ethereum). **MPC Contracts** There is an [MPC contract](https://github.com/Near-One/mpc/tree/main/libs/chain-signatures/contract) available on both `mainnet` and `testnet`: * Mainnet: `v1.signer` * Testnet: `v1.signer-prod.testnet` The MPC network is made up of 8 nodes. *** ## Chain Signatures Contract To interact with the chain signatures library you first need to instantiate a `ChainSignaturesContract`. The `networkId` and `contractId` are set to the values specified in the previous section depending which network you are on. *** ## Chain Adapters To interact with a specific chain, you need to instantiate the relevant `chainAdapter`. The EVM chain adapter takes the `ChainSignaturesContract` as an argument as well as `publicClient` which is constructed from an EVM RPC URL. To use different EVM networks, simply specify the RPC URL for your desired network. The example demonstrates compatibility with multiple EVM-compatible networks including Ethereum, Base, BNB Chain, Avalanche, Polygon, Arbitrum, zkSync, and many others. You can find RPC URLs for various networks at [ChainList](https://chainlist.org/?testnets=true). The Bitcoin chain adapter takes the `ChainSignaturesContract` as an argument as well as the `network` ("mainnet", "testnet" or "regtest") and a `btcRpcAdapter` which handles communication with the Bitcoin network. The Solana chain adapter takes the `ChainSignaturesContract` as an argument as well as a `connection` which is constructed from a Solana RPC URL. If you want to use Mainnet, then you need to choose a Mainnet RPC. The XRP chain adapter takes the `ChainSignaturesContract` as an argument as well as an `rpcUrl` for the XRP Ledger and the `rpcURl` specification. For testnet, use `https://s.altnet.rippletest.net:51234`. The SUI chain adapter takes the `ChainSignaturesContract` as an argument as well as a `connection` which is a SuiClient constructed from a SUI RPC URL. The Aptos chain adapter takes the `ChainSignaturesContract` as an argument as well as a `nodeUrl` for the Aptos network and the `network` specification. *** ## 1. Deriving the Foreign Address Chain Signatures use [`derivation paths`](../chain-signatures#derivation-paths-one-account-multiple-chains) to represent accounts on the target blockchain. The foreign address to be controlled can be deterministically derived from: * The NEAR account calling the MPC contract (e.g., `example.near`, `example.testnet`, etc.) * A derivation path (a string such as `ethereum-1`, `ethereum-2`, etc.) * The MPC service's master public key (we don't need to worry about this as it is defined in the library we're using). To derive the address call the `deriveAddressAndPublicKey` method passing the near account Id from which the address is being derived and the derivation path. On Solana, your address is the same as your public key. The same NEAR account and path will always produce the same address on the target blockchain. * `example.near` + `ethereum-1` = `0x1b48b83a308ea4beb845db088180dc3389f8aa3b` * `example.near` + `ethereum-2` = `0x99c5d3025dc736541f2d97c3ef3c90de4d221315` *** ## 2. Creating the Transaction To construct the transaction to be signed use the method `prepareTransactionForSigning`. Constructing a transaction to transfer ETH is very simple. The `value` is the amount of ETH in Wei as type BigInt (1 ETH = 1018 Wei). This method returns the `unsigned transaction` and the transaction `hash(es)` (also known as the `payload`). Constructing a transaction to transfer BTC is very simple. The `value` is the amount of BTC in satoshis as a string (1 BTC = 100,000,000 sats). This method returns the `unsigned transaction` and the transaction `hash(es)` (also known as the `payload`). Constructing a transaction to transfer SOL is very simple. The `value` is the amount of SOL in lamports as type BigInt (1 SOL = 1,000,000,000 lamports). This method returns the `unsigned transaction`. Constructing a transaction to transfer XRP is straightforward. The `value` is the amount of XRP in drops as a string (1 XRP = 1,000,000 drops). This method returns the `unsigned transaction` and the transaction `hash` (also known as the `payload`). Constructing a transaction to transfer SUI is simple. The `value` is the amount of SUI in MIST as type BigInt (1 SUI = 1,000,000,000 MIST). This method returns the `unsigned transaction` and the transaction `hash` (also known as the `payload`). Constructing a transaction to transfer APT is straightforward. The `value` is the amount of APT in octas as type BigInt (1 APT = 100,000,000 octas). This method returns the `unsigned transaction` and the transaction `hash` (also known as the `payload`). To call a function on a smart contract we need the ABI of the contract, in our repo this is defined in the [config.js](https://github.com/near-examples/near-multichain/blob/main/src/config.js#L23-L63) file (this can be gathered from Remix or using Etherscan). Then define a `Contract` object using the `ethers` library Then to construct the transaction This approach allows you to call smart contract functions by encoding the function data and including it in the transaction. *** ## 3. Requesting the Signature Once the transaction is created and ready to be signed, a signature request is made by calling `sign` on the MPC smart contract. The method requires four parameters: 1. The `payloads` (or hashes) to be signed for the target blockchain 2. The derivation `path` for the account we want to use to sign the transaction 3. The `keyType`, `Ecdsa` for `Secp256k1` signatures and `Eddsa` for `Ed25519` signatures. 4. The `signerAccount` which contains the `accountId` that is signing and the `signAndSendTransactions` function from [Near Connect](../../web3-apps/tutorials/wallet-login). For Bitcoin, it is common to have multiple UTXOs to sign when sending a single transaction. We create a NEAR transaction (to call `sign` on the MPC contract) for each UTXO and send them to be signed by the MPC individually. Each signature is then parsed from each transaction outcome to produce an array of signatures. To get the payload, serialize the transaction to a `uint8Array` and then convert it to hex. *** ## 4. Formatting the Signature Once the signature is returned from the MPC it needs to be formatted and added to the transaction to produce a signed transaction. For Bitcoin, the array of signatures is added to the transaction to produce a complete signed transaction. *** ## 5. Relaying the Signed Transaction Now that we have a signed transaction, we can relay it to the target network using `broadcastTx`. The method returns a transaction hash which can be used to locate the transaction on an explorer. ⭐️ For a deep dive into the concepts of Chain Signatures, see [What are Chain Signatures?](../chain-signatures) ⭐️ For a complete example of a NEAR account using chain signatures in a frontend, see our [web app example](https://github.com/near-examples/near-multichain). # Controlling a NEAR account Source: https://docs.near.org/chain-abstraction/chain-signatures/tutorials/controlling-near-accounts/0-introduction Learn to control a NEAR account securely using Multi-Party Computation. Imagine acting on behalf of another Near account - without ever holding its private key. Sounds futuristic? It’s possible today, thanks to [Chain Abstraction and Multi-Party Computation (MPC)](/chain-abstraction/what-is), and this tutorial will walk you step-by-step through the entire process of transferring 0.1 NEAR on behalf of another Near account. ## How It Works Behind the scenes, a smart contract constructs a valid transaction on behalf of a user and forwards it to an MPC contract for signing. The key advantage of this approach is that no single entity possesses the private key — ensuring enhanced security and decentralization. The complete source code for the smart contract used in this tutorial, along with scripts for playground simulation, is available in the [GitHub repository](https://github.com/nearuaguild/control-near-account-with-mpc-example). The contract is rolled out on testnet at `broken-rock.testnet`, feel free to use it for your own purposes if you don't want to dig deeper into deploying it on your own. ## What You Will Learn In this tutorial, you will learn how to: * [Prepare Near account](/chain-abstraction/chain-signatures/tutorials/controlling-near-accounts/1-setup) to be fully controlled via MPC * [Build a transfer transaction and get it signed](/chain-abstraction/chain-signatures/tutorials/controlling-near-accounts/2-transfer) in a smart contract * [Broadcast a signed transaction](/chain-abstraction/chain-signatures/tutorials/controlling-near-accounts/2-transfer) into the network over RPC. # Setting up a Near account to be controlled by MPC Source: https://docs.near.org/chain-abstraction/chain-signatures/tutorials/controlling-near-accounts/1-setup Set up a NEAR account to be securely controlled via MPC by deriving a public key and adding it as an access key. One of the powerful features of the NEAR Protocol is its flexible [access keys architecture](/protocol/accounts-contracts/access-keys). An account can hold multiple access keys, each with different levels of permission. This enables us to grant transaction-signing capabilities to an external key without compromising security. To achieve secure external control via MPC, we must derive a valid `secp256k1` public key from the MPC smart contract. This key belongs to a key pair that will be used later in the tutorial for signing transactions securely. Before we proceed, let's create an account on whose behalf we will be acting. ## Creating an account If you already have a NEAR account that you want to control via MPC, feel free to skip this step. Otherwise, use the following command: ```sh theme={"theme":{"light":"github-light","dark":"github-dark"}} near account create-account fund-myself ``` ## Deriving a Public Key from MPC As you already know from the [Chain Signatures documentation](/chain-abstraction/chain-signatures#how-it-works), `derivation_path` is the key component that allows generating multiple distinct key pairs. When combined with `predecessor_id`, it forms a unique and secure pair. In our example, the smart contract acts as a proxy between a user and the MPC, `User Account <-> Contract Proxy <-> Contract Requesting a Signature`, which means the contract itself becomes the `predecessor` in the derivation process: `predecessor: contract_proxy_address`. If the Contract Proxy were deployed directly onto the User Account, `User Account <-> Contract Requesting a Signature`, the User Account would become the `predecessor` in the derivation process: `predecessor: user_account_address`. To understand how `derivation_path` is built, let's examine the [smart contract implementation](https://github.com/nearuaguild/control-near-account-with-mpc-example/blob/97883851483c05d4c9206afb6efeac02ec9c2541/contract/src/lib.rs#L64-L68): ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} let derivation_path = format!( "{}-{}", env::predecessor_account_id().to_string(), args.signer_id.to_string() ); ``` * `args.signer_id` is the account on whose behalf we're acting * `env::predecessor_account_id().to_string()` refers to the account that is calling the contract, please do not confuse it with previously mentioned `predecessor_id` as it refers to the smart contract address Now that we understand how each input is calculated, let's put them together and actually derive a public key. ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} const contractId = "broken-rock.testnet"; // smart contract address const adminAccountId = "admin.testnet"; // signs transactions to act on behalf of `controllableAccountId` const controllableAccountId = "controllable.testnet"; // on whose behalf we'll be acting // admin.testnet-controllable.testnet const derivationPath = `${adminAccountId}-${controllableAccountId}`; // secp256k1:m2CUiQw9f5nN8sAszkHrbok6apRz7j6LkpFZ6vT6zzxLHh2C54udU9Ue7eRy7FRK42pD796nNSwEdsqXzLb96PR const derivedPublicKey = await deriveKey(contractId, derivationPath); ``` ## Adding key to the account Once we have the public key, the final step is to add it to the NEAR account. ```sh theme={"theme":{"light":"github-light","dark":"github-dark"}} near account add-key controllable.testnet grant-full-access use-manually-provided-public-key secp256k1:m2CUiQw9f5nN8sAszkHrbok6apRz7j6LkpFZ6vT6zzxLHh2C54udU9Ue7eRy7FRK42pD796nNSwEdsqXzLb96PR network-config testnet sign-with-legacy-keychain send ``` ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} const path = require("node:path"); const { homedir } = require("node:os"); const { keyStores, connect } = require("near-api-js"); const CREDENTIALS_DIR = ".near-credentials"; const credentialsPath = path.join(homedir(), CREDENTIALS_DIR); const keyStore = new keyStores.UnencryptedFileSystemKeyStore(credentialsPath); const config = { keyStore, networkId: "testnet", nodeUrl: "https://rpc.testnet.near.org", }; const near = await connect(config); const account = await near.account("controllable.testnet"); // uses derivedPublicKey from previous step await account.addKey(derivedPublicKey); ``` In our example, we’ve added this public key as a [**FullAccess key**](/protocol/accounts-contracts/access-keys#full-access-keys), meaning it has full control over the account, this allows us to execute all transactions without limitations. However, it is also possible to add the key as a **FunctionCall access key** with limited permissions. The next step is to create, sign and eventually send a transfer transaction on behalf of `controllable.testnet`. Continue to [the next chapter](/chain-abstraction/chain-signatures/tutorials/controlling-near-accounts/2-transfer) to learn how. # Transfer Near tokens on behalf of a controlled account Source: https://docs.near.org/chain-abstraction/chain-signatures/tutorials/controlling-near-accounts/2-transfer Build transaction arguments, request MPC signatures, and broadcast signed NEAR token transfers securely. In this part of the tutorial, we'll dig into how transaction arguments are built, how to request a signature according to the arguments from the smart contract, and how to broadcast the signed transaction into the network. ## Building transaction arguments Now that we've set up the account and derived the public key, it's time to build the transaction arguments. For a transaction to be valid, we must attach both a `nonce` and a `recent_block_hash` - these values ensure that the transaction is unique and prevent replay attacks. Let's fetch `nonce` first: ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} const accessKey = await near.connection.provider.query({ request_type: "view_access_key", account_id: controllableAccountId, // "controllable.testnet" public_key: derivedPublicKey, // derived in the previous chapter finality: "optimistic", }); const nonce = accessKey.nonce; ``` And `recent_block_hash`, now it's your turn: ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} const block = await near.connection.provider.block({ finality: "final", }); const blockHash = block.header.hash; ``` Now that we have everything needed, let's build transaction arguments: ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} const transactionArgs = { signer_id: controllableAccountId, // "controllable.testnet" signer_pk: derivedPublicKey, // derived in the previous chapter nonce: (nonce + 1).toString(), block_hash: blockHash, }; ``` ## Requesting signature from Smart Contract After building transaction arguments, the next step is to request a signature from the smart contract. ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} const adminAccount = await near.account("admin.testnet"); const outcome = await adminAccount.functionCall({ contractId: contractId, // "broken-rock.testnet" methodName: "transfer_on_behalf_of", args: { args: transactionArgs, }, gas: "300000000000000", attachedDeposit: "100000000000000000000000", // 0.1 NEAR is enough in most cases to pay MPC fee }); ``` ## Broadcasting the transaction With the signature in hand, we are now ready to send it to the network! ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} // Get the signed transaction from the outcome result = providers.getTransactionLastResult(outcome); const signedTx = new Uint8Array(result); // Send the signed transaction const transferOutcome = await near.connection.provider.sendJsonRpc( "broadcast_tx_commit", [Buffer.from(signedTx).toString("base64")] ); console.log( `https://nearblocks.io/txns/${transferOutcome.transaction_outcome.id}` ); ``` ## Final Thoughts With that, we've successfully completed the full journey of acting on behalf of another Near account securely and transferred to yourself 0.1 NEAR from a controllable account. By following this process, you now have a solid understanding of how to manage external accounts on Near using Multi-Party Computation (MPC). # Near Multi-Chain DAO Governance Source: https://docs.near.org/chain-abstraction/chain-signatures/tutorials/multichain-dao/0-intro Learn how Abstract DAO enables a single vote on NEAR to execute actions across multiple EVM chains. Many multi-chain organizations deploy copies of the same smart contract across multiple EVM chains, which need to be kept in sync. Generally, this is tackled by handling multiple DAOs - one per chain - where the same action is voted simultaneously, a process that is not only time-consuming, but also very expensive and error-prone. multi chain flow To solve this, we have built the [Abstract DAO](https://github.com/nearuaguild/abstract-dao), which enables organizations to **vote once** in NEAR, and then **execute the same action** across **multiple chains**. multi chain flow Abstract DAO is an example, and as such it has not been audited, use it at your own risk. *** ### How It Works? The [Abstract DAO](https://github.com/nearuaguild/abstract-dao) acts as an intermediary between NEAR DAOs and the EVM chains. The process of voting and executing an action looks like this: 1. **Craft an EIP-1559 Payload**: You create the transaction that will execute across all chain, specifying the recipient address, nonce, value, and transaction data. Only the gas parameters are not set, as they will vary across chains. 2. **Choose a Single Allowed Account**: As part of the voting process, your organization chooses an "allowed account," which is the member who will be responsible to setup gas parameters, and generate signatures for all the chains. 3. **Vote on the Request**: Your decentralized organization votes once on NEAR to approve this request. Each member can review the transaction, then cast their vote to confirm or reject it. 4. **Generate Signatures**: Once the request has enough confirmations, the transaction is approved. The "allowed account" can now interact with the [Abstract DAO](https://github.com/nearuaguild/abstract-dao) to generate signatures for as many EVM-compatible chains as needed. The result is a drastically simplified governance process (one vote, one confirmation) and the ability to sign and execute transactions across multiple chains in a coordinated manner. **Handling Gas** Since Gas prices can vary widely across chains, the transaction's gas price is not set until the signatures are generated. This means that the "allowed account" will be in charge of setting the gas price for each transaction being signed. *** ## Prerequisites To complete this tutorial successfully, you will need [Near CLI](/tools/cli#installation) to be installed, and have a general understanding of how [Chain Signatures](/chain-abstraction/chain-signatures/getting-started) work. *** ## Next steps Ready to start? Let's jump to the first step, in which we will understand how the Abstract DAO contract works. *** **Versioning for this article** * near-cli: `0.12.0` * rustc: `1.78.0` * cargo: `1.80.1` * cargo-near: `0.6.2` * rustc: `1.78.0` * node: `21.6.1` # Abstract DAO: Requests Source: https://docs.near.org/chain-abstraction/chain-signatures/tutorials/multichain-dao/1-request Learn how to create a signature request in Abstract DAO to execute actions on foreign EVM chains. The Abstract DAO contract works as an intermediary between decentralized organizations in NEAR and EVM networks. To better understand how it works it is better to start by using it by itself, without using a DAO yet. Join us as we explore how to create a request in the Abstract DAO contract, that will be later used to derive signatures for foreign EVM chains. We have deployed the Abstract DAO in two environments: 1. Testnet: `abstract-dao.testnet` 2. Dev (unstable): `dev.abstract-dao.testnet` *** ## Ethereum Function Call Imagine that our organization agreed on changing a value in a simple [counter we deployed on Sepolia Ethereum](https://sepolia.etherscan.io/address/0xe2a01146FFfC8432497ae49A7a6cBa5B9Abd71A3), and now want to leave this intent in the Abstract DAO. For this, we will call the **`register_signature_request`** function on Abstract Dao saying: *We allow **executor.testnet** to request signatures for one of our Ethereum accounts, making it set a counter to `1000`*. Here are the parameters, take a quick glance for now, since we will go over each one of them: ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} { "request": { "derivation_seed_number": 0, "allowed_account_id": "executor.testnet", "transaction_payload": { "to": "0xe2a01146FFfC8432497ae49A7a6cBa5B9Abd71A3", "nonce": "0", "function_data": { "function_abi": { "inputs": [ { "internalType": "uint256", "name": "_num", "type": "uint256" } ], "name": "set", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, "arguments": [ { "Uint": "A97" } ] } }, } } ``` There are 3 arguments in the call above: `derivation_seed_number`, `transaction_payload`, and `allowed_account_id` lets see them in depth. ### Derivation Path The parameter `derivation seed number` will be used to derive which external address we will be requesting signatures from, the address will be derived as: `DAO Address` + `Derivation Path` + `Contract Address` = `EVM Address` For example, if we register a request from the address `...` using the derivation path `0` we will obtain control the `0x...` account. Learn more about derivation paths [here](/chain-abstraction/chain-signatures) ### Transaction Payload The `transaction_payload` contains all the information on the transaction that we want to perform, particularly: * `to`: The recipient address of the transaction * `nonce`: The transaction nonce, used to ensure uniqueness * `function_data`: (optional) Defines the function that will be called on the recipient's contract, including: * `function_abi`: The ABI of the function being called * `arguments`: The input arguments for the function, all ABI encoded (e.g. integers are `base64`) There are a couple important points to notice about this `transaction_payload`: * **Readable Payload:** The parameters make it easy for anyone to quickly understand what transaction will be executed externally. The Abstract DAO is designed to be transparent and easy to audit, abstracting away the complexity of creating the transaction. * **We Are Setting a Nonce:** By setting the nonce, we make sure that the transaction will only be valid once, as future transactions will need higher `nonces` * **We Are Not Setting the GAS:** Gas prices are expected to vary wildly across EVMs, for which it makes no sense to setup a fixed gas amount and gas price for all the networks, for this is that we use the last parameter `allowed_account` ### Allowed Account In this case, the `allowed_account` will be the one in charge of generating the signatures. At the time of generating the signature, the account will also set the `gas_price` for the transaction on a per-chain basis. # Abstract Dao: Signatures Source: https://docs.near.org/chain-abstraction/chain-signatures/tutorials/multichain-dao/2-signing Learn how to sign Abstract DAO requests for different chains and relay them to target EVM networks. In the previous section, we saw how to register a signature request on the Abstract DAO contract. Now, it is time to sign the transaction for different chains and relay it to the target EVM network. *** ## Signing the Transaction To sign a transaction for a specific chain, the allowed account needs to call the `get_signature` function, passing the `request_id` (generated on the previous section) and all the necessary info to finish creating the transaction before signing it. For example, to sign the transaction for the Sepolia Testnet, the following command can be used: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction abstract-dao.testnet get_signature json-args '{ "request_id": 1, "other_payload": { "chain_id": 11155111, "max_fee_per_gas": "1000000000", "max_priority_fee_per_gas": "100000000" } }' prepaid-gas '300.0 Tgas' attached-deposit '0.05 NEAR' sign-as executor.testnet network-config testnet ``` Note that all we are specifying now is the `chain_id` (to identify the destination chain), the `max_fee_per_gas`, and the `max_priority_fee_per_gas` (to set the transaction fee). The account authorized to call `get_signature` - in this case `executor.testnet` cannot change any parameter of the transaction being signed besides setting a gas fee per chain. *** ## Signature Response The signature response is going to look like this: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "big_r": { "signature": { "affine_point": "02D532992B0ECBF67800DB14E04530D9BA55609AD31213CC7ABDB554E8FDA986D3" }, "recovery_id": 1, "s": { "scalar": "40E81711B8174712B9F34B2540EE0F642802387D15543CBFC84211BB04B83AC3" } }, "tx": "0x02f85083aa36a702850485034c878517a4eb0789829dd094e2a01146fffc8432497ae49a7a6cba5b9abd71a380a460fe47b1000000000000000000000000000000000000000000000000000000000000a84bc0" } ``` As we can see, it is not the signed transaction itself, but instead the data we need to reconstruct it. We have created an [script](https://github.com/nearuaguild/multichain-dao-scripts) to automate this process, as well as the relaying to the target EVM network. # MultiSig Voting Source: https://docs.near.org/chain-abstraction/chain-signatures/tutorials/multichain-dao/3-voting Learn how to deploy a MultiSig contract and vote on multi-chain proposals using the Abstract DAO. Now that we understand how the Abstract DAO works, it is time to use it in within an organization. Lets see how to deploy a MultiSig contract, where users will vote on a multi-chain proposal. *** ## Creating a MultiSig Contract As a first step we need to create an account and deploy a MultiSig contract on it, so users can start creating proposals and voting on them. **Deploy Multisig** You can download the [compiled multisig](https://github.com/near/core-contracts/raw/refs/heads/master/multisig2/res/multisig2.wasm) from the near repository ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near create-account --useFaucet near deploy multisig2.wasm ``` See the github repository for instructions on how to [initialize the multisig contract](https://github.com/near/core-contracts/tree/master/multisig2) *** ## Creating a Request on the Multisig Contract To call `register_signature_request` on the Multi-Chain DAO Governance Contract, you need to submit a request through your Multisig contract. This ensures that the decision to generate a signature is confirmed by the necessary members. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction multisignature.testnet add_request json-args '{ "request": { "receiver_id": "abstract-dao.testnet", "actions": [ { "type": "FunctionCall", "method_name": "register_signature_request", "args": { "request": { "allowed_account_id": "executor.testnet", "derivation_seed_number": 0, "transaction_payload": { "to": "0xe2a01146FFfC8432497ae49A7a6cBa5B9Abd71A3", "nonce": "0", "function_data": { "function_abi": { "inputs": [ { "internalType": "uint256", "name": "_num", "type": "uint256" } ], "name": "set", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, "arguments": [ { "Uint": "A97" } ] } } } }, "gas": "100000000000000", "deposit": "0.1" } ] } }' prepaid-gas '100.0 Tgas' attached-deposit '1 yoctoNEAR' sign-as executor.testnet network-config testnet ``` *** ## Voting on the Request Once the request is submitted, members of the multisig contract have a set amount of time to vote to either Confirm or Reject the request. Each member needs to cast their vote using the following command: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction multisignature.testnet confirm json-args '{"request_id": 1}' prepaid-gas '100.0 Tgas' attached-deposit '1 yoctoNEAR' sign-as account.testnet network-config testnet ``` Replace provided `request_id` with value retrieved from the response when creating the request Once the request has received enough confirmations, it will be automatically executed. At this point, the signature request is successfully registered on the Multi-Chain DAO Governance Contract. Now, the allowed account (specified in the request) can generate signatures for the transaction just as we saw in the [previous section](./2-signing). # NEAR Intents Source: https://docs.near.org/chain-abstraction/intents/overview Learn how the intents protocol works NEAR Intents is a multichain transaction protocol where users specify what they want and let third parties compete to provide the best solution. This works for everything from token swaps to pizza delivery, creating a universal marketplace across crypto and traditional services. NEAR Intents Overview Read the official documentation to learn more about NEAR Intents and how to use it *** ## How It Works A user or AI agent expresses a desired outcome *(ex: Swap Token A for Token B)* and broadcasts the intent to network of Market Makers (also called Solvers). An off-chain decentralized network of Market Makers (aka solvers) compete to fulfill the request in the most optimal way. When the network finds the best solution, it presents it as a quote to the originating user/agent for approval. If the quote from the Market Maker is accepted, the intent is executed by calling a "Verifier" smart contract on NEAR Protocol. This contract securely verifies and settles the final transaction. *** ## Resources Read the official documentation to learn more about NEAR Intents. Join the Telegram developer support channel. Explore an easy integration example that uses the 1Click API. Try the live demo application showcasing token swaps. # How Omni Bridge Works Source: https://docs.near.org/chain-abstraction/omnibridge/how-it-works Learn how Omni Bridge uses Chain Signatures to enable cross-chain transfers. The journey toward truly trustless cross-chain communication took a significant leap forward when the NEAR team [created the first trustless bridge with Ethereum](https://near.org/blog/the-rainbow-bridge-is-live) (Rainbow Bridge). This pioneering achievement demonstrated that completely trustless cross-chain communication was possible, marking a crucial step toward the vision of chain abstraction. However, this approach relied on implementing a NEAR light client directly on Ethereum - essentially requiring Ethereum to understand and verify NEAR's complex blockchain rules. Omni Bridge introduces a more elegant solution using Chain Signatures. Instead of running light clients on each destination chain, it leverages Chain Signature's MPC Service to enable secure cross-chain message verification without the overhead of light client verification. This new approach reduces verification times from hours to minutes while significantly reducing gas costs across all supported chains. ### Issues with Light Clients A light client is a smart contract that lets one blockchain verify events happening on another blockchain. In Rainbow Bridge's case, the Ethereum light client needs to track NEAR's blocks, verify its validators' signatures, and confirm transactions. This comes with major technical challenges: it requires storing two weeks of Ethereum block data, maintaining an updated list of NEAR validators and their stakes, and most crucially, verifying NEAR's ED25519 signatures - a process Ethereum wasn't built for. This verification is computationally expensive, making the whole process slow, costly, and ultimately a major bottleneck. For example, with Rainbow Bridge, transactions from NEAR to Ethereum take between 4 and 8 hours due to the 4-hour challenge period and block submission intervals driven by Ethereum's high gas costs. More importantly, this approach becomes increasingly impractical when connecting to multiple chains, as each chain would require its own light client implementation. Some chains, such as Bitcoin, don't even support smart contracts, making it technically impossible to implement a NEAR light client. While we still need to support light clients of different networks on NEAR (which is significantly easier to implement), a different approach is needed for verifying NEAR state on foreign chains. ### Token Standards and Cross-Chain Communication Before exploring how Chain Signatures solves these issues, it's important to understand how tokens work on NEAR. [NEP-141](https://github.com/near/NEPs/tree/master/neps/nep-0141.md), NEAR's fungible token standard, has a key feature that sets it apart from Ethereum's ERC-20: built-in composability through transfer-and-call functionality. When a token transfer happens on NEAR using `ft_transfer_call`, the token contract first transfers the tokens and then automatically calls the specified `ft_on_transfer` method on the receiver contract. While these operations happen in sequence within the same transaction, the receiver contract has the ability to reject the transfer, causing the tokens to be refunded. This atomic behavior ensures the integrity and safety of bridge operations by preventing partial execution states. For more information see [Fungible Tokens](../../primitives/ft/ft). ## Enter Chain Signatures Instead of maintaining complex light clients on destination chains, Chain Signatures introduces a fundamentally different approach based on three core components: 1. **Deterministic Address Derivation** - Every NEAR account can mathematically derive addresses on other chains through derivation paths. This isn't just a mapping - it's a cryptographic derivation that ensures the same NEAR account always controls the same set of addresses across all supported chains. 2. **Bridge Smart Contract** - A central contract on NEAR coordinates with the MPC network to generate secure signatures for cross-chain transactions. This contract handles the token locking and requesting of signatures for outbound transfers 3. **MPC Service** - A decentralized network of nodes that jointly sign transactions without ever reconstructing a full private key. The security comes from threshold cryptography - no single node or small group of nodes can create valid signatures alone. ## Putting It All Together As we've learned, Chain Signatures fundamentally changes the verification mechanism for cross-chain messages. Here's what this means in practice: The light client approach requires destination chains to verify ED25519 signatures from NEAR validators. Chain Signatures replaces this with a single MPC signature verification. Destination chains only need to verify one signature using their native signature verification schemes - typically ECDSA for EVM chains. NEP-141's transaction guarantees handle the security of token locking. A transfer creates two operations within a **single transaction**: 1. Lock tokens and record the transfer state 2. Request MPC signature for the destination chain The Locker contract requests signatures from the MPC network, which then generates signatures for valid transfer requests. This replaces the need for challenge periods - the security derives from the MPC threshold guarantees rather than optimistic assumptions. Adding new chains becomes a matter of implementing three standard components: 1. Chain-specific address derivation 2. MPC signature verification (or transaction signing for chains like Bitcoin) 3. Bridge contract deployment 4. Communication path for transfers back to NEAR (currently using Wormhole for newer chains) While we still need light clients on NEAR for receiving transfers from other chains, this approach makes it feasible to support a wider range of chains without implementing complex verification logic on each destination chain. ```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}} sequenceDiagram title: High-Level Overview of NEAR to External Chain Transfer participant User as User Account participant Bridge as Omni Bridge
Locker Contract participant MPC as MPC Service
(off-chain) participant Other as Destination Chain note over User, Bridge: NEAR Blockchain User->>Bridge:1. Submits transfer
token request Bridge->>Bridge: 2. Locks tokens Bridge->>MPC: 3. Request signature MPC->>MPC: 3. Signs message MPC-->>Bridge: 4. Return signed msg Bridge->>Other: 5. Broadcast signed msg to destination chain Other->>Other: 4. Mint/release tokens ``` To get started building with Omni Bridge, see: * [Bridge SDK JS](https://github.com/near-one/bridge-sdk-js) Omni Bridge implementation in JavaScript * [Bridge SDK Rust](https://github.com/near-one/bridge-sdk-rs) Omni Bridge implementation in Rust # Implementation Details Source: https://docs.near.org/chain-abstraction/omnibridge/implementation Explore Omni Bridge's technical architecture The Omni Bridge is a sophisticated cross-chain bridge infrastructure that enables secure and efficient token transfers between NEAR Protocol and various other blockchain networks. This document provides a detailed technical overview of the bridge's architecture, covering its core components, security model, and operational mechanisms. By leveraging a combination of Multi-Party Computation (MPC), chain-specific light clients, and a permissionless relayer network, the bridge achieves a robust balance of security, decentralization, and user experience. For reference code implementations, see: * [Bridge SDK JS](https://github.com/near-one/bridge-sdk-js) Omni Bridge implementation in JavaScript * [Bridge SDK Rust](https://github.com/near-one/bridge-sdk-rs) Omni Bridge implementation in Rust *** ## The Bridge Token Factory Pattern At the core of Omni Bridge is the Bridge Token Factory contract on NEAR that serves as both a token factory and custodian. This unified contract handles both native tokens from the source chain and bridged tokens created by the factory itself. This design simplifies maintenance and reduces complexity compared to having separate contracts. The contract has several key responsibilities: ### For bridged tokens (tokens originally from other chains): * Deploys new token contracts when bridging tokens for the first time * Mints tokens when receiving valid transfer messages * Burns tokens when initiating transfers back to the origin chain ### For native NEAR tokens: * Acts as a custodian by locking tokens during transfers * Releases tokens when receiving valid transfer messages * Manages token operations through the NEP-141 standard ### Transfer Lifecycle A transfer's lifecycle includes several states, shown below for a NEAR to Ethereum transfer of native NEAR tokens: ```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}} stateDiagram-v2 [*] --> Initiated: User calls transfer Initiated --> Locked: Tokens locked in bridge Locked --> Signed: MPC signature generated Signed --> Completed: Tokens released on Ethereum Completed --> [*] ``` *** ## Message Signing and Verification For most chains, the bridge uses a payload-based message signing system (with Bitcoin being a notable exception requiring full transaction signing). ### Message Types The bridge supports several types of signed messages: * **Transfer Messages** * Initiation messages * Finalization messages * **Token Messages** * Deployment messages * Metadata update messages ### Payload Structure Messages are encoded using Borsh serialization and contain: | Component | Description | | -------------- | ----------------------------------- | | Message Type | Identifier for the message category | | Chain Info | Chain IDs and relevant addresses | | Operation Data | Amounts, recipients, fees, etc. | ### Signature Process 1. NEAR contract creates and stores the message payload 2. MPC network observers detect valid payloads 3. Nodes jointly sign the payload 4. Signature is verified on destination chains **Key Benefits** * Clearer message intent through structured payloads * More efficient signature verification on destination chains * Standardized message format across chains ## Transaction Flow: NEAR to Other Chains Here's an overview of how transfers are processed from NEAR to different destination chains: ```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}} flowchart TD Start[User Initiates Transfer] --> TokenCheck{Token Type?} TokenCheck -->|NEAR Native| Lock[Lock in Bridge Contract] TokenCheck -->|Bridged Token| Burn[Burn Token] Lock --> MPCSign[Request MPC Signature] Burn --> MPCSign MPCSign --> Chain{Destination Chain} Chain -->|Bitcoin| BTCBridge[Bitcoin Script] Chain -->|Other| OtherBridge[Verify MPC Signature] BTCBridge --> Mint[Mint/Release Tokens] OtherBridge --> Mint Mint --> End[Transfer Complete] ``` ### Transfer Process Let's follow what happens when a user wants to transfer tokens from NEAR to another chain: #### 1. Initiation The user starts by calling the token contract with: * Amount to transfer * Destination chain and address * Fee preferences (whether to pay fees in the token being transferred or in NEAR) * Fees are minted on NEAR side for relayers #### 2. Token Lock The token contract transfers tokens to the locker contract, which: * Validates the transfer message * Assigns a unique nonce * Records the pending transfer * Emits a transfer event #### 3. MPC Signing The bridge contract: * Requests signature generation * MPC nodes jointly generate and aggregate signature * Maintains threshold security throughout process #### 4. Destination Chain The Bridge Token Factory on the destination chain: * Verifies the MPC signature * Mints equivalent tokens *** ## Transaction Flow: Other Chains to NEAR The reverse flow varies based on the source chain: ### 1. Ethereum Uses NEAR light client for maximum security: * Burning tokens on source chain * Submitting proof to NEAR * Verifying proof through light client * Releasing tokens to recipient ### 2. Supported Non-EVM Chains (e.g., Solana) Utilize established message passing protocols (such as Wormhole) for: * Message passing between chains * Transaction verification * Integration with NEAR token factory system ### 3. Other EVM Chains Utilize a combination of light clients (where efficient) and message passing protocols to ensure secure verification of inbound transfers. *** ## Transaction Flow: Chain to Chain (via NEAR) For transfers between two non-NEAR chains (e.g., Ethereum to Solana), the bridge combines both flows using NEAR as an intermediary routing layer. Rather than minting or unlocking tokens on NEAR, the bridge creates a forwarding message that directs tokens to be minted or unlocked on the final destination chain. From the user's perspective, this appears as a single operation - they initiate the transfer on the source chain, and the off-chain relayer infrastructure handles the intermediate NEAR routing automatically. *** ## Security Model ### Trust Assumptions Omni Bridge requires different trust assumptions depending on the chain connection: #### For Chain Signatures: * NEAR Protocol security (2/3+ honest validators) * MPC network security (2/3+ honest nodes) * No single entity controls enough MPC nodes to forge signatures * Correct implementation of the signing protocol #### For Ethereum/Bitcoin connections: * Light client security * Finality assumptions (e.g., sufficient block confirmations) * Chain-specific consensus assumptions #### For Message Passing connections: * Security of the underlying message passing protocol (e.g., Wormhole Guardian network) * Verified by NEAR network participants (e.g., validators and full nodes) *** ## Relayer Network Relayers are permissionless infrastructure operators who monitor for bridge events and execute cross-chain transactions. Unlike many bridge designs, our relayers cannot: * Forge transfers * Steal funds * Censor transactions (users can self-relay) * Front-run transactions for profit * Do not create additional security assumptions The relayer's role is purely operational - executing valid transfers and collecting predetermined fees. Multiple relayers can operate simultaneously, creating competition for faster execution and lower fees. *** ## Fast Transfers Standard cross-chain transfers can take time due to finality and verification requirements. **Fast Transfers** allow relayers to expedite this process by fronting liquidity. ### How it Works 1. **User Initiation:** A user sends a `FastFinTransferMsg` specifying the destination and fee. 2. **Relayer Execution:** A relayer detects the request and instantly transfers the equivalent amount (minus fees) to the user on the destination chain from their own funds. 3. **Settlement:** The bridge later reimburses the relayer once the original transfer is fully verified and finalized. Fast transfers are ideal for users who prioritize speed over cost, as relayers may charge a premium for the liquidity and convenience. *** ## Multi-Token Support (ERC1155) Omni Bridge supports the **ERC1155** standard, enabling the transfer of multiple token types within a single contract. ### Address Derivation To maintain consistency across chains, bridged ERC1155 tokens use a deterministic address derivation scheme: * **Deterministic Address:** `keccak256(tokenAddress + tokenId)` * This ensures that each `tokenId` within an ERC1155 contract maps to a unique, consistent address on the destination chain. ### Key Functions * **`initTransfer1155`**: Initiates a transfer for a specific ERC1155 token ID. * **`logMetadata1155`**: Registers metadata for a specific token ID, ensuring it is recognized by indexers and wallets. *** ## Fee Structure Bridge fees are unified and processed on NEAR, with components including: ### Execution Fees * Destination chain gas costs * Source chain storage costs * Relayer operational costs * MPC signing costs ### Fee Payment Options * Native tokens of source chain * The token being transferred Fees dynamically adjust based on gas prices across different chains to ensure reliable execution. ### Design Goals The fee structure is designed to: * Ensure relayer economic viability * Prevent economic attacks * Allow fee market competition * Cover worst-case execution costs Users can bypass relayers entirely by executing their own transfers, paying only the necessary gas fees on each chain. This creates a natural ceiling on relayer fees. # Omni Bridge Overview Source: https://docs.near.org/chain-abstraction/omnibridge/overview Learn about Omni Bridge, a multi-chain asset bridge that enables secure and efficient transfers between blockchain networks using Chain Signatures and MPC technology. The [Omni Bridge](https://github.com/Near-One/omni-bridge) is a multi-chain asset bridge that facilitates secure and efficient asset transfers between different blockchain networks. It solves key challenges in cross-chain communication by leveraging [Chain Signatures](/chain-abstraction/chain-signatures) and its decentralized [Multi-Party Computation (MPC) service](/chain-abstraction/chain-signatures#multi-party-computation-service) to enable trustless cross-chain asset transfers. To learn more see [How Omni Bridge Works](./how-it-works). ## Supported Chains Omni Bridge launches with a hybrid architecture, utilizing different verification methods based on chain-specific requirements and technical constraints. This approach allows us to support multiple chains from day one while progressively transitioning to full Chain Signatures integration. Currently the supported chains are: * **Ethereum** - *(Light client + Chain Signatures)* * **Bitcoin** - *(Light client + Chain Signatures)* * **Solana** - *(Wormhole + Chain Signatures)* * **Base** - *(Wormhole + Chain Signatures)* * **BNB** - *(Wormhole + Chain Signatures)* * **Arbitrum** - *(Wormhole + Chain Signatures)* See [Omni Bridge Roadmap](./roadmap) for more details. ## Resources * [Near-One/omni-bridge](https://github.com/Near-One/omni-bridge) - Omni Bridge repository * [Near-One/bridge-sdk-js](https://github.com/Near-One/bridge-sdk-js) - JavaScript SDK * [Near-One/bridge-sdk-rs](https://github.com/Near-One/bridge-sdk-rs) - Rust SDK # Omni Bridge Roadmap Source: https://docs.near.org/chain-abstraction/omnibridge/roadmap Explore the Omni Bridge roadmap, including hybrid architecture launch, Chain Signatures migration path, and future development plans for cross-chain infrastructure. Omni Bridge launches with a hybrid architecture, utilizing different verification methods based on chain-specific requirements and technical constraints. This approach allows us to support multiple chains from day one while progressively transitioning to full Chain Signatures integration. ## Supported Chains The bridge currently supports the following networks: * **EVM Chains:** * Ethereum * Base * Arbitrum * BNB Chain * Polygon (PoS) * **Non-EVM Chains:** * Bitcoin * Solana * Zcash ## Architecture Overview Omni Bridge utilizes **Chain Signatures** as its primary verification mechanism for outbound transfers from NEAR. Incoming transfers rely on chain-specific verification methods, including light clients for maximum security where available. ### Verification Methods * **Ethereum & Bitcoin:** Light Client verification for inbound transfers. * **Other Chains:** Message passing protocols verified by the NEAR network. * **Outbound (All Chains):** Chain Signatures (MPC) for secure transaction signing. ## Future Development 1. **Protocol Improvements** * Enhanced fee mechanisms * Cross-chain contract calls * New token standards support Beyond basic asset transfers, we're expanding the bridge's capabilities. Enhanced fee mechanisms will better handle gas price volatility, while cross-chain contract calls will enable more complex interactions. 2. **Infrastructure** * Expanded relayer network * Improved monitoring tools * Enhanced developer tooling Infrastructure development focuses on reliability and usability. An expanded relayer network improves transfer speeds and reliability, while better monitoring and developer tools make integration and maintenance easier. ## Get Involved ### Areas for Contribution * Chain integrations * Performance optimization * Security analysis * Developer tools * [Near-One/omni-bridge](https://github.com/Near-One/omni-bridge) - Omni Bridge repository * [Near-One/bridge-sdk-js](https://github.com/Near-One/bridge-sdk-js) - JavaScript SDK * [Near-One/bridge-sdk-rs](https://github.com/Near-One/bridge-sdk-rs) - Rust SDK and Bridge CLI The code is open source and we welcome contributions from the community. Whether you're interested in adding support for new chains, optimizing performance, or building developer tools, there's room for meaningful contribution. Bridge infrastructure is a fundamental component of a multi-chain future. Through Chain Signatures, we're creating a more efficient, secure, and scalable approach to cross-chain communication. Join us in building it. # What is Chain Abstraction? Source: https://docs.near.org/chain-abstraction/what-is Learn how NEAR allows you to seamlessly work across all chains Through a combination of innovative technologies, NEAR enables developers to build applications that work seamlessly across multiple blockchains while abstracting away the underlying complexity for both developers and end users. Chain Signatures allow NEAR accounts **and smart contracts** to sign transactions for all other chains (including Bitcoin, Ethereum and Solana) A decentralized system where users simply **express desired outcomes** (like "swap BTC for ETH at the best price"), and a network of solvers competes to fulfill these intents optimally A multi-chain bridge that enables secure and efficient cross-chain transfers. The bridge serves as both a token factory and custodian, managing native and bridged tokens through a unified interface *** ## Why Chain Abstraction Matters By building on NEAR, developers do not need to worry about the complexities of integrating with multiple blockchains. Instead, they can focus on building great applications that work seamlessly across all chains. Meanwhile, users can enjoy a smooth experience, using unified accounts and assets without needing to even understand on which blockchain they are operating. * Integrate with multiple blockchains through a single NEAR API * Focus on application logic instead of blockchain complexity * Reach users regardless of their preferred blockchain network * Operate across all chains using a single NEAR account * Access assets and services from multiple blockchains seamlessly * Enjoy a unified and intuitive user experience Imagine building a digital art marketplace where users can purchase NFTs from different blockchains (Ethereum, Solana, etc.). Without chain abstraction, you'd need to: * Implement multiple blockchain connections * Handle different wallet types * Manage cross-chain transfers * Build complex UIs to explain blockchain concepts With chain abstraction, both you and your users just focus on the core experience: browsing and trading art. All blockchain complexity is handled automatically behind the scenes. # Communities Source: https://docs.near.org/communities Connect with the NEAR community through various channels and join specialized communities. NEAR is a global community of Web3 enthusiasts and innovators. Connect with developers, builders, and founders across our social channels. *** ## Frequently Asked Questions Upon submitting a support ticket, you can expect to receive an initial response from our team within 72 hours during our business hours. Our business hours are on weekdays in the PST timezone, excluding US holidays. Social channels such as [Telegram](https://t.me/neardev) and [Discord](https://discord.gg/RhZGHPXPf2) are a great resource to tap into for community support on development issues. You can find information on grants and funding opportunities on the [main NEAR portal](https://www.near.org/funding). Follow [NEAR on X](https://twitter.com/nearprotocol) for our latest product announcements or subscribe to [NEAR Week](https://subscribe.nearweek.com/) to receive their weekly newsletter on ecosystem announcements. For any issues or concerns you've encountered, please feel free to provide us with detailed information through our [Bug Bounty Program](https://hackenproof.com/near). Your cooperation and additional details will assist us in addressing and resolving any potential vulnerabilities effectively. We appreciate your proactive approach in helping us maintain the security and integrity of the NEAR ecosystem. As we embrace a more decentralized future, wallet.near.org will be discontinued. This change invites you to discover a variety of new and secure wallet options within our ecosystem. Your funds are safe! Accounts exist on the blockchain, not in a wallet. Wallets are just an interface into using the blockchain with your account. [Learn more](https://wallet.near.org/) For issues relating to a third-party exchange, such as Binance or Coinbase, we're unable to investigate issues on external platforms. To address your concern effectively, we recommend contacting the customer support team of the specific exchange where you're experiencing issues. They are most equipped to assist you in resolving the matter. # BigQuery Public Dataset Source: https://docs.near.org/data-infrastructure/big-query Learn how to use NEAR Protocol's BigQuery public dataset for blockchain data analysis, including querying on-chain data, understanding costs, and accessing historical transaction data. This document provides an overview of the BigQuery public dataset that allows users to query historical on-chain data from the NEAR Protocol. It includes setup instructions, example queries, and information about the available data structures. # NEAR Public Lakehouse Blockchain data indexing in NEAR Public Lakehouse is for anyone wanting to understand blockchain data. This includes: * **Users**: create queries to track NEAR assets, monitor transactions, or analyze on-chain events at a massive scale. * **Researchers**: use indexed data for data science tasks, including on-chain activities, identifying trends, or feeding AI/ML pipelines for predictive analysis. * **Startups**: can use NEAR's indexed data for deep insights on user engagement, smart contract utilization, or insights across tokens and NFT adoption. Benefits: * **NEAR instant insights**: Historical on-chain data queried at scale. * **Cost-effective**: eliminate the need to store and process bulk NEAR protocol data; query as little or as much data as preferred. * **Easy to use**: no prior experience with blockchain technology is required; bring a general knowledge of SQL to unlock insights. ## Getting started 1. Login into your [Google Cloud Account](https://console.cloud.google.com/). 2. Open the [NEAR Protocol BigQuery Public Dataset](https://console.cloud.google.com/bigquery?p=bigquery-public-data\&d=crypto_near_mainnet_us\&page=dataset). 3. Click in the VIEW DATASET button. 4. Click in the + to create a new tab and write your query, click in the RUN button, and check the `Query results` below the query. 5. Done :) The [NEAR Public Lakehouse repository](https://github.com/near/near-public-lakehouse) contains the source code for ingesting NEAR Protocol data stored as JSON files in AWS S3 by [NEAR Lake Indexer](https://github.com/near/near-lake-indexer). **NEAR Lake (the AWS S3 source) was deprecated on March 24, 2026** and no longer indexes new blocks. The NEAR Public Lakehouse / BigQuery dataset itself remains available; check the [NEAR Public Lakehouse repository](https://github.com/near/near-public-lakehouse) for the latest ingestion source. ### Example Queries * *How many unique signers and accounts have interacted with my smart contract per day?* ```sql theme={"theme":{"light":"github-light","dark":"github-dark"}} SELECT ra.block_date collected_for_day, COUNT(DISTINCT t.signer_account_id) as total_signers, COUNT(DISTINCT ra.receipt_predecessor_account_id) as total_accounts FROM `bigquery-public-data.crypto_near_mainnet_us.receipt_actions` ra JOIN `bigquery-public-data.crypto_near_mainnet_us.receipt_origin_transaction` ro ON ro.receipt_id = ra.receipt_id JOIN `bigquery-public-data.crypto_near_mainnet_us.transactions` t ON ro.originated_from_transaction_hash = t.transaction_hash WHERE ra.action_kind = 'FUNCTION_CALL' AND ra.receipt_receiver_account_id = 'social.near' -- change to your contract GROUP BY 1 ORDER BY 1 DESC; ``` ## How much it costs? * NEAR pays for the storage and doesn't charge you to use the public dataset. > To learn more about BigQuery public datasets [check this page](https://cloud.google.com/bigquery/public-data). * Google GCP charges for the queries that you perform on the data. For example, in today's price "Sep 1st, 2023" the On-demand (per TB) query pricing is \$6.25 per TB where the first 1 TB per month is free. > Check [Google's pricing page](https://cloud.google.com/bigquery/pricing#analysis_pricing_models) for detailed pricing info, options, and best practices. You can check how much data it will query before running it in the BigQuery console UI. Again, since BigQuery uses a columnar data structure and partitions, it's recommended to select only the columns and partitions (`block_date`) needed to avoid unnecessary query costs. Query Costs ## Architecture The data is loaded in a streaming fashion using [Databricks Autoloader](https://docs.gcp.databricks.com/ingestion/auto-loader/index.html) into raw/bronze tables, and transformed with [Databricks Delta Live Tables](https://www.databricks.com/product/delta-live-tables) streaming jobs into cleaned/enriched/silver tables. The silver tables are also copied into the [GCP BigQuery Public Dataset](https://cloud.google.com/bigquery/public-data). Architecture [Databricks Medallion Architecture](https://www.databricks.com/glossary/medallion-architecture). ## Available Data The current data that NEAR is providing was inspired by [NEAR Indexer for Explorer](https://github.com/near/near-indexer-for-explorer/). NEAR plans to improve the data available in the NEAR Public Lakehouse making it easier to consume by denormalizing some tables. The tables available in the NEAR Public Lakehouse are: * **blocks**: A structure that represents an entire block in the NEAR blockchain. `Block` is the main entity in NEAR Protocol blockchain. Blocks are produced in NEAR Protocol every second. * **chunks**: A structure that represents a chunk in the NEAR blockchain. `Chunk` of a `Block` is a part of a `Block` from a `Shard`. The collection of `Chunks` of the `Block` forms the NEAR Protocol Block. `Chunk` contains all the structures that make the `Block`: `Transactions`, [`Receipts`](https://nomicon.io/RuntimeSpec/Receipts), and `Chunk Header`. * **transactions**: `Transaction` is the main way of interaction between a user and a blockchain. Transaction contains: Signer account ID, Receiver account ID, and Actions. * **execution\_outcomes**: Execution outcome is the result of execution of `Transaction` or `Receipt`. In the result of the Transaction execution will always be a Receipt. * **receipt\_details**: All cross-contract (we assume that each account lives in its own shard) communication in Near happens through Receipts. Receipts are stateful in a sense that they serve not only as messages between accounts but also can be stored in the account storage to await `DataReceipts`. Each receipt has a `predecessor_id` (who sent it) and `receiver_id` the current account. * **receipt\_origin**: Tracks the transaction that originated the receipt. * **receipt\_actions**: Action Receipt represents a request to apply actions on the `receiver_id` side. It could be derived as a result of a `Transaction` execution or another `ACTION` Receipt processing. Action kind can be: `ADD_KEY`, `CREATE_ACCOUNT`, `DELEGATE_ACTION`, `DELETE_ACCOUNT`, `DELETE_KEY`, `DEPLOY_CONTRACT`, `FUNCTION_CALL`, `STAKE`, `TRANSFER`. * **receipts (view)**: It's recommended to select only the columns and partitions (`block_date`) needed to avoid unnecessary query costs. This view join the receipt details, the transaction that originated the receipt and the receipt execution outcome. * **account\_changes**: Each account has an associated state where it stores its metadata and all the contract-related data (contract's code + storage). **Additional information about the data** * Skipped Blocks: NEAR Blockchain can contain skipped blocks, e.g. block `57730443`. For these cases we can find the block for the chunk data using the `prev_block_hash` column, e.g. `SELECT * FROM chunks c JOIN blocks b ON c.chunk.header.prev_block_hash = b.header.prev_hash`. **References** * [Protocol documentation](/getting-started/what-is-near) * [Near Data flow](/protocol/data-flow/near-data-flow) * [Protocol specification](https://nomicon.io/) # Data APIs Source: https://docs.near.org/data-infrastructure/data-api Explore community-built APIs for accessing on-chain data If you are building a decentralized applications, chances are that you will need to query on-chain data. Since building a full indexer is not always feasible, the community has created a set of APIs that you can use to query data from the NEAR blockchain. These APIs provide a simple way to access on-chain data without having to run your own indexer or node. They are designed to be easy to use and provide a wide range of functionality, from querying account balances to exploring transactions and blocks. *** ## FastNEAR API The [FastNEAR API](https://github.com/fastnear/fastnear-api-server-rs?tab=readme-ov-file#api-v1) allows to easily query the NEAR blockchain to get an account's assets, map keys into account IDs, explore a block's transactions, etc. Possible use cases include: * Querying all assets of an account (including fungible and non-fungible tokens) * Querying the last block produced * Mapping Public Key to Account ID * Mapping Full Access Public Key to Account ID * Knowing a user's staking pools (validators) * Querying the top holders of a token
#### Examples ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} # Query user's FTs curl https://api.fastnear.com/v1/account/root.near/ft # Query user's NFTs curl https://api.fastnear.com/v1/account/root.near/nft # Query all user's assets curl https://api.fastnear.com/v1/account/root.near/full ``` *** ## NearBlocks API [NearBlocks API](https://api.nearblocks.io/api-docs/) provides an endpoint to query actions that happened on a NEAR account, possible use cases include: * Query an account balance * Query all function calls to specific contract * Get total NEAR supply and circulating supply * Query the number of total transactions on NEAR
#### Examples ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} # All the transactions where somebody called `create_drop` on Keypom curl -X GET "https://api.nearblocks.io/v1/account/v2.keypom.near/txns?method=create_drop" # All the times that `gagdiez.near` called `create_drop` on Keypom curl -X GET "https://api.nearblocks.io/v1/account/v2.keypom.near/txns?method=create_drop&from=gagdiez.near" ``` *** ## Pikespeak API The [Pikespeak API](https://doc.pikespeak.ai/) allows you to fetch blockchain events and aggregated analytics on wallets, validators, delegators, money transfers, dApps activity, and more. Use case includes: * Querying account balances * Querying the most active wallets * Querying historic account events *To access the Pikespeak API you'll need to [register and create an account](https://pikespeak.ai/plans). Once you're registered, under the [`My Account`](https://pikespeak.ai/myaccount) page you can get your API key*
#### Examples ```sh theme={"theme":{"light":"github-light","dark":"github-dark"}} # Check the account balance for `root.near`: curl -X GET https://api.pikespeak.ai/account/balance/root.near -H "accept: application/json" -H "x-api-key: YOUR-PIKESPEAK-API-KEY" # Most active wallets NEAR senders curl -X GET https://api.pikespeak.ai/hot-wallets/near -H "accept: application/json" -H "x-api-key: YOUR-PIKESPEAK-API-KEY" # Get historic account events for `keypom.near` curl -X GET https://api.pikespeak.ai/event-historic/keypom.near -H "accept: application/json" -H "x-api-key: YOUR-PIKESPEAK-API-KEY" ``` *** ## The Graph [The Graph](https://thegraph.com/docs/en/cookbook/near/) gives developers tools to process blockchain events and make the resulting data easily available via a GraphQL API, known individually as a subgraph. [Graph Node](https://github.com/graphprotocol/graph-node) is now able to process NEAR events, which means that NEAR developers can now build subgraphs to index their smart contracts. *** ## SubQuery [SubQuery](https://academy.subquery.network/quickstart/quickstart_chains/near.html): A fast, flexible, and reliable open-source data indexer that provides you with custom APIs for your web3 project across NEAR and many other chains # Data Services Source: https://docs.near.org/data-infrastructure/data-services Indexers are constantly listening for transactions and storing them so they can be easily queried. Data Services are constantly listening to the blockchain, processing the transactions and storing them in a database that can be easily queried. You can use them to access blockchain data efficiently: * [Neardata](https://neardata.xyz): a direct, drop-in replacement for NEAR Lake providing a stream of blocks for your custom indexer. * [BigQuery](./big-query): Blockchain data indexing in NEAR Public Lakehouse is for anyone wanting to understand blockchain data. * [Indexer.xyz Multichain Indexer](https://indexer.xyz/): Indexer.xyz is an application layer that you can build your NFT or DeFi applications entirely on top of. In addition to raw transaction indexing, Indexer.xyz provides you with a standardized GraphQL API layer to easily tap into transactions across contracts and chains. * [The Graph](https://thegraph.com/docs/en/cookbook/near/): development tools to process blockchain events and make the resulting data easily available via a GraphQL API, known individually as a subgraph. [Graph Node](https://github.com/graphprotocol/graph-node) is able to process NEAR events, which means that NEAR developers can build subgraphs to index their smart contracts. * [GetBlock](https://getblock.io/explorers/near/blocks/): developer tools offering a simple and reliable API access for historical data streams and other services for NEAR. * [Community APIs](./data-api): build precise & reliable dApps with our community's APIs. * [Covalent](https://www.covalenthq.com/docs/networks/aurora/): for [Aurora EVM](https://aurora.dev/) indexing, Covalent provides a unified API bringing visibility to billions of Web3 data points. * [NEAR Indexer Framework](https://github.com/near/nearcore/tree/master/chain/indexer): a micro-framework providing you with a "live" stream of blocks. Useful to handle on-chain real-time `events`. * [SubQuery](https://academy.subquery.network/quickstart/quickstart_chains/near.html): is an end to end multi-blockchain indexing solution that provides NEAR developers with fast, flexible, universal, open source and decentralized APIs for web3 projects. The [NEAR starter project](https://github.com/subquery/near-subql-starter/tree/main/Near/near-starter) provides a template for developers to get up and running within minutes. * [GoldSky](https://docs.goldsky.com/chains/near): a hosted data platform that supports NEAR mainnet via **Mirror** (real-time data replication into your own infrastructure) and **Turbo** (high-performance streaming pipelines with sub-second latency). No infrastructure to manage — connect your data destination and start streaming on-chain data immediately. * NEAR Lake Framework (**deprecated**): a companion library to NEAR Lake. It allows you to build your own indexer that watches a stream of blocks **from a NEAR Lake data source**. **NEAR Lake deprecated as of March 24, 2026.** The NEAR Lake (AWS S3 buckets) has stopped indexing new blocks. For new projects, use [Neardata](https://neardata.xyz) (direct replacement for NEAR Lake), [Data APIs](./data-api), [Goldsky](https://goldsky.com), or the [Nearcore Indexer](./near-indexer). # Introduction to Indexers Source: https://docs.near.org/data-infrastructure/indexers Learn about blockchain indexers, how they work with NEAR Protocol, the difference between pull and push models, and when to use indexers for data querying. Here you will find everything you need to know in order to familiarize yourself with the concept of indexers. We recommend checking the [NEAR Data Flow](../protocol/data-flow/near-data-flow) to familiarize yourself with how data flows within the NEAR ecosystem *** ## Blockchains and their nature Blockchain data is optimized for serialized **writes**, one block at a time, as the chain is being created. Querying the blockchain for data about a specific block or account is fairly straightforward, as only the data for a specific block needs to be retrieved. However, querying data across many blocks (e.g. `all transfers between date X and Y`) can be cumbersome because we have to aggregate results from multiple single-block queries. Given the fact that a blockchain itself is a distributed database, and a smart contract (decentralized application, dApp) is an application that runs on a virtual machine inside a blockchain, we need to understand that smart contracts should *not* be considered as a "backend". While some applications might consist only of smart contracts, building a dApp with only smart contracts, in most cases, is not possible. Smart contracts are limited in terms of interactions. By "interactions" we mean things that are very common in the real world, like user notifications, integration with third-party applications, etc. However, the nature of a blockchain is that it *must* be deterministic. A critical feature of a blockchain is that it knows the state at a given time, and for blockchains that time unit is a block. Think of them as being snapshots. A blockchain does snapshots of its state on every block. We as users can call smart contracts for a specific block, and the blockchain provides guarantees that execution will always produce the same result for the same block any time we call it. The deterministic nature of a blockchain closes it from external (off-chain) variables. It is totally impossible to perform a call to an API from within a smart contract. A blockchain and a smart contract are closed off from the external (off-chain) world. Blockchain closed from outer world Blockchains are great at providing a way to apply the requested changes to the state in a decentralized manner. However, in order to observe the changes, you need to actively pull the information from the network. Instead of abstract explanations let's look at an example. **Example dApp** Say, we have a smart contract that sells e-books. Once a user buys a book we want to send them a copy via email. The dApp has a helper deployed somewhere off-chain, and this helper has code that can send an email with a copy of an e-book. But how would we trigger the helper? *** ## Getting the data from a blockchain from the external world NEAR blockchain implements a [JSON-RPC endpoint](/api/rpc/introduction) for everyone to interact with the blockchain. Through the JSON-RPC API users can call smart contracts triggering them to be executed with given parameters. Also, users can view the data from the blockchain. So, continuing with our example we can make our helper pull a [Block](/api/rpc/block-chunk#block-details) every second, then pull all the [Chunks](/api/rpc/block-chunk#chunk-details) and analyze the Transactions included in the Block to check if there is a transaction to our smart contract with "buy an e-book" function call. If we observe such a Transaction, we need to ensure it is successful, so we don't send the e-book to a user whose "buy e-book" Transaction failed. After the process is complete we can trigger the helper's code to send the user an email with the e-book they bought. This approach is so-called *pull model* of getting the data. There is nothing wrong with this approach, but sometimes you might find it is not the most comfortable or reliable approach. Also, not all the data is available through the JSON-RPC. *Local Receipts* for example are not available through the JSON-RPC, because they are not stored in NEAR node's internal database. *** ## Indexer A blockchain indexer is an implementation of the *push model* of getting the data. Instead of actively pulling the data from the source, your helper waits for the data to be sent to it. The data is complete and so the helper can start analyzing it immediately; ideally the data is complete enough to avoid additional pulls to get more details. Getting back to our example, the helper becomes **an indexer** that receives every *Block*, along with **Chunks**, **Transactions** with its statuses, etc. In the same way the helper analyzes the data and triggers the code to send the user an email with the e-book they bought. Indexer is streaming the data from the blockchain **An indexer concept** An indexer listens to the *stream of data as it's being written on chain* and can then be immediately filtered and processed to detect interesting events or patterns. *** ## Indexers and "wide" queries The term *"wide" queries* was mentioned in the beginning of this document. Here's a recap: **"Wide" queries definition** To query data across many blocks requires the aggregation of results from multiple single-block queries. We can consider these aggregates as coming from *"wide" queries*. Because indexers listen to the *stream of data* from the blockchain and the data can be immediately filtered and processed according to defined requirements, they can be used to simplify the "wide" queries execution. For example, a stream of data can be written to a permanent database for later data analysis using a convenient query language like SQL. Another example that highlights the need for a "wide query" is when you use a seed phrase to recover one or more accounts. Since a seed phrase essentially represents a signing key pair, the recovery is for all accounts that share the associated public key. Therefore, when a seed phrase is used to recover an account via [NEAR Wallet](https://wallet.near.org), the query requires that all accounts with a matching public key are found and recovered. Utilizing [Near Lake Framework](https://github.com/near/near-lake-framework-rs) can be used to store this data in a permanent database and this allows [NEAR Wallet](https://wallet.near.org) to perform such "wide queries". This is impossible to achieve using JSON-RPC only. *** ## Indexers in the NEAR ecosystem **NEAR Lake deprecated as of March 24, 2026.** The NEAR Lake (AWS S3 buckets) has stopped indexing new blocks. For new projects, prefer [Neardata](https://neardata.xyz) (direct replacement), [Data APIs](./data-api), [Goldsky](https://goldsky.com), or the [Nearcore Indexer](./near-indexer). If you are ready to host your own indexer, we recommend using [Neardata](https://neardata.xyz) — it is the direct replacement for NEAR Lake and provides a similar streaming API. If speed is critical for your indexing needs, consider using [Near Indexer](./near-indexer). However, please note that maintaining it can be more complex and costly, as it essentially operates as an independent node in the network. If you prefer not to host your own solution, you can utilize [third-party services](./data-services). *** ## Summary We hope this article gives you an understanding of the Indexer concept. Also, we hope now you can easily decide whether you need an indexer for your application. *** ## What's next? You can learn more about the [Lake Indexer project](./lake-framework/near-lake) (note: deprecated since March 24, 2026). For new projects, see [Neardata](https://neardata.xyz) and the [Tutorials](/data-infrastructure/tutorials/near-lake-state-changes-indexer) section to learn how to build an indexer in 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, Pikespeak, SubQuery, and GoldSky) under [indexing tools](./data-services). # What is NEAR Indexer? Source: https://docs.near.org/data-infrastructure/near-indexer A framework to handle real-time events on the blockchain As scaling dApps enter NEAR’s mainnet, an issue may arise: how do they quickly and efficiently access state from our deployed smart contracts, and cut out the cruft? Contracts may grow to have complex data structures and querying the network RPC may not be the optimal way to access state data. The [NEAR Indexer](https://github.com/near/nearcore/tree/master/chain/indexer) is a micro-framework specifically designed to handle real-time events on the blockchain, allowing to capture and index streams of blocks in a customized manner. With the NEAR Indexer, developers can perform both high-level data aggregation and low-level introspection of blockchain events. For those searching to not build their own indexer, [Neardata](https://neardata.xyz) provides a hosted stream of blocks as a direct replacement for the deprecated NEAR Lake. *** ## How It Works The NEAR Indexer works by **running a node** and processing blocks as they are added to the blockchain. The framework provides a stream of blocks, allowing developers to subscribe and process these blocks in real-time. Learn how to run it following the [tutorial](./tutorials/near-indexer). *** ## Comparison with [NEAR Lake Framework](./near-lake-framework) **NEAR Lake deprecated as of March 24, 2026.** The comparison below is kept for historical context. For new projects, see [Neardata](https://neardata.xyz) as a drop-in replacement for NEAR Lake. Comparing to NEAR Lake Framework in terms of latency the NEAR Indexer is significantly faster as it reads data directly from the blockchain the same way as RPC nodes do. | Feature | Indexer Framework | Lake Framework | | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Allows to follow the blocks and transactions in the NEAR Protocol | **Yes** | **Yes**
(but only mainnet and testnet networks) | | Decentralized | **Yes** | No
(Aurora dumps the blocks to AWS S3) | | Reaction time (end-to-end) | minimum 3.8s (estimated average 5-7s) | [minimum 3.9s (estimated average 6-8s)](./near-lake-framework#latency) | | Reaction time (framework overhead only) | 0.1s | 0.2-2.2s | | Estimated cost of infrastructure | [\$500+/mo](https://near-nodes.io/rpc/hardware-rpc) | [**\$20/mo**](./near-lake-framework#cost) | | Ease of maintenance | Advanced
(need to follow every nearcore upgrade, and sync state) | **Easy**
(deploy once and forget) | | How long will it take to start? | days (on mainnet/testnet) | **seconds** | | Ease of local development | Advanced
(localnet is a good option, but testing on testnet/mainnet is too heavy) | **Easy**
(see [tutorials](./tutorials/near-lake-state-changes-indexer)) | | Programming languages that a custom indexer can be implemented with | Rust only | **Any**
(currently, helper packages are released in [Python](http://pypi.org/project/near-lake-framework), [JavaScript](https://www.npmjs.com/package/near-lake-framework), and [Rust](https://crates.io/crates/near-lake-framework)) | *** # Tutorial: Creating an Indexer Source: https://docs.near.org/data-infrastructure/tutorials/near-indexer This tutorial will guide you through building an indexer using the NEAR Indexer Framework. The indexer will listen for FunctionCalls on a specific contract and log the details of each call. In this tutorial, we will build an indexer using the NEAR Indexer Framework. The indexer will listen realtime blocks data from NEAR blockchain. To get our indexer up and running we will need two steps: 1. To [initialize](#initialization) the indexer 2. To [start it](#starting-the-indexer) The full source code for the indexer example is available in the [GitHub repository](https://github.com/near/nearcore/tree/master/tools/indexer/example). Source code link is for `nearcore` repository, as the Indexer Framework is part of the `nearcore` codebase. We provide the link to `master` branch. If you want to use **the latest stable release version** you should check the [releases page](https://github.com/near/nearcore/releases) and checkout the corresponding tag. NEAR Indexer Framework only works on **`Linux x86`**, it does **not** support Windows or MacOS *** ## Prerequisites ### Install Rust ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` ### Install developer tools ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} apt update apt install -y git binutils-dev libcurl4-openssl-dev zlib1g-dev libdw-dev libiberty-dev cmake gcc g++ python docker.io protobuf-compiler libssl-dev pkg-config clang llvm cargo awscli ``` NEAR Indexer Framework only works on **`Linux x86`**, it does **not** support Windows or MacOS ### Clone nearcore repository ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} git clone git@github.com:near/nearcore.git ``` *** ## Initialization In order for our indexer to process blocks it needs to join the NEAR network as a node. To do that, we need first to initialize it, which will download the blockchain `genesis` config, and create a `key` for our node to communicate with other nodes. Go to the `nearcore/tools/indexer/example` folder and build the indexer: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cd nearcore/tools/indexer/example && cargo build --release ``` Then, run the following command to initialize the network configuration: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo run --release -- --home-dir ~/.near/localnet init ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo run --release -- --home-dir ~/.near/testnet init --chain-id testnet --download-config rpc --download-genesis ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo run --release -- --home-dir ~/.near/mainnet init --chain-id mainnet --download-config rpc --download-genesis ``` Depending on the network we want to connect, the keys will be created in different folders (`~/.near/`). #### Config File A configuration file (`~/.near//config.json`) is created automatically, whoever, it is recommended to replace with one of the following ones, intended for RPC nodes: * [testnet config.json](https://s3-us-west-1.amazonaws.com/build.nearprotocol.com/nearcore-deploy/testnet/rpc/config.json) * [mainnet config.json](https://s3-us-west-1.amazonaws.com/build.nearprotocol.com/nearcore-deploy/mainnet/rpc/config.json) **Configuration Options** See the [Custom Configuration](#custom-configuration) section below to learn more about further configuration options. *** ## Starting the Indexer After we finish initializing the indexer, and configuring it, we can start it by running the following command: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo run --release -- --home-dir ~/.near/localnet ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo run --release -- --home-dir ~/.near/testnet run ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo run --release -- --home-dir ~/.near/mainnet run ``` * The command initializes the indexer's configuration: home directory, sync mode, streaming mode, finality, etc. * Creates a Tokio runtime on a dedicated thread. * Creates an instance of the Indexer using the provided configuration, starts it, and streams blocks to our handler. Within the handler (`listen_blocks` method), there is an infinite loop that parses block data for each new block received. #### Run into an Error? * If your indexer cannot find `boot nodes`, check the [boot nodes](#boot-nodes) section *** ## Parsing the Block Data Within the `listen_blocks` method, we can parse the block data as it flows from the stream. From the block data, we can access the transactions, their receipts, and actions. See the code below for an example of how to parse the block data: *** ## Custom Configuration By default, nearcore is configured to do as little work as possible while still operating on an up-to-date state. Indexers may have different requirements, so you might need to tweak the configuration based on yours. ### Shards/Accounts to Track We need to ensure that NEAR Indexer follows all the necessary shards, so by default the `"tracked_shards_config"` is set to `"AllShards"`. The most common tweak you might need to apply is listing to specific shards; to do that, lists all the shard UIDs you want to track in the `"tracked_shards_config"` section (`~/.near//config.json` file): ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} ... "tracked_shards_config": { "Shards": [ "s3.v3", "s4.v3" ] }, ... ``` Or, if you want to track specific accounts: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} ... "tracked_shards_config": { "Accounts": [ "account_a", "account_b" ] }, ... ``` ### Sync Mode You can choose Indexer Framework sync mode by setting what to stream: * LatestSynced - Real-time syncing, always taking the latest finalized block to stream * FromInterruption - Starts syncing from the block NEAR Indexer was interrupted last time * BlockHeight(u64) - Specific block height to start syncing from. ### Streaming Mode You can choose Indexer Framework streaming mode by setting what to stream: * StreamWhileSyncing - Stream while node is syncing * WaitForFullSync - Don't stream until the node is fully synced ### Finality You can choose finality level at which blocks are streamed: * None - `optimistic`, a block that (though unlikely) might be skipped * DoomSlug - `near-final`, a block that is irreversible, unless at least one block producer is slashed * Final - `final`, the block is final and irreversible. ### Boot Nodes If your node can't find any peers to connect to, you can manually specify some boot nodes in the `config.json` file. You can get a list of active peers for your network by running the following command: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -X POST https://rpc.testnet.near.org \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "network_info", "params": [], "id": "dontcare" }' | \ jq '.result.active_peers as $list1 | .result.known_producers as $list2 | $list1[] as $active_peer | $list2[] | select(.peer_id == $active_peer.id) | "\(.peer_id)@\($active_peer.addr)"' |\ awk 'NR>2 {print ","} length($0) {print p} {p=$0}' ORS="" | sed 's/"//g' ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl -X POST https://rpc.mainnet.near.org \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "method": "network_info", "params": [], "id": "dontcare" }' | \ jq '.result.active_peers as $list1 | .result.known_producers as $list2 | $list1[] as $active_peer | $list2[] | select(.peer_id == $active_peer.id) | "\(.peer_id)@\($active_peer.addr)"' |\ awk 'NR>2 {print ","} length($0) {print p} {p=$0}' ORS="" | sed 's/"//g' ``` And then add the output to the `boot_nodes` section of your `config.json` file as a string: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} ... "network": { "addr": "0.0.0.0:24567", "boot_nodes": "ed25519:8oVENgBp6zJfnwXFe...", ... }, ... ``` ### Historical Data Indexer Framework also exposes access to the internal APIs (see Indexer::client\_actors method), so you can fetch data about any block, transaction, etc, yet by default, nearcore is configured to remove old data (garbage collection), so querying the data that was observed a few epochs before may return an error saying that the data is not found. If you only need blocks streaming, you don't need this tweak, but if you need access to the historical data right from your Indexer, consider updating "archive" setting in config.json to true: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} ... "archive": true, ... ``` *** ## Using NEAR Indexer in your Project You can also use NEAR Indexer Framework as a dependency in your own Rust project. To do that, add the following to your `Cargo.toml` file (replace `2.8.0` with the latest stable release version): ```toml theme={"theme":{"light":"github-light","dark":"github-dark"}} [dependencies] near-indexer = { git = "https://github.com/near/nearcore", tag = "2.9.1" } near-indexer-primitives = { git = "https://github.com/near/nearcore", tag = "2.9.1" } near-config-utils = { git = "https://github.com/near/nearcore", tag = "2.9.1" } near-o11y = { git = "https://github.com/near/nearcore", tag = "2.9.1" } near-primitives = { git = "https://github.com/near/nearcore", tag = "2.9.1" } ``` # Running Lake Indexer Source: https://docs.near.org/data-infrastructure/tutorials/running-near-lake/run-near-lake Learn how to set up and run a NEAR Lake Indexer, including prerequisites, network configuration, and commands for syncing from the latest or a specific block. **NEAR Lake deprecated as of March 24, 2026.** This page uses the NEAR Lake Framework, which reads from AWS S3 buckets that have stopped indexing new blocks. For new projects, use [Neardata](https://neardata.xyz) (direct replacement), [Data APIs](/data-infrastructure/data-api), [Goldsky](https://goldsky.com), or the [Nearcore Indexer](/data-infrastructure/near-indexer). At NEAR we already have a working solution to index blockchain data and store it in AWS S3 buckets called **NEAR Lake**. In this guide you will learn how to set up and run an instance of the NEAR Lake Indexer. The Lake Indexer setup consists of the following components: * AWS S3 Bucket as a storage * NEAR Lake binary that operates as a regular NEAR Protocol peer-to-peer node, so you will operate it as any other [Regular/RPC Node in NEAR](https://near-nodes.io/rpc/hardware-rpc) NEAR Lake is an indexer specialized on storing events as JSON files on AWS S3, built on top of the [NEAR Indexer microframework](https://github.com/nearprotocol/nearcore/tree/master/chain/indexer) ### Prepare Development Environment Before you proceed, make sure you have the following software installed: * [Rust compiler](https://rustup.rs/) of the version that is mentioned in `rust-toolchain` file in the root of [nearcore](https://github.com/nearprotocol/nearcore) project. * Ensure you have [AWS Credentials configured](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) From AWS Docs: > For example, the files generated by the AWS CLI for a default profile configured with aws configure looks similar to the following. > > \~/.aws/credentials > > ``` > [default] > aws_access_key_id=AKIAIOSFODNN7EXAMPLE > aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY > ``` ### Compile NEAR Lake ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} $ cargo build --release ``` ### Configure NEAR Lake To connect NEAR Lake to the specific chain you need to have necessary configs, you can generate it as follows: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} $ ./target/release/near-lake --home ~/.near/testnet init --chain-id testnet --download-config --download-genesis ``` The above code will download the official genesis config and generate necessary configs. You can replace `testnet` in the command above to different network ID (`betanet`, `mainnet`). Configs for the specified network are in the `--home` provided folder. We need to ensure that NEAR Lake follows all the necessary shards, so `"tracked_shards"` parameters in `~/.near/testnet/config.json` needs to be configured properly. Currently, `nearcore` treats empty value for `"tracked_shards"` as "do not track any shard" and **any value** as "track all shards". For example, in order to track all shards, you just add the shard #0 to the list: ```text theme={"theme":{"light":"github-light","dark":"github-dark"}} ... "tracked_shards": [0], ... ``` ### Run NEAR Lake Commands to run NEAR Lake, after `./target/release/near-lake` | Command | Key/Subcommand | Required/Default | Responsible for | | ------- | ----------------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | | `--home` | Default
`~/.near` | Tells the node where too look for necessary files:
`config.json`
,
`genesis.json`
,
`node_key.json`
, and
`data`
folder | | `init` | | | Tells the node to generate config files in `--home-dir` | | | `--chain-id` | Required

\_ `localnet`
\_ `testnet`
\* `mainnet` | Defines the chain to generate config files for | | | `--download-config` | Optional | If provided tells the node to download `config.json` from the public URL. You can download them manually

- [testnet config.json](https://s3-us-west-1.amazonaws.com/build.nearprotocol.com/nearcore-deploy/testnet/rpc/config.json)
- [mainnet config.json](https://s3-us-west-1.amazonaws.com/build.nearprotocol.com/nearcore-deploy/mainnet/rpc/config.json) | | | `--download-genesis` | Optional | If provided tells the node to download `genesis.json` from the public URL. You can download them manually

- [testnet genesis.json](https://s3-us-west-1.amazonaws.com/build.nearprotocol.com/nearcore-deploy/testnet/genesis.json)
- [mainnet genesis.json](https://s3-us-west-1.amazonaws.com/build.nearprotocol.com/nearcore-deploy/mainnet/genesis.json) | | | TODO:
Other `neard` keys | | | | `run` | | | Runs the node | | | `--bucket` | Required | AWS S3 Bucket name | | | `--region` | Required | AWS S3 Bucket region | | | `--fallback-region` | Default eu-central-1 | AWS S3 Fallback region | | | `--endpoint` | Optional | AWS S3 compatible API endpoint | | | `--stream-while-syncing` | Optional | If provided Indexer streams blocks while they appear on the node instead of waiting the node to be fully synced | | | `--concurrency` | Default 1 | Defines the concurrency for the process of saving block data to AWS S3 | | | `sync-from-latest` | One of the `sync-` subcommands is required | Tells the node to start indexing from the latest block in the network | | | `sync-from-interruption` | One of the `sync-` subcommands is required | Tells the node to start indexing from the block the node was interrupted on (if it is a first start it will fallback to `sync-from-latest`) | | | `sync-from-block --height N` | One of the
`sync-`
subcommands is required | Tells the node to start indexing from the specified block height `N` (**Ensure** you node data has the block you want to start from) | ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} $ ./target/release/near-lake --home ~/.near/testnet run --stream-while-syncing --concurrency 50 sync-from-latest ``` After the network is synced, you should see logs of every block height currently received by NEAR Lake. *** ## Syncing Whenever you run NEAR Lake for any network except localnet you'll need to sync with the network. This is required because it's a natural behavior of `nearcore` node and NEAR Lake is a wrapper for the regular `nearcore` node. In order to work and index the data your node must be synced with the network. While snapshot-based syncing was previously the recommended default, we now recommend [Epoch Sync](https://near-nodes.io/intro/node-epoch-sync) —a faster, more lightweight method that allows a node to catch up from genesis without downloading a large state snapshot. *** ## Running NEAR Lake as an archival node It's not necessary but in order to index everything in the network it is better to do it from the genesis. `nearcore` node is running in non-archival mode by default. That means that the node keeps data only for [5 last epochs](/protocol/network/epoch). In order to index data from the genesis you need to turn the node in archival mode. To do it you need to update `config.json` located in `--home-dir` (by default it is `~/.near`). Find next keys in the config and update them as following: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { ... "archive": true, "tracked_shards": [0], ... } ``` The syncing process in archival mode can take a lot of time, so it's better to download a backup provided by NEAR and put it in your `data` folder. After that your node will download only the data after the backup was cut and it takes reasonable amount time. All the backups can be downloaded from the public [S3 bucket](https://docs.fastnear.com/docs/snapshots/mainnet#archival-mainnet-snapshot) provided by FastNEAR. See [this link](https://near-nodes.io/archival/run-archival-node-with-nearup) for reference *** ## Custom S3 storage In case you want to run you own `near-lake` instance and store data in some S3 compatible storage ([Minio](https://min.io/) or [Localstack](https://localstack.cloud/) as example) You can override default S3 API endpoint by using `--endpoint` option * run `minio` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} $ mkdir -p /data/near-lake-custom && minio server /data ``` * run `near-lake` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} $ ./target/release/near-lake --home ~/.near/testnet run --endpoint http://127.0.0.1:9000 --bucket near-lake-custom sync-from-latest ``` ### Data structure The data structure we use is the following: ```text theme={"theme":{"light":"github-light","dark":"github-dark"}} / block.json shard_0.json shard_1.json ... shard_N.json ``` * `` is a 12-character-long `u64` string with leading zeros (e.g `000042839521`). [See this issue for a reasoning](https://github.com/near/near-lake/issues/23) * `block_json` contains JSON-serialized [`BlockView`](https://github.com/near/nearcore/blob/e9a28c46c2bea505b817abf484e6015a61ea7d01/core/primitives/src/views.rs#L711-L716) struct. **Note:** this struct might change in the future, we will announce it * `shard_N.json` where `N` is `u64` starting from `0`. Represents the index number of the shard. In order to find out the expected number of shards in the block you can look in `block.json` at `.header.chunks_included` # What is Data Infrastructure? Source: https://docs.near.org/data-infrastructure/what-is Explore NEAR's data infrastructure for accessing on-chain data NEAR offers ready-to-use solutions to access and monitor on-chain data easily. This is very useful to automate actions based on specific **events**, cache data to **reduce latency**, gather **usage data** of the blockchain, and even **study user preferences**. img In NEAR you will find three main solutions to access and monitor on-chain data: [**Data APIs**](#data-apis), [**BigQuery Public Dataset**](#bigquery-public-dataset) and [**NEAR Lake**](#near-lake). Each of these solutions is designed to fit different needs and use cases, and can be used in combination to create a complete data infrastructure for your application. *** ## [Data APIs](./data-api) Members of the NEAR community have built a set of APIs to access and monitor on-chain data. These APIs are designed to be easy to use and can be accessed from any application through a simple API call. * User assets: Easily track all the assets that a user or a contract holds * Monitor transactions: Get all the transactions of a user, a contract or a specific token * Track on-chain events: Get all the events emitted by a contract, or a specific event type
## [BigQuery: Public Dataset](./big-query) A large dataset with on-chain data publicly available on Google Cloud Platform. Obtain near real-time blockchain data using simple SQL queries. **All the data, zero setup**. * Instant insights: Historic on-chain data queried at scale. No need to run your own infrastructure. * Cost-effective: Eliminate the need to store and process bulk NEAR Protocol data. Query as little or as much data as you like. * As easy as SQL: No prior experience with blockchain technology is required. Just bring a general knowledge of SQL to unlock insights.
## [NEAR Lake](./near-lake-framework) **Deprecated as of March 24, 2026.** NEAR Lake (AWS S3 buckets) has stopped indexing new blocks. For new projects, use [Neardata](https://neardata.xyz) (direct replacement), [Data APIs](./data-api), [Goldsky](https://goldsky.com), or the [Nearcore Indexer](./near-indexer). A solution that watches over the NEAR network and stores all the events for your easy access. * Cost-efficient solution: Cost-efficient solution for building self-hosted indexers in Rust, JavaScript, Python, Go and other languages * Streamlined data management: Use NEAR Lake Framework to stream blocks to your server directly from NEAR Lake *** ## Conclusion Data infrastructure is a key component of any blockchain application. It allows developers to access and monitor on-chain data easily, which is essential for building applications that interact with the blockchain. NEAR offers a range of solutions to help developers build robust data infrastructure for their applications, including Data APIs, BigQuery Public Dataset, and NEAR Lake. By using these solutions in combination, developers can create a complete data infrastructure that meets their specific needs and use cases. # Create an Account Source: https://docs.near.org/getting-started/create-account Understand how to create a NEAR account using a wallet and the NEAR CLI To start developing applications in NEAR you will need a NEAR `testnet` account. This account will allow you to deploy and test your applications without spending any real money. You can create a `testnet` NEAR account through one of the following methods: * [Using one of the wallets listed in wallet.near.org](#using-a-wallet) * [Using the command line interface (CLI)](#through-the-cli) If you already have a NEAR account, you can import it into another wallet or the CLI. See [Importing Existing Accounts](#importing-existing-accounts) below. *** ## Using a Wallet Go to [wallet.near.org](https://wallet.near.org/) and choose one of the wallets listed there. Do not worry, the list has been curated, so you can be sure that all wallets listed there are safe to use. In general, all wallets will offer similar functionality, so in theory you can choose any of them. However, know that some wallets will readily allow you to create [named accounts](/protocol/accounts-contracts/account-id#named-address) (e.g. `alice.testnet`), which are easier to remember. Remember to write down the seed phrase, as it is the only way to access your account! **Testnet** Make sure to create a `testnet` account (ending with `.testnet`, e.g. `alice.testnet`), and not a `mainnet` account (ending with `.near`). NEAR `testnet` is a separate network that allows you to test your applications without spending real money. **Funding the Wallet** Need `testnet` funds? try using one of our [faucets](/getting-started/faucet) *** ## Through the CLI When developing smart contracts you will expend lots of time interacting with the NEAR blockchain through the command line interface (CLI). First, you will need to install the [NEAR CLI](/tools/cli#installation): ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} npm install -g near-cli-rs@latest ``` ``` $ cargo install near-cli-rs ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/near-cli-rs/releases/latest/download/near-cli-rs-installer.sh | sh ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} irm https://github.com/near/near-cli-rs/releases/latest/download/near-cli-rs-installer.ps1 | iex ``` Once you have the CLI installed, you can create a new account using the following command: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near create-account --useFaucet ``` This command will create a new account with the name `` and fund it using the `testnet` faucet. Make sure to replace `` with your desired account name. *** ## Importing Existing Accounts If you want to use an existing NEAR account in another wallet or in the CLI, you can import it using your seed phrase or private key. From your current wallet, use its account backup/export flow. If the account was created with the CLI, run: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near account export-account ``` In your destination wallet, choose the account import/restore option and provide your seed phrase. Run: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near account import-account ``` Then follow the prompts to enter your seed phrase or private key. Keep your seed phrase and private key secure. Anyone with access to them can control your account. *** ## Next Steps Now that you have created a NEAR account, you can start developing applications on the NEAR Protocol. Here are some resources to help you get started: * Fund the wallet through one of our [faucets](/getting-started/faucet) * Create your [first smart contract](/smart-contracts/quickstart) * Build a [Web3 Application](/web3-apps/quickstart) * Learn how to build an [Auction App from end-to-end](/web3-apps/tutorials/mastering-near/0-intro) # Token Faucet Source: https://docs.near.org/getting-started/faucet Learn how to get free testnet tokens for development and testing on the NEAR blockchain A **faucet** provides free `testnet` tokens for testing and development purposes. There are two testnet faucets: the built‑in faucet on this page - which provides native `testnet` NEAR only - and the [Testnet Faucet](#external-faucet), which supports many fungible tokens (NEAR, USDT, and more). If any of the faucets is not working, please report it on our [NEAR Telegram Channel](https://t.me/neardev) *** ## Faucet Simply introduce the account you want to receive the tokens in, and click on the "Request" button. The faucet will send a small amount of `testnet` NEAR tokens to that account. *** ## External Faucet Navigate to the [Testnet Faucet](https://near-faucet.io/) page, input your address and select which type of token you need! The faucet supports a wide range of fungible tokens, including NEAR, Tether USD, Ether, and many others. Faucet showing token selection interface Please know that the faucet might be out of tokens at times, keep reading below for alternative ways to get other fungible tokens *** ## Getting Fungible Tokens Another way to get fungible tokens on `testnet` is through the [`testnet` version of ref finance](https://testnet.ref.finance/#near|ref.fakes.testnet) There, you can swap `testnet` NEAR for other fungible tokens, such as `testnet USDC`, `testnet USDT`, `testnet DAI`, and others Please notice that tokens on `testnet` might not hold the same rate as on `mainnet` (e.g. `1 USDC` might not exchange to the same amount of `NEAR` as on `mainnet`), furthermore, liquidity on `testnet` might be very low # Building on NEAR Source: https://docs.near.org/getting-started/hackathons Curated resources to help you start building quickly, plus the Awesome NEAR directory. This page brings together practical resources you can use right away when building on NEAR. ## Getting started Learn NEAR basics, architecture, and why developers choose it. Join Telegram developer chats to ask questions and get help. Request NEAR AI Cloud credits for your project. ## Core docs * [NEAR protocol basics](/protocol/accounts-contracts/account-model) * [Smart contracts quickstart](/smart-contracts/quickstart) * [Web3 apps quickstart](/web3-apps/quickstart) * [Chain abstraction overview](/chain-abstraction/what-is) * [Tools for AI agents](/getting-started/tools-for-ai) * [NEAR AI documentation](https://docs.near.ai/) * [NEAR intents documentation](https://docs.near-intents.org/near-intents) ## Awesome NEAR `awesome-near` is a community-maintained resource directory with tooling, examples, libraries, and integrations. * [Skills](#skills) * [Testnet faucets](#testnet-faucets) * [NEAR protocol SDKs](#near-protocol-sdks) * [Wallet and authentication](#wallet-and-authentication) * [CLI tools](#cli-tools) * [Starter templates](#starter-templates) * [Data infrastructure](#data-infrastructure) * [Data APIs](#data-apis) * [AI and cloud services](#ai-and-cloud-services) * [Near intents](#near-intents) * [Chain signatures](#chain-signatures) * [Explorers](#explorers) * [Additional resources](#additional-resources) ## Skills | Package | Description | | ---------------------------------------------------- | -------------------------------------------------------- | | [agent-skills](https://github.com/near/agent-skills) | AI agent skills for NEAR Protocol blockchain development | ## Testnet faucets | Faucet | Description | | ------------------------------------------- | ------------------------------------------------- | | [Circle Faucet](https://faucet.circle.com/) | 20 USDC on NEAR Testnet (claimable every 2 hours) | | [NEAR Faucet](https://near-faucet.io/) | 2 NEAR on Testnet (rate limited) | ## NEAR protocol SDKs ### JavaScript / TypeScript | Package | Description | | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- | | [near-api-js](https://github.com/near/near-api-js) | High-level JavaScript client for accounts, blocks, transactions, tokens, and function calls | | [near-api-ts](https://github.com/near/near-api-ts) | High-level type-safe TypeScript client for NEAR Protocol | | [near-kit](https://github.com/r-near/near-kit) | Modern TypeScript client with fetch-like API | | [near-jsonrpc-client-ts](https://github.com/near/near-jsonrpc-client-ts) | Auto-generated TypeScript JSON-RPC client | ### Rust | Package | Description | | -------------------------------------------------- | -------------------------------------------------- | | [near-api-rs](https://github.com/near/near-api-rs) | High-level Rust off-chain client for NEAR Protocol | | [near-sdk-rs](https://github.com/near/near-sdk-rs) | Rust SDK for writing NEAR smart contracts | | [near-abi-rs](https://github.com/near/near-abi-rs) | ABI primitives and models for Rust contracts | ### Python | Package | Description | | ------------------------------------------------------------------------ | -------------------------------------------------------------- | | [py-near](https://github.com/pvolnov/py-near) | Async Python client with HOT Protocol and NEAR Intents support | | [near-jsonrpc-client-py](https://github.com/near/near-jsonrpc-client-py) | Type-safe Pythonic JSON-RPC client with Pydantic models | | [near-sdk-py](https://github.com/r-near/near-sdk-py) | Python SDK for writing NEAR smart contracts | ## Wallet and authentication | Package | Description | | ------------------------------------------------------------------------ | ------------------------------------------------------------- | | [@hot-labs/near-connect](https://github.com/azbang/near-connect) | Secure lightweight wallet connector for JavaScript/TypeScript | | [near-connect-hooks](https://github.com/matiasbenary/near-connect-hooks) | React hooks for NEAR wallet integration | | [near-sign-verify](https://github.com/elliotBraem/near-sign-verify) | Create and validate NEP-413 signed messages | | [better-near-auth](https://github.com/elliotBraem/better-near-auth) | Sign in with NEAR plugin for Better Auth | ## CLI tools | Package | Description | | ---------------------------------------------------------------------- | ------------------------------------------------------------ | | [near-cli-rs](https://github.com/near/near-cli-rs) | Human-friendly interactive CLI for NEAR Protocol | | [create-near-app](https://github.com/near/create-near-app) | Scaffold NEAR apps with frontend and contract templates | | [cargo-near](https://github.com/near/cargo-near) | Cargo extension for build and deploy with ABI generation | | [near-validator-cli-rs](https://github.com/near/near-validator-cli-rs) | CLI companion for staking operations and validator workflows | ## Starter templates | Package | Description | | ------------------------------------------------------------------------------- | ---------------------------------------------- | | [near-ai-chat](https://github.com/jlwaugh/near-ai-chat) | AI chat agent starter for NEAR AI Cloud | | [NEAR Playground](https://nearplay.app/) | Online IDE to create and deploy NEAR contracts | | [near-sdk-rs-template](https://github.com/near/cargo-near-new-project-template) | Rust smart contract template | | [NEAR-fast-ft-transfer](https://github.com/NEAR-DevHub/NEAR-fast-ft-transfer) | High-performance FT transfer service | ## Data infrastructure | Package | Description | | ------------------------------------------------------------------------ | -------------------------------------------------- | | [Goldsky](https://goldsky.com/chains/near) | Data infrastructure and indexing service | | [Stream NEAR](https://stream.near.tools) | Server-Sent Events stream for real-time block data | | [Explorer API](https://github.com/fastnear/explorer-api) | Transaction-based explorer API | | [Near Lake Indexer](https://github.com/aurora-is-near/near-lake-indexer) | Lake-based indexing service | ## Data APIs | Package | Description | | ------------------------------------------------------------------- | ----------------------------------------- | | [FastNear API](https://github.com/fastnear/fastnear-api-server-rs) | Low-latency API for wallets and explorers | | [NearBlocks API](https://api.nearblocks.io/api-docs/) | REST APIs for NEAR blockchain data | | [Pikespeak API](https://doc.pikespeak.ai/) | Aggregated analytics APIs | | [Allium API](https://docs.allium.so/api/developer/wallets/overview) | Wallet and historical transaction API | ## AI and cloud services | Package | Description | | -------------------------------------- | ------------------------------------------------------ | | [NEAR AI Cloud](https://cloud.near.ai) | Private inference platform for verifiable AI inference | ## Near intents | Package | Description | | --------------------------------------------------------------------------------------------- | --------------------------------------------------- | | [One Click SDK TypeScript](https://github.com/defuse-protocol/one-click-sdk-typescript) | TypeScript SDK for cross-chain swaps via 1Click API | | [One Click SDK Rust](https://github.com/defuse-protocol/one-click-sdk-rs) | Rust API client for one-click swaps | | [One Click SDK Go](https://github.com/defuse-protocol/one-click-sdk-go) | Go API client for one-click swaps | | [intents-sdk](https://github.com/defuse-protocol/sdk-monorepo/tree/main/packages/intents-sdk) | SDK for intents-based applications | ## Chain signatures | Package | Description | | ------------------------------------------------------------------ | ------------------------------------------------------------------ | | [chainsig.js](https://github.com/NearDeFi/chainsig.js) | TypeScript library for multi-chain transactions and MPC signatures | | [omni-transaction-rs](https://github.com/near/omni-transaction-rs) | Rust library to build transactions for multiple chains | ## Explorers * [NEAR Validate](https://nearvalidate.org/) * [NearBlocks](https://nearblocks.io/) * [Pikespeak](https://pikespeak.ai/) * [Near Intents Explorer](https://explorer.near-intents.org/) ## Additional resources * [NEAR Intents Documentation](https://docs.near-intents.org) * [NEP Specifications](https://github.com/near/NEPs) * [NEAR Blog](https://near.org/blog) * [NEAR Catalog](https://nearcatalog.xyz/) # Tools for AI Agents Source: https://docs.near.org/getting-started/tools-for-ai Guide your agent on building NEAR applications NEAR offers multiple tools and resources to help your AI agents build and use NEAR applications. This page provides an overview of the key tools available and how to use them effectively. When you need to provide your agent with a quick reference to all NEAR docs. When you want agents to search docs in real-time for up-to-date details. When you need your agent to become an expert in a specific task (e.g. using our API). When your agent needs to perform on-chain actions (e.g., transfers and function calls). *** ## llms.txt **What it is:** Curated NEAR docs context for coding assistants. **Use it when:** You need to provide your agent with a quick reference to all NEAR docs. **Link:** [https://docs.near.org/llms.txt](https://docs.near.org/llms.txt) Use `#fetch` in your prompt: ```text theme={"theme":{"light":"github-light","dark":"github-dark"}} How can I upgrade a contract state? #fetch https://docs.near.org/llms.txt ``` Add docs source once in Cursor Chat: 1. `@` → `Docs` → `+ Add new doc` 2. Add: `https://docs.near.org/llms.txt` 3. Select the source while prompting *** ## Docs MCP endpoint **What it is:** An endpoint to search NEAR documentation via MCP. **Use it when:** You want agents to search docs in real-time for up-to-date details and narrower API lookups. **Link:** [https://docs.near.org/mcp](https://docs.near.org/mcp) Use two complementary layers: 1. **Static context (`llms.txt`)** for fast, high-signal docs grounding. 2. **Retrieval (Docs MCP)** when the agent needs live lookup across docs. *** ## NEAR Agent Skills NEAR Agent Skills are reusable capabilities that package repeatable workflows. **Use it when:** You need your agent to become an expert in specific tasks (for example, using NEAR APIs). **Link:** [https://github.com/near/agent-skills](https://github.com/near/agent-skills) | Skill | Focus | | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | | [near-ai-cloud](https://github.com/near/agent-skills/tree/main/skills/near-ai-cloud) | Verifiable private AI inference and attestation | | [near-api-js](https://github.com/near/agent-skills/tree/main/skills/near-api-js) | JS/TS blockchain interaction, transactions, tokens, and wallet integration | | [near-dapp](https://github.com/near/agent-skills/tree/main/skills/near-dapp) | dApp project setup, wallet integration, React/Next.js patterns | | [near-intents](https://github.com/near/agent-skills/tree/main/skills/near-intents) | Cross-chain swaps via the 1Click API | | [near-kit](https://github.com/near/agent-skills/tree/main/skills/near-kit) | TypeScript SDK with type-safe contracts and sandbox testing | | [near-smart-contracts](https://github.com/near/agent-skills/tree/main/skills/near-smart-contracts) | Rust smart contract development, security, and state management | *** ## NEAR MCP Server The NEAR MCP Server is a tool server (currently [23 tools](https://github.com/nearai/near-mcp/blob/main/TOOLS.md)) that enables agents to perform blockchain operations. **Use it when:** Your agent needs to hold funds, transfer funds, interact with smart contracts, or perform any action on-chain in NEAR Protocol **Repo**: [https://github.com/nearai/near-mcp](https://github.com/nearai/near-mcp) **Remote deployment guide**: [https://github.com/nearai/near-mcp/blob/main/tee.md](https://github.com/nearai/near-mcp/blob/main/tee.md) The NEAR MCP is designed to run **locally** or on your **trusted infrastructure** because it handles private keys. There is no hosted public version. # What is NEAR? Source: https://docs.near.org/getting-started/what-is-near A scalable and secure chain with an amazing developer experience NEAR is a **user-friendly** and [**carbon-neutral**](https://near.org/blog/near-climate-neutral-product/) blockchain, built to be [fast, secure, and infinitely scalable](https://www.leewayhertz.com/comparison-of-blockchain-protocols#Parallel-comparison-of-various-blockchain-networks). It offers a simple user experience with named accounts, low fees, and a robust developer ecosystem. img In technical terms, NEAR is a [layer one](https://coinmarketcap.com/academy/glossary/layer-1-blockchain), [sharded](https://near.org/blog/near-launches-nightshade-sharding-paving-the-way-for-mass-adoption), [proof-of-stake](https://en.wikipedia.org/wiki/Proof_of_stake) blockchain built with usability in mind. In simpler terms, NEAR is the **blockchain for everyone**. In technical terms, NEAR is a [layer-one](https://coinmarketcap.com/academy/glossary/layer-1-blockchain), [sharded](https://near.org/blog/near-launches-nightshade-sharding-paving-the-way-for-mass-adoption), [proof-of-stake](https://en.wikipedia.org/wiki/Proof_of_stake) blockchain built with usability in mind. [Layer-1](https://coinmarketcap.com/academy/glossary/layer-1-blockchain) means NEAR is the foundation that supports everything else built on it. It keeps all the transaction records safe and unchangeable which keeps the network secure and trustworthy. [Sharded](https://near.org/blog/near-launches-nightshade-sharding-paving-the-way-for-mass-adoption) means the network is broken into pieces that work in parallel. This helps NEAR process transactions quickly and efficiently. [Proof-of-stake](https://en.wikipedia.org/wiki/Proof_of_stake) uses less electricity compared with other blockchains which use proof-of-work. Users show they own NEAR tokens to help run the network. This makes it cheaper and lets more people use it. *** ## Why Choose NEAR? NEAR is a technical marvel, offering built-in features such as named accounts and account abstraction. For developers, NEAR offers everything needed for their applications, from smart contracts to indexers. All while being interoperable with other chains. ### Simple to Use 1. Use [**named accounts**](/protocol/accounts-contracts/account-model) like `alice.near` 2. Simple sign-up: create an [account for free](/getting-started/create-account), login [with socials](../web3-apps/tutorials/wallet-login) or [telegram](https://web.telegram.org/k/#@herewalletbot) 3. Transactions are **fast** *(\~1.3s finality)* and **cheap** *(\< 1¢ in fees)* 4. You don't need to buy crypto thanks to **built-in account abstraction** 5. [Access Keys](/protocol/accounts-contracts/access-keys) make it safe and easy to use 6. Control accounts on **other chains** thanks to [chain signatures](../chain-abstraction/chain-signatures) ### Battle-Tested 1. 5 years of **100% uptime** and [**4 Billion** transactions](https://pikespeak.ai/near-world/overview) processed 2. NEAR has sustained peaks of [>13M transactions](https://pikespeak.ai/near-world/overview) in a single day 3. NEAR is home to decentralized apps with [millions of users](https://dappradar.com/rankings/protocol/near?sort=uawCount\&order=desc\&range=30d): * [Kai-ching](https://cosmose.ai/) * [Sweat](https://sweateconomy.com/) * [Hot Wallet](https://t.me/herewalletbot/) ### Great Developer Experience 1. Build smart contracts with **Javascript** or **Rust** 2. **Simple onboarding**, thanks to its complete documentation and examples 3. Get answers and learn at NEAR DevRel **office hours**, where anybody can participate 4. Earn from your contract's gas fees 5. **EVM compatible** with [Project Aurora](http://www.aurora.dev) *(Deploy your Solidity contracts with ease)* ### Environmentally Friendly 1. NEAR is **[certified carbon-neutral](https://near.org/blog/the-near-blockchain-is-climate-neutral/)** 2. NEAR **consumes in a year** the same energy [**bitcoin consumes in 3 minutes**](https://medium.com/nearprotocol/how-near-went-carbon-neutral-e656db96da47#:~:text=The%20firm%20found%20that%20NEAR,PoS%20technology%20instead%20of%20PoW) # Source: https://docs.near.org/index

NEAR Developer Docs

It has never been easier to build smart contracts, decentralized applications, and native cross-chain applications.

\~5 min Rust JavaScript Python Go

Deploy your first contract in minutes

Write smart contracts in Rust, JavaScript, TypeScript or Python. Scaffold a working project with a single command, then build, test, and deploy.

Start the quickstart → Concepts, storage model, and how execution works on NEAR. Actions, callbacks, cross-contract calls, and best practices.
```bash bash theme={"theme":{"light":"github-light","dark":"github-dark"}} $> npx create-near-app@latest ====================================================== 👋 Welcome to Near! Learn more: https://docs.near.org/ 🔧 Let's get your project ready. ====================================================== ✅ What do you want to build? › "Smart Contract" ✅ Name your project to create a contract: "hello-near" ✅ Success! Created 'hello-near', a smart contract in Rust Build, test, and deploy your contract using cargo: * cargo near build * cargo test * cargo near deploy ```
\~10 min React TypeScript

Connect your frontend to NEAR

Use near-api-js and the Wallet Selector to authenticate users and call smart contracts from any frontend framework.

Start the quickstart → Connect wallets, handle sessions, and manage user accounts. How NEAR types map to JavaScript in near-api-js.
```bash bash theme={"theme":{"light":"github-light","dark":"github-dark"}} $> npx create-near-app@latest ====================================================== 👋 Welcome to Near! Learn more: https://docs.near.org/ 🔧 Let's get your project ready. ====================================================== ✅ What do you want to build? › "A Web App" ✅ Select a framework for your frontend › "Vite (React)" ✅ Name your project: "hello-near" ✅ Success! Created 'hello-near', a web-app using Vite React. Start using your new NEAR app: * cd hello-near * npm run dev ```
Multi-chain Ethereum Bitcoin Solana

Sign transactions on any chain

Use Chain Signatures to derive threshold keys and sign transactions on any blockchain — all from a single NEAR account, no bridge or wrapped assets required.

Get started → How NEAR lets one account control wallets on any chain. Key derivation, MPC signing, and implementation details.
```javascript multichain.js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { Account, KeyPair, JsonRpcProvider, KeyPairSigner } from "near-api-js" import { getAdapter, chains } from "multichain.js" async function main() { const nearProvider = new JsonRpcProvider({ url: "https://test.rpc.fastnear.com" }) const nearAccount = new Account("account.testnet", nearProvider, "ed25519:...") const arbitrum = getAdapter({ chain: chains.ARBITRUM, mpcNetwork: "testnet" }) const arbAddress = await arbitrum.getAddressControlledBy({ nearAddress: nearAccount.accountId }) const arbBalance = await arbitrum.getBalance({ address: arbAddress }) console.log("Controlled Account", { arbAddress, arbBalance }) await arbitrum.transfer({ to: "0x2f318C334780961FB129D2a6c30D0763d9a5C970", amount: "10000000000000000", // 0.01 ETH nearAccount, }) } ```
*** ## Platform capabilities Transactions confirm in \~1–2 seconds on mainnet with deterministic finality. No reorgs, no waiting. Transaction fees under \$0.001. Storage costs \~1 NEAR per 100 KB — fully refundable on deletion. Write in Rust, JavaScript/TypeScript, Python, or Go. Full WASM runtime, no new syntax to learn. Derive threshold keys for any chain — Bitcoin, Ethereum, Solana — from one NEAR account. Run AI inference inside Trusted Execution Environments for verifiable, tamper-proof outputs. Nightshade sharding enables linear throughput scaling as validator count grows. *** ## Get started in 2 steps Get a human-readable account like `yourname.testnet` and fund it immediately with the faucet — no wallet install required. Free testnet account with instant NEAR balance. Ready in under 60 seconds. Run `create-near-app` to generate a working smart contract or full-stack web app in your preferred language. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} npx create-near-app@latest ``` *** ## Browse by topic Accounts, access keys, gas, transactions, and the NEAR runtime. Write and deploy contracts in Rust, TypeScript, or Python. Connect frontends to NEAR using near-api-js and the Wallet Selector. Sign transactions on any chain from a single NEAR account. FTs, NFTs, DAOs, DEXes, liquid staking, and more — ready to use. Index and query on-chain data with NEAR Lake, BigQuery, and indexers. # Decentralized Autonomous Organizations Source: https://docs.near.org/primitives/dao Learn about Decentralized Autonomous Organizations (DAOs) on NEAR - self-organized groups that coordinate membership, decision-making, and funding through smart contract voting. Decentralized Autonomous Organizations (DAOs) are self-organized groups that form around common purposes. Membership, decision-making, and funding are coordinated by publicly voting on proposals through a smart contract. dao In contrast with [FT](./ft/ft) and [NFT](./nft/nft), DAO contract's are not standardized. Because of this, on this page we will use as reference the [sputnik dao contract](https://github.com/near-daos/sputnik-dao-contract). The main concepts covered here should easily generalizable to other DAO implementations. The simplest way to create and interact with a DAO is to go through the [AstraDAO UI](https://near.social/astraplusplus.ndctools.near/widget/home?page=daos). *** ## Create a DAO You can create a DAO by interacting with the `sputnik-dao` contract: ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const DAO_FACTORY_CONTRACT_ADDRESS = 'sputnik-dao.near'; const { callFunction } = useNearWallet(); await callFunction({ contractId: DAO_FACTORY_CONTRACT_ADDRESS, method: 'create', args: { name: 'primitives', args: btoa({ config: { name: 'Primitives', purpose: 'Building primitives on NEAR', metadata: '', }, policy: ['bob.near'], }), }, gas: 300000000000000, deposit: 6000000000000000000000000, }); ``` The full list of roles and permissions you can find [here](https://github.com/near-daos/sputnik-dao-contract#roles-and-permissions). Learn more about adding [Near Connect](../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} export COUNCIL='["bob.near"]' export ARGS=`echo '{"config": {"name": "Primitives", "purpose": "Building primitives on NEAR", "metadata":""}, "policy": '$COUNCIL'}' | base64` near call sputnikv2.testnet create "{\"name\": \"primitives\", \"args\": \"$ARGS\"}" --useAccount bob.near --amount 6 --gas 150000000000000 ``` The full list of roles and permissions you can find [here](https://github.com/near-daos/sputnik-dao-contract#roles-and-permissions). You can find the complete list of [roles and permissions here](https://github.com/near-daos/sputnik-dao-contract#roles-and-permissions). ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} // Validator interface, for cross-contract calls #[ext_contract(ext_dao_factory_contract)] trait ExternalDaoFactoryContract { fn create(&mut self, name: AccountId, args: Base64VecU8) -> Promise; } // Implement the contract structure #[near] impl Contract { #[payable] pub fn create_dao(&mut self, name: AccountId, args: Base64VecU8) -> Promise { let promise = ext_dao_factory_contract::ext(self.dao_factory_contract.clone()) .with_attached_deposit(env::attached_deposit()) .with_static_gas(Gas(30*TGAS)) .create(name, args); return promise.then( // Create a promise to callback query_greeting_callback Self::ext(env::current_account_id()) .with_static_gas(Gas(50*TGAS)) .external_common_callback() ) } #[private] // Public - but only callable by env::current_account_id() pub fn external_common_callback(&self, #[callback_result] call_result: Result<(), PromiseError>) { // Check if the promise succeeded if call_result.is_err() { log!("There was an error contacting external contract") } } } ``` The simplest way to create and interact with a DAO is to go through the [AstraDAO UI](https://near.social/astraplusplus.ndctools.near/widget/home?page=daos).
### Using Global Contract You can deploy a new DAO using our global contract - a pre-deployed [a Sputnik DAO contract](https://github.com/near-daos/sputnik-dao-contract/tree/main/sputnikdao2) that you can reuse. [Global contracts](../smart-contracts/global-contracts) are deployed once and can be reused by any account without incurring high storage costs. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract deploy use-global-account-id dao.globals.primitives.testnet \ with-init-call new \ json-args '{"config": {"name": "Primitives", "purpose": "Building primitives on NEAR", "metadata":""}, "policy": [""]}' \ prepaid-gas '100.0 Tgas' \ attached-deposit '0 NEAR' \ network-config testnet \ sign-with-keychain \ send ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract deploy use-global-hash Ea8tHXFSQVszVwGASyzAfLq65DjcRDhkfab4FcPaRpgD \ with-init-call new \ json-args '{"config": {"name": "Primitives", "purpose": "Building primitives on NEAR", "metadata":""}, "policy": [""]}' \ prepaid-gas '100.0 Tgas' \ attached-deposit '0 NEAR' \ network-config testnet \ sign-with-keychain \ send ``` Deploying by **hash** creates an immutable contract that never changes. Deploying by **account ID** creates an updatable contract that changes when the referenced account's contract is updated. Choose based on whether you want your FT contract to be updatable or permanent.
### Voting policy Currently, DAOs support two different types of [voting policies](https://github.com/near-daos/sputnik-dao-contract#voting-policy): `TokenWeight`, and `RoleWeight`. When the vote policy is `TokenWeight`, the council votes using [tokens](./ft/ft). The weigh of a vote is the proportion of tokens used for voting over the token's total supply. When the vote policy is `RoleWeight(role)`, the vote weigh is computed as "one over the total number of people with the role". Both voting policies further include a `threshold` for passing a proposal, which can be a ratio or a fixed number. The ratio indicates that you need a proportion of people/tokens to approve the proposal (e.g. half the people need to vote, and to vote positively). A fixed number indicated that you need a specific number of votes/tokens to pass the proposal (e.g. 3 people/tokens are enough to approve the proposal). *** ## List of DAOs Query the list of DAOs existing in Sputnik Dao. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const DAO_FACTORY_CONTRACT_ADDRESS = 'sputnik-dao.near'; const { viewFunction } = useNearWallet(); await viewFunction({ method: 'get_dao_list', args: {}, contractId: DAO_FACTORY_CONTRACT_ADDRESS, }); ``` Learn more about adding [Near Connect](../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near view sputnik-dao.near get_dao_list '{}' ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} [ 'ref-finance.sputnik-dao.near' 'gaming-dao.sputnik-dao.near', ... ] ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} [ 'ref-finance.sputnik-dao.near' 'gaming-dao.sputnik-dao.near', ... ] ```
*** ## Query Existing Proposals These snippets will enable you to query the proposals existing in a particular DAO. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const DAO_CONTRACT_ADDRESS = 'nearweek-news-contribution.sputnik-dao.near'; const { viewFunction } = useNearWallet(); await viewFunction({ method: 'get_proposals', args: { from_index: 9262, limit: 2 }, contractId: DAO_CONTRACT_ADDRESS, }); ``` Learn more about adding [Near Connect](../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near view nearweek-news-contribution.sputnik-dao.near get_proposals '{"from_index": 9262, "limit": 2}' ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} [ { id: 9262, proposer: 'pasternag.near', description: 'NEAR, a top non-EVM blockchain, has gone live on Router’s Testnet Mandara. With Router Nitro, our flagship dApp, users in the NEAR ecosystem can now transfer test tokens to and from NEAR onto other supported chains. $$$$https://twitter.com/routerprotocol/status/1727732303491961232', kind: { Transfer: { token_id: '', receiver_id: 'pasternag.near', amount: '500000000000000000000000', msg: null } }, status: 'Approved', vote_counts: { council: [ 1, 0, 0 ] }, votes: { 'brzk-93444.near': 'Approve' }, submission_time: '1700828277659425683' }, { id: 9263, proposer: 'fittedn.near', description: 'How to deploy BOS component$$$$https://twitter.com/BitkubAcademy/status/1728003163318563025?t=PiN6pwS380T1N4JuQXSONA&s=19', kind: { Transfer: { token_id: '', receiver_id: 'fittedn.near', amount: '500000000000000000000000', msg: null } }, status: 'InProgress', vote_counts: { 'Whitelisted Members': [ 1, 0, 0 ] }, votes: { 'trendheo.near': 'Approve' }, submission_time: '1700832601849419123' } ] ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} [ { "id": 9262, "proposer": "pasternag.near", "description": "NEAR, a top non-EVM blockchain, has gone live on Router’s Testnet Mandara. With Router Nitro, our flagship dApp, users in the NEAR ecosystem can now transfer test tokens to and from NEAR onto other supported chains. $$$$https://twitter.com/routerprotocol/status/1727732303491961232", "kind": { "Transfer": { "token_id": "", "receiver_id": "pasternag.near", "amount": "500000000000000000000000", "msg": null } }, "status": "Approved", "vote_counts": { "council": [1, 0, 0] }, "votes": { "brzk-93444.near": "Approve" }, "submission_time": "1700828277659425683" }, { "id": 9263, "proposer": "fittedn.near", "description": "How to deploy BOS component$$$$https://twitter.com/BitkubAcademy/status/1728003163318563025?t=PiN6pwS380T1N4JuQXSONA&s=19", "kind": { "Transfer": { "token_id": "", "receiver_id": "fittedn.near", "amount": "500000000000000000000000", "msg": null } }, "status": "Expired", "vote_counts": { "Whitelisted Members": [2, 0, 0] }, "votes": { "trendheo.near": "Approve", "vikash.near": "Approve" }, "submission_time": "1700832601849419123" } ] ```
*** ## Create proposal Create a proposal so other users can vote in favor or against it. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const DAO_CONTRACT_ADDRESS = 'primitives.sputnik-dao.near'; const { callFunction } = useNearWallet(); await callFunction({ contractId: DAO_CONTRACT_ADDRESS, method: 'add_proposal', args: { proposal: { description: 'My first proposal', kind: { Transfer: { token_id: '', receiver_id: 'bob.near', amount: '10000000000000000000000000', }, }, }, }, gas: 300000000000000, deposit: 100000000000000000000000, }); ``` Learn more about adding [Near Connect](../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call primitives.sputnik-dao.near add_proposal '{"proposal": {"description": "My first proposal", "kind": { "Transfer": {"token_id": "", "receiver_id": "bob.near", "amount": "10000000000000000000000000"}}}}' --deposit 0.1 --gas 300000000000000 --useAccount bob.near ``` ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} // Account ID that represents a token in near-sdk v3 // Need to keep it around for backward compatibility pub type OldAccountId = String; // How the voting policy votes get weighted. #[near(serializers = [json, borsh]) #[derive(Clone, PartialEq)] #[cfg_attr(not(target_arch = "wasm32"), derive(Debug))] pub enum WeightKind { // Using token amounts and total delegated at the moment. TokenWeight, // Weight of the group role. Roles that don't have scoped group are not supported. RoleWeight, } // Direct weight or ratio to total weight, used for the voting policy #[near(serializers = [json, borsh]) #[derive(Clone)] #[cfg_attr(not(target_arch = "wasm32"), derive(Debug, PartialEq))] #[serde(untagged)] pub enum WeightOrRatio { Weight(U128), Ratio(u64, u64), } // Defines configuration of the vote #[near(serializers = [json, borsh]) #[derive(Clone)] #[cfg_attr(not(target_arch = "wasm32"), derive(Debug, PartialEq))] pub struct VotePolicy { // Kind of weight to use for votes. pub weight_kind: WeightKind, // Minimum number required for vote to finalize. // If weight kind is TokenWeight - this is minimum number of tokens required. // This allows to avoid situation where the number of staked tokens from total supply is too small. // If RoleWeight - this is minimum number of votes. // This allows to avoid situation where the role is got too small but policy kept at 1/2, for example. pub quorum: U128, // How many votes to pass this vote. pub threshold: WeightOrRatio, } #[near(serializers = [json, borsh])] #[derive(Clone)] #[cfg_attr(not(target_arch = "wasm32"), derive(Debug, PartialEq))] pub enum RoleKind { // Matches everyone, who is not matched by other roles. Everyone, // Member greater or equal than given balance. Can use `1` as non-zero balance. Member(U128), // Set of accounts. Group(HashSet), } #[near(serializers = [json, borsh])] #[derive(Clone)] #[cfg_attr(not(target_arch = "wasm32"), derive(Debug, PartialEq))] pub struct RolePermission { // Name of the role to display to the user. pub name: String, // Kind of the role: defines which users this permissions apply. pub kind: RoleKind, // Set of actions on which proposals that this role is allowed to execute. // : pub permissions: HashSet, // For each proposal kind, defines voting policy. pub vote_policy: HashMap, } // Defines voting / decision making policy of this DAO #[near(serializers = [json, borsh])] #[derive(Clone)] #[cfg_attr(not(target_arch = "wasm32"), derive(Debug, PartialEq))] pub struct Policy { // List of roles and permissions for them in the current policy. pub roles: Vec, // Default vote policy. Used when given proposal kind doesn't have special policy. pub default_vote_policy: VotePolicy, // Proposal bond. pub proposal_bond: U128, // Expiration period for proposals. pub proposal_period: U64, // Bond for claiming a bounty. pub bounty_bond: U128, // Period in which giving up on bounty is not punished. pub bounty_forgiveness_period: U64, } // Versioned policy #[near(serializers = [json, borsh])] #[derive(Clone)] #[cfg_attr(not(target_arch = "wasm32"), derive(Debug, PartialEq))] pub enum VersionedPolicy { // Default policy with given accounts as council. Default(Vec), Current(Policy), } // Function call arguments #[near(serializers = [json, borsh])] #[cfg_attr(not(target_arch = "wasm32"), derive(Clone, Debug))] pub struct ActionCall { method_name: String, args: Base64VecU8, deposit: U128, gas: U64, } // Bounty information. #[near(serializers = [json, borsh])] #[derive(Clone)] #[cfg_attr(not(target_arch = "wasm32"), derive(Debug))] pub struct Bounty { /// Description of the bounty. pub description: String, /// Token the bounty will be paid out. /// Can be "" for `$NEAR` or a valid account id. pub token: OldAccountId, /// Amount to be paid out. pub amount: U128, /// How many times this bounty can be done. pub times: u32, /// Max deadline from claim that can be spend on this bounty. pub max_deadline: U64, } // Info about factory that deployed this contract and if auto-update is allowed #[near(serializers = [json, borsh])] #[cfg_attr(not(target_arch = "wasm32"), derive(Clone, Debug))] pub struct FactoryInfo { pub factory_id: AccountId, pub auto_update: bool, } // Function call arguments #[near(serializers = [json, borsh])] #[cfg_attr(not(target_arch = "wasm32"), derive(Clone, Debug))] pub struct PolicyParameters { pub proposal_bond: Option, pub proposal_period: Option, pub bounty_bond: Option, pub bounty_forgiveness_period: Option, } // Votes recorded in the proposal #[near(serializers = [json, borsh])] #[derive(Clone, Debug)] pub enum Vote { Approve = 0x0, Reject = 0x1, Remove = 0x2, } // Configuration of the DAO #[near(serializers = [json, borsh])] #[derive(Clone, Debug)] pub struct Config { // Name of the DAO. pub name: String, // Purpose of this DAO. pub purpose: String, // Generic metadata. Can be used by specific UI to store additional data. // This is not used by anything in the contract. pub metadata: Base64VecU8, } // Kinds of proposals, doing different action #[near(serializers = [json, borsh])] #[cfg_attr(not(target_arch = "wasm32"), derive(Clone, Debug))] pub enum ProposalKind { // Change the DAO config. ChangeConfig { config: Config }, // Change the full policy. ChangePolicy { policy: VersionedPolicy }, // Add member to given role in the policy. This is short cut to updating the whole policy. AddMemberToRole { member_id: AccountId, role: String }, // Remove member to given role in the policy. This is short cut to updating the whole policy. RemoveMemberFromRole { member_id: AccountId, role: String }, // Calls `receiver_id` with list of method names in a single promise. // Allows this contract to execute any arbitrary set of actions in other contracts. FunctionCall { receiver_id: AccountId, actions: Vec, }, // Upgrade this contract with given hash from blob store. UpgradeSelf { hash: Base58CryptoHash }, // Upgrade another contract, by calling method with the code from given hash from blob store. UpgradeRemote { receiver_id: AccountId, method_name: String, hash: Base58CryptoHash, }, // Transfers given amount of `token_id` from this DAO to `receiver_id`. // If `msg` is not None, calls `ft_transfer_call` with given `msg`. Fails if this base token. // For `ft_transfer` and `ft_transfer_call` `memo` is the `description` of the proposal. Transfer { // Can be "" for `$NEAR` or a valid account id. token_id: OldAccountId, receiver_id: AccountId, amount: U128, msg: Option, }, // Sets staking contract. Can only be proposed if staking contract is not set yet. SetStakingContract { staking_id: AccountId }, // Add new bounty. AddBounty { bounty: Bounty }, // Indicates that given bounty is done by given user. BountyDone { bounty_id: u64, receiver_id: AccountId, }, // Just a signaling vote, with no execution. Vote, // Change information about factory and auto update. FactoryInfoUpdate { factory_info: FactoryInfo }, // Add new role to the policy. If the role already exists, update it. This is short cut to updating the whole policy. ChangePolicyAddOrUpdateRole { role: RolePermission }, // Remove role from the policy. This is short cut to updating the whole policy. ChangePolicyRemoveRole { role: String }, // Update the default vote policy from the policy. This is short cut to updating the whole policy. ChangePolicyUpdateDefaultVotePolicy { vote_policy: VotePolicy }, // Update the parameters from the policy. This is short cut to updating the whole policy. ChangePolicyUpdateParameters { parameters: PolicyParameters }, } #[near(serializers = [json])] pub struct ProposalInput { /// Description of this proposal. pub description: String, /// Kind of proposal with relevant information. pub kind: ProposalKind, } // Validator interface, for cross-contract calls #[ext_contract(ext_dao_contract)] trait ExternalDaoContract { fn add_proposal(&mut self, proposal: ProposalInput) -> Promise; } // Implement the contract structure #[near] impl Contract { #[payable] pub fn create_proposal(&mut self, proposal: ProposalInput) -> Promise { let promise = ext_dao_contract::ext(self.dao_contract.clone()) .with_attached_deposit(env::attached_deposit()) .with_static_gas(Gas(5\*TGAS)) .add_proposal(proposal); return promise.then( // Create a promise to callback query_greeting_callback Self::ext(env::current_account_id()) .with_static_gas(Gas(50*TGAS)) .external_proposal_callback() ) } #[private] // Public - but only callable by env::current_account_id() pub fn external_proposal_callback(&self, #[callback_result] call_result: Result) -> Option { if call_result.is_err() { log!("There was an error contacting external contract"); return None; } // Return the proposal id let id = call_result.unwrap(); return Some(id); } } ``` By default, only **council members** can create proposals. *** ## Vote for proposal These snippet will enable your users to cast a vote for proposal of a particular DAO. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const DAO_CONTRACT_ADDRESS = 'primitives.sputnik-dao.near'; const { callFunction } = useNearWallet(); await callFunction({ contractId: DAO_CONTRACT_ADDRESS, method: 'act_proposal', args: { id: 0, action: 'VoteApprove' }, gas: 300000000000000, }); ``` Available vote options: `VoteApprove`, `VoteReject`, `VoteRemove`. Learn more about adding [Near Connect](../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call primitives.sputnik-dao.near act_proposal '{"id": 0, "action": "VoteApprove"}' --gas 300000000000000 --useAccount bob.near ``` Available vote options: `VoteApprove`, `VoteReject`, `VoteRemove`. Available vote options: `VoteApprove`, `VoteReject`, `VoteRemove`. ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} // Set of possible action to take #[near(serializers = [json, borsh])] #[derive(Debug)] pub enum Action { // Action to add proposal. Used internally. AddProposal, // Action to remove given proposal. Used for immediate deletion in special cases. RemoveProposal, // Vote to approve given proposal or bounty. VoteApprove, // Vote to reject given proposal or bounty. VoteReject, // Vote to remove given proposal or bounty (because it's spam). VoteRemove, // Finalize proposal, called when it's expired to return the funds // (or in the future can be used for early proposal closure). Finalize, // Move a proposal to the hub to shift into another DAO. MoveToHub, } // Validator interface, for cross-contract calls #[ext_contract(ext_dao_contract)] trait ExternalDaoContract { fn act_proposal(&mut self, id: u64, action: Action, memo: Option) -> Promise; } // Implement the contract structure #[near] impl Contract { #[payable] pub fn act_proposal(&mut self, id: u64, action: Action, memo: Option) -> Promise { let promise = ext_dao_contract::ext(self.dao_contract.clone()) .with_attached_deposit(env::attached_deposit()) .with_static_gas(Gas(10\*TGAS)) .act_proposal(id, action, memo); return promise.then( // Create a promise to callback query_greeting_callback Self::ext(env::current_account_id()) .external_common_callback() ) } #[private] // Public - but only callable by env::current_account_id() pub fn external_common_callback(&self, #[callback_result] call_result: Result<(), PromiseError>) { // Check if the promise succeeded if call_result.is_err() { log!("There was an error contacting external contract") } } } ``` *** ## Additional Resources 1. [NEAR Treasury](https://neartreasury.com/) - a Treasury management web app built on top of the Sputnik DAO Contract. Allows users to create and manage treasury funds with ease. # Decentralized Exchanges (DEX) Source: https://docs.near.org/primitives/dex Learn how to interact with decentralized exchanges on NEAR Protocol, including token swapping, liquidity pools, and integration with Ref Finance DEX. A Decentralized Exchange (DEX) is an application that allows users to trade tokens (native & fungible tokens) through smart contracts. dex In brief, DEXs work by having [pools of token pairs](https://guide.rhea.finance/products/overview/pooling) (e.g. NEAR-USDC) that users can deposit tokens into. The ratio of the tokens in the pool determines the exchange rate for a swap. Indeed, swapping is adding tokens to one side of the pool while removing tokens from the other side of the pool. This docs refer to [Ref Finance](https://www.ref.finance/), a community built DEX in NEAR. Please check their [docs](https://guide.rhea.finance/) for more information. *** ## Query Token Exchange Rate One can query the exchange rate of a token pair by calling the `get-token-price` method on the DEX contract. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} const tokenContract = 'token.v2.ref-finance.near'; const tokenPriceResult = await fetch( `https://indexer.ref.finance/get-token-price?token_id=${tokenContract}`, ); const tokenPriceValue = await tokenPriceResult.json(); ```

```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "token_contract_id": "token.v2.ref-finance.near", "price": "0.08153090" } ```

Ref Finance has a method to [get all token prices at once](https://indexer.ref.finance/list-token-price).
*** ## Query Whitelisted Tokens Anyone list tokens for sale in the DEX. This is why, in order to protect users, the DEX contract has a list of whitelisted tokens that can be traded. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near view v2.ref-finance.near get_whitelisted_tokens ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} 'wrap.near', 'usdt.tether-token.near', 'berryclub.ek.near', 'farm.berryclub.ek.near', 'token.v2.ref-finance.near', 'token.paras.near', 'marmaj.tkn.near', 'meta-pool.near', ... ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} 'wrap.near', 'usdt.tether-token.near', 'berryclub.ek.near', 'farm.berryclub.ek.near', 'token.v2.ref-finance.near', 'token.paras.near', 'marmaj.tkn.near', 'meta-pool.near', ... ``` *** ## Register in the DEX In order to use the contract, make sure to register your account in the DEX by paying for the storage you will use in order to keep track of your balances. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call v2.ref-finance.near storage_deposit '' --useAccount --amount 0.1 ``` *** ## Deposit funds In order to swap tokens, one must first deposit tokens into the DEX. For this, you will need to transfer the FT you want to swap to the DEX contract. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call token.v2.ref-finance.near ft_transfer_call {"receiver_id": "v2.ref-finance.near", "amount": "1000000000000", "msg": ""} --gas 300000000000000 --depositYocto 1 --useAccount ``` Do **NOT** transfer **NEAR** tokens to Ref Finance. Instead, call `near_deposit` in the [`wrap.near`](https://nearblocks.io/address/wrap.near) contract, attaching the amount of NEAR you want to swap. This will mint `wrap.near` for you, which you can then transfer to Ref Finance. *** ## Get Deposit Balances Query your deposit balances by calling the `get_deposits` method: ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const AMM_CONTRACT_ADDRESS = 'v2.ref-finance.near'; const { viewFunction } = useNearWallet(); await viewFunction({ method: 'get_deposits', args: { account_id: 'bob.near', }, contractId: AMM_CONTRACT_ADDRESS, }); ``` Learn more about adding [Near Connect](../web3-apps/tutorials/wallet-login) to your application

```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "token.v2.ref-finance.near": "0", "wrap.near": "0" } ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near view v2.ref-finance.near get_deposits '{"account_id": "bob.near"}' ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} { 'token.v2.ref-finance.near': '0', 'wrap.near': "0" } ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} { 'token.v2.ref-finance.near': '0', 'wrap.near': "0" } ```

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} // Validator interface, for cross-contract calls #[ext_contract(ext_amm_contract)] trait ExternalAmmContract { fn get_deposits(&self, account_id: AccountId) -> Promise; } // Implement the contract structure #[near] impl Contract { #[private] // Public - but only callable by env::current_account_id() pub fn external_get_deposits_callback(&self, #[callback_result] call_result: Result, PromiseError>) -> Option> { // Check if the promise succeeded if call_result.is_err() { log!("There was an error contacting external contract"); return None; } // Return the pools data let deposits_data = call_result.unwrap(); return Some(deposits_data); } pub fn get_contract_deposits(&self) -> Promise { let promise = ext_amm_contract::ext(self.amm_contract.clone()) .get_deposits(env::current_account_id()); return promise.then( // Create a promise to callback query_greeting_callback Self::ext(env::current_account_id()) .external_get_deposits_callback() ) } } ```
*** ### Query Pools DEXs work by having multiple pools of token pairs (e.g. NEAR-USDC) that users can deposit tokens into. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const AMM_CONTRACT_ADDRESS = 'v2.ref-finance.near'; const { viewFunction } = useNearWallet(); await viewFunction({ method: 'get_pools', args: { from_index: 0, limit: 1000, }, contractId: AMM_CONTRACT_ADDRESS, }); ``` Learn more about adding [Near Connect](../web3-apps/tutorials/wallet-login) to your application

```js theme={"theme":{"light":"github-light","dark":"github-dark"}} [ { pool_kind: 'SIMPLE_POOL', token_account_ids: ['token.skyward.near', 'wrap.near'], amounts: ['51865812079751349630100', '6254162663147994789053210138'], total_fee: 30, shares_total_supply: '1305338644973934698612124055', amp: 0, }, { pool_kind: 'SIMPLE_POOL', token_account_ids: [ 'c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2.factory.bridge.near', 'wrap.near', ], amounts: ['783621938569399817', '1100232280852443291118200599'], total_fee: 30, shares_total_supply: '33923015415693335344747628', amp: 0, }, ]; ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near view v2.ref-finance.near get_pools '{"from_index": 0, "limit": 1000}' ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} [ { pool_kind: 'SIMPLE_POOL', token_account_ids: [ 'token.skyward.near', 'wrap.near' ], amounts: [ '51865812079751349630100', '6254162663147994789053210138' ], total_fee: 30, shares_total_supply: '1305338644973934698612124055', amp: 0 }, { pool_kind: 'SIMPLE_POOL', token_account_ids: [ 'c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2.factory.bridge.near', 'wrap.near' ], amounts: [ '783621938569399817', '1100232280852443291118200599' ], total_fee: 30, shares_total_supply: '33923015415693335344747628', amp: 0 } ] ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} [ { pool_kind: 'SIMPLE_POOL', token_account_ids: [ 'token.skyward.near', 'wrap.near' ], amounts: [ '51865812079751349630100', '6254162663147994789053210138' ], total_fee: 30, shares_total_supply: '1305338644973934698612124055', amp: 0 }, { pool_kind: 'SIMPLE_POOL', token_account_ids: [ 'c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2.factory.bridge.near', 'wrap.near' ], amounts: [ '783621938569399817', '1100232280852443291118200599' ], total_fee: 30, shares_total_supply: '33923015415693335344747628', amp: 0 } ] ```

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} #[near(serializers = [json])] pub struct PoolInfo { /// Pool kind. pub pool_kind: String, /// List of tokens in the pool. pub token_account_ids: Vec, /// How much NEAR this contract has. pub amounts: Vec, /// Fee charged for swap. pub total_fee: u32, /// Total number of shares. pub shares_total_supply: U128, pub amp: u64, } // Validator interface, for cross-contract calls #[ext_contract(ext_amm_contract)] trait ExternalAmmContract { fn get_pools(&self, from_index: u64, limit: u64) -> Promise; } // Implement the contract structure #[near] impl Contract { #[private] // Public - but only callable by env::current_account_id() pub fn external_get_pools_callback(&self, #[callback_result] call_result: Result, PromiseError>) -> Option> { // Check if the promise succeeded if call_result.is_err() { log!("There was an error contacting external contract"); return None; } // Return the pools data let pools_data = call_result.unwrap(); return Some(pools_data); } pub fn get_amm_pools(&self, from_index: u64, limit: u64) -> Promise { let promise = ext_amm_contract::ext(self.amm_contract.clone()) .get_pools(from_index, limit); return promise.then( // Create a promise to callback query_greeting_callback Self::ext(env::current_account_id()) .external_get_pools_callback() ) } } ```
*** ## Swap tokens In order to swap a token for another, you need to [have funds](#deposit-funds), and there needs to [**exist a pool**](#query-pools) that has **both tokens** on it. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const AMM_CONTRACT_ADDRESS = 'v2.ref-finance.near'; const { callFunction } = useNearWallet(); await callFunction({ contractId: AMM_CONTRACT_ADDRESS, method: 'swap', args: { actions: [ { pool_id: 79, token_in: 'token.v2.ref-finance.near', token_out: 'wrap.near', amount_in: '100000000000000000', min_amount_out: '1', }, ], }, gas: 300000000000000, deposit: 1, }); ``` Learn more about adding [Near Connect](../web3-apps/tutorials/wallet-login) to your application ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} "5019606679394603179450" ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call v2.ref-finance.near swap "{\"actions\": [{\"pool_id\": 79, \"token_in\": \"token.v2.ref-finance.near\", \"amount_in\": \"100000000000000000\", \"token_out\": \"wrap.near\", \"min_amount_out\": \"1\"}]}" --gas 300000000000000 --depositYocto 1 --useAccount bob.near ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} '5019606679394603179450' ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} '5019606679394603179450' ```

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} #[near(serializers = [json])] pub struct SwapAction { /// Pool which should be used for swapping. pub pool_id: u64, /// Token to swap from. pub token_in: AccountId, /// Amount to exchange. /// If amount_in is None, it will take amount_out from previous step. /// Will fail if amount_in is None on the first step. pub amount_in: Option, /// Token to swap into. pub token_out: AccountId, /// Required minimum amount of token_out. pub min_amount_out: U128, } // Validator interface, for cross-contract calls #[ext_contract(ext_amm_contract)] trait ExternalAmmContract { fn swap(&self, actions: Vec) -> Promise; } // Implement the contract structure #[near] impl Contract { #[private] // Public - but only callable by env::current_account_id() pub fn external_call_callback(&self, #[callback_result] call_result: Result) { // Check if the promise succeeded if call_result.is_err() { log!("There was an error contacting external contract"); } } #[payable] pub fn swap_tokens(&mut self, pool_id: u64, token_in: AccountId, token_out: AccountId, amount_in: U128, min_amount_out: U128) -> Promise { assert_eq!(env::attached_deposit(), 1, "Requires attached deposit of exactly 1 yoctoNEAR"); let swap_action = SwapAction { pool_id, token_in, token_out, amount_in: Some(amount_in), min_amount_out }; let mut actions = Vec::new(); actions.push(swap_action); let promise = ext_amm_contract::ext(self.amm_contract.clone()) .with_static_gas(Gas(150*TGAS)) .with_attached_deposit(YOCTO_NEAR) .swap(actions); return promise.then( // Create a promise to callback query_greeting_callback Self::ext(env::current_account_id()) .with_static_gas(Gas(100*TGAS)) .external_call_callback() ) } } ```
*** ## Additional Resources 1. [Claim Fungible Tokens from Lockup](https://near.org/near/widget/ComponentDetailsPage?src=whtt.near/widget/Draft-0) - the example how to claim locked tokens from the `lockup.burrow.near` contract. 2. [BSC Dex Collection](https://near.org/near/widget/ComponentDetailsPage?src=bluebiu.near/widget/Bsc.Swap.Dex) - the example of how to build simple swap page for a DEX. # Decentralized Identifiers (DIDs) Source: https://docs.near.org/primitives/didnear Learn about W3C-compliant identity resolution on NEAR. This document details how to use the `did:near` method for decentralized identifiers on the NEAR blockchain, how it complies with [W3C DID Core](https://www.w3.org/TR/did-core/), and how it integrates with verifiable credentials (VCs), proof registries, and resolution tooling. *** ## What is a DID? A **Decentralized Identifier (DID)** is a persistent, unique identifier that does not require a centralized registry. On NEAR, DIDs are created based on either account names or raw public keys, and they are fully compatible with the W3C DID standard. Built in collaboration with NTT DATA Innovation Center Web3 *** ## The `did:near` Method This method supports two types of DIDs with different resolution strategies: | Type | Example | Description | | --------------------- | ------------------------------------------------------- | ------------------------------------------------------------------- | | Named Account | `did:near:alice.testnet` or `did:near:alice.near` | Resolved directly from on-chain NEAR account keys (FullAccess keys) | | Registry DID (Base58) | `did:near:CF5RiJYh4EVmEt8UADTjoP3XaZo1NPWxv6w5TmkLqjpR` | Resolved via smart contract registry using `identity_owner` method | *** ## DID Document Format Example output from resolving a `did:near`: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "@context": [ "https://www.w3.org/ns/did/v1", "https://w3id.org/security/suites/ed25519-2018/v1" ], "id": "did:near:alice.testnet", "verificationMethod": [ { "id": "did:near:alice.testnet#owner", "type": "Ed25519VerificationKey2018", "controller": "did:near:alice.testnet", "publicKeyBase58": "7WLUHT69sw5UpYK9xAY5cbdWKf4vSMruXzwfbL999zXo" } ], "authentication": ["did:near:alice.testnet#owner"], "assertionMethod": ["did:near:alice.testnet#owner"] } ``` This structure follows the [W3C DID Core Spec](https://www.w3.org/TR/did-core/), including: * A DID identifier (`id`) * Key references (`verificationMethod`) * Authentication and assertion capabilities * Base58-encoded Ed25519 public keys *** ## ⚙️ Repositories | Component | Repository URL | | ----------------------- | -------------------------------------------------------------------------------------------------------- | | DID Registry (contract) | [https://github.com/DTI-web3/did-near](https://github.com/DTI-web3/did-near) | | ProofType Contract | [https://github.com/DTI-web3/did-near-prooftype](https://github.com/DTI-web3/did-near-prooftype) | | ProofType SDK | [https://www.npmjs.com/package/@kaytrust/prooftypes](https://www.npmjs.com/package/@kaytrust/prooftypes) | | DID Resolver SDK | [https://github.com/DTI-web3/did-near-resolver](https://github.com/DTI-web3/did-near-resolver) | *** ## How Resolution Works The resolver uses different strategies based on DID format: ### Named Account DIDs (`did:near:alice.testnet`) 1. Parse the account ID from the DID (e.g., `alice.testnet`). 2. Determine the network from the suffix (`.testnet` → testnet, `.near` → mainnet). 3. Query the NEAR RPC using `near-api-js` to fetch account access keys. 4. Filter for keys with `permission: "FullAccess"`. 5. Construct the DID document with all FullAccess public keys as verification methods. ### Registry DIDs (`did:near:CF5RiJYh4EVmEt8UADTjoP3XaZo1NPWxv6w5TmkLqjpR`) 1. Identify the DID as Base58 format (44-50 character string matching `[1-9A-HJ-NP-Za-km-z]+`). 2. Call the `identity_owner` view method on the configured registry contract. 3. Retrieve the owner DID registered for that Base58 identifier. 4. Construct the DID document with the public key from the registry. *** ## How to Use ### Create a DID #### Named Account DID (Direct Resolution) If using a NEAR wallet account, the DID is derived directly from the account name: ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} const did = "did:near:yourname.testnet"; // For testnet const did = "did:near:yourname.near"; // For mainnet ``` #### Registry DID (Contract-Based) If using a Base58-encoded identifier registered in a smart contract: ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} const did = "did:near:CF5RiJYh4EVmEt8UADTjoP3XaZo1NPWxv6w5TmkLqjpR"; ``` #### Network-Specific DIDs You can explicitly specify the network: ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} const did = "did:near:testnet:CF5RiJYh4EVmEt8UADTjoP3XaZo1NPWxv6w5TmkLqjpR"; // Explicitly targets testnet const did = "did:near:near:CF5RiJYh4EVmEt8UADTjoP3XaZo1NPWxv6w5TmkLqjpR"; // Explicitly targets mainnet ``` *** ## Issuing and Verifying Credentials ### Step 1 – Hash the Credential ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} const cid = SHA256(JSON.stringify(credential)).toString(CryptoJS.enc.Base64); ``` ### Step 2 – Issue on NEAR ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} await proofType.generateProof(credential, { wallet, cid }); ``` This records the hash (`cid`) on-chain with the `subject_did`. ### Step 3 – Verify On-chain ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} const isValid = await proofType.verifyProof("did:near:subject|bafy..."); // returns true or false ``` *** ## SDK Usage ### Resolver SDK #### Standalone Usage ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} import { NearDIDResolver } from '@kaytrust/did-near-resolver'; const resolver = new NearDIDResolver({ networks: [ { networkId: 'testnet', rpcUrl: 'https://rpc.testnet.near.org', contractId: 'neardidregistry.testnet' // Optional: only for Registry DIDs }, { networkId: 'mainnet', // You can use 'near' for mainnet (or 'mainnet', both are equivalent) rpcUrl: 'https://rpc.mainnet.near.org', contractId: 'neardidregistry.near' // Optional } ] }); const doc = await resolver.resolveDID("did:near:alice.testnet"); console.log(doc.id); // "did:near:alice.testnet" ``` #### Integration with `did-resolver` ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} import { Resolver } from 'did-resolver'; import { getResolver } from '@kaytrust/did-near-resolver'; const nearResolver = getResolver({ networks: [ { networkId: 'testnet', rpcUrl: 'https://rpc.testnet.near.org', contractId: 'neardidregistry.testnet' } ] }); const resolver = new Resolver({ ...nearResolver, // ... other DID methods }); const result = await resolver.resolve('did:near:alice.testnet'); console.log(result.didDocument); ``` ### ProofType SDK ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} import { ProofTypeNear } from '@kaytrust/prooftypes'; const proofType = new ProofTypeNear(); const proof = await proofType.generateProof(vcPayload, { wallet, cid }); const isValid = await proofType.verifyProof(proof); ``` *** ## Security & Compliance * Each `(did, cid)` pair can only be registered once. * Issuer is linked to the signer account via NEAR transaction. * DID resolution and structure is fully W3C-compliant. * `cid` is always a Base64-encoded SHA-256 hash of the VC content. * **Key Security**: Only `FullAccess` keys are included in the DID document's `verificationMethod` array, ensuring that only keys with complete account authority are used for authentication. * Public keys are handled securely via NEAR native accounts or custom registries. * **Multi-Network Support**: The resolver automatically routes requests to the correct network (mainnet/testnet) based on the DID suffix. *** ## Testnet Deployment * Registry Contract: `neardidregistry.testnet` * ProofType Contract: `neardtiprooftype.testnet` * Network: `testnet` * Language: Rust (`near-sdk`) *** ## Conclusion The `did:near` method enables full-stack decentralized identity flows on NEAR, including: * Account- and key-based identifiers * W3C-compliant DID documents * Smart contract-backed credential proofs * SDKs for resolution and attestation Use this stack to build portable, verifiable, and secure Web3 identity solutions on NEAR. # Using FTs Source: https://docs.near.org/primitives/ft/ft Learn how to create, transfer, and integrate FT in your dApp Wanting to use Fungible Tokens (FT) in your dApp? Here you will find all the information you need to get started creating your own tokens, registering users , querying balances, transferring tokens, and integrating them into your smart contracts. *** ## Creating a New Token The simplest way to create a new Fungible Token is by interacting with a factory contract, to which you only need to provide the token metadata, and they will automatically deploy and initialize a [canonical FT contract](https://github.com/near-examples/FT). Here is how to directly interact with the factory contract through your application: ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const TOKEN_FACTORY_ADDRESS = 'token.primitives.near'; const { callFunction } = useNearWallet(); const args = { args: { owner_id: 'bob.near', total_supply: '1000000000', metadata: { spec: 'ft-1.0.0', name: 'Test Token', symbol: 'test', icon: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7', decimals: 18, }, }, account_id: 'bob.near', }; await callFunction({ contractId: TOKEN_FACTORY_ADDRESS, method: 'create_token', args, gas: 300000000000000, deposit: '2234830000000000000000', }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call token.primitives.near create_token '{"args":{"owner_id": "bob.near","total_supply": "1000000000","metadata":{"spec": "ft-1.0.0","name": "Test Token","symbol": "TTTEST","icon": "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7","decimals": 18}},"account_id": "bob.near"}' --gas 300000000000000 --depositYocto 2234830000000000000000000 --useAccount bob.near ``` The FT you create will live in the account `.token.primitives.near` (e.g. `test.token.primitives.near`). *** ## Deploying Your Own Contract You can also create a fungible token by deploying and initializing a [canonical FT contract](https://github.com/near-examples/FT). On initialization, you will define the token's metadata such as its name (e.g. Ethereum), symbol (e.g. ETH) and total supply (e.g. 10M). You will also define an `owner`, which will own the tokens **total supply**. To initialize a FT contract you will need to deploy it and then call the `new` method defining the token's metadata. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} cargo near deploy build-non-reproducible-wasm \ with-init-call new \ json-args '{ "owner_id": "", "total_supply": "1000000000000000", "metadata": { "spec": "ft-1.0.0", "name": "Example Token Name", "symbol": "EXLT", "decimals": 8 } }' \ prepaid-gas '100.0 Tgas' \ attached-deposit '0 NEAR' \ network-config testnet \ sign-with-keychain send ``` ### Global Contracts You can deploy a new Fungible Token using our global FT contract - a pre-deployed [standard FT contract](https://github.com/near-examples/FT) that you can reuse. [Global contracts](../../smart-contracts/global-contracts) are deployed once and can be reused by any account without incurring high storage costs. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract deploy use-global-account-id ft.globals.primitives.testnet \ with-init-call \ new_default_meta \ json-args '{"owner_id": "", "total_supply": "100000000000000000000000000000"}' \ prepaid-gas '100.0 Tgas' \ attached-deposit '0 NEAR' \ network-config testnet \ sign-with-keychain send ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract deploy use-global-hash 3vaopJ7aRoivvzZLngPQRBEd8VJr2zPLTxQfnRCoFgNX \ with-init-call \ new_default_meta \ json-args '{"owner_id": "", "total_supply": "100000000000000000000000000000"}' \ prepaid-gas '100.0 Tgas' \ attached-deposit '0 NEAR' \ network-config testnet \ sign-with-keychain send ``` Deploying by **hash** creates an immutable contract that never changes. Deploying by **account ID** creates an updatable contract that changes when the referenced account's contract is updated. Choose based on whether you want your FT contract to be updatable or permanent. *** ## Querying Metadata You can query the FT's metadata by calling the `ft_metadata`. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const TOKEN_CONTRACT_ADDRESS = 'token.v2.ref-finance.near'; const { viewFunction } = useNearWallet(); await viewFunction({ method: 'ft_metadata', args: {}, contractId: TOKEN_CONTRACT_ADDRESS, }); ```

```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "spec": "ft-1.0.0", "name": "Ref Finance Token", "symbol": "REF", "icon": "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='16 24 248 248' style='background: %23000'%3E%3Cpath d='M164,164v52h52Zm-45-45,20.4,20.4,20.6-20.6V81H119Zm0,18.39V216h41V137.19l-20.6,20.6ZM166.5,81H164v33.81l26.16-26.17A40.29,40.29,0,0,0,166.5,81ZM72,153.19V216h43V133.4l-11.6-11.61Zm0-18.38,31.4-31.4L115,115V81H72ZM207,121.5h0a40.29,40.29,0,0,0-7.64-23.66L164,133.19V162h2.5A40.5,40.5,0,0,0,207,121.5Z' fill='%23fff'/%3E%3Cpath d='M189 72l27 27V72h-27z' fill='%2300c08b'/%3E%3C/svg%3E%0A", "reference": null, "reference_hash": null, "decimals": 18 } ```

Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near view token.v2.ref-finance.near ft_metadata ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} { spec: "ft-1.0.0", name: "Ref Finance Token", symbol: "REF", icon: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='16 24 248 248' style='background: %23000'%3E%3Cpath d='M164,164v52h52Zm-45-45,20.4,20.4,20.6-20.6V81H119Zm0,18.39V216h41V137.19l-20.6,20.6ZM166.5,81H164v33.81l26.16-26.17A40.29,40.29,0,0,0,166.5,81ZM72,153.19V216h43V133.4l-11.6-11.61Zm0-18.38,31.4-31.4L115,115V81H72ZM207,121.5h0a40.29,40.29,0,0,0-7.64-23.66L164,133.19V162h2.5A40.5,40.5,0,0,0,207,121.5Z' fill='%23fff'/%3E%3Cpath d='M189 72l27 27V72h-27z' fill='%2300c08b'/%3E%3C/svg%3E%0A", reference: null, reference_hash: null, decimals: 18 } ```

*** ## Checking Balance To know how many coins a user has you will need to query the method `ft_balance_of`. Remember about fungible token precision. You may need this value to show a response of balance requests in an understandable-to-user way in your app. How to get precision value (decimals) you may find [here](#querying-metadata). ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const TOKEN_CONTRACT_ADDRESS = 'token.v2.ref-finance.near'; const { viewFunction } = useNearWallet(); await viewFunction({ method: 'ft_balance_of', args: { account_id: 'bob.near', }, contractId: TOKEN_CONTRACT_ADDRESS, }); ```

```json theme={"theme":{"light":"github-light","dark":"github-dark"}} "3479615037675962643842" ```

Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near view token.v2.ref-finance.near ft_balance_of '{"account_id": "bob.near"}' ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} '376224322825327177426' ```

*** ## Registering a User In order for a user to own and transfer tokens they need to first **register** in the contract. This is done by calling `storage_deposit` and attaching 0.00125Ⓝ. By calling this `storage_deposit` the user can register themselves or **register other users**. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const TOKEN_CONTRACT_ADDRESS = 'token.v2.ref-finance.near'; const { callFunction } = useNearWallet(); await callFunction({ contractId: TOKEN_CONTRACT_ADDRESS, method: 'storage_deposit', args: { account_id: 'alice.near', }, deposit: 1250000000000000000000, }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call token.v2.ref-finance.near storage_deposit '{"account_id": "alice.near"}' --depositYocto 1250000000000000000000 --useAccount bob.near ``` You can make sure a user is registered by calling `storage_balance_of`. After a user calls the `storage_deposit` the FT will appear in their Wallets. *** ## Transferring Tokens To send FT to another account you will use the `ft_transfer` method, indicating the receiver and the amount of FT you want to send. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const TOKEN_CONTRACT_ADDRESS = 'token.v2.ref-finance.near'; const { callFunction } = useNearWallet(); await callFunction({ contractId: TOKEN_CONTRACT_ADDRESS, method: 'ft_transfer', args: { receiver_id: 'alice.near', amount: '100000000000000000', }, deposit: 1, }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call token.v2.ref-finance.near ft_transfer '{"receiver_id": "alice.near", "amount": "100000000000000000"}' --depositYocto 1 --useAccount bob.near ``` ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} #[near] impl Contract { #[payable] pub fn send_tokens(&mut self, receiver_id: AccountId, amount: U128) -> Promise { assert_eq!(env::attached_deposit(), 1, "Requires attached deposit of exactly 1 yoctoNEAR"); let promise = ext(self.ft_contract.clone()) .with_attached_deposit(YOCTO_NEAR) .ft_transfer(receiver_id, amount, None); return promise.then( // Create a promise to callback query_greeting_callback Self::ext(env::current_account_id()) .with_static_gas(Gas(30*TGAS)) .external_call_callback() ) } #[private] // Public - but only callable by env::current_account_id() pub fn external_call_callback(&self, #[callback_result] call_result: Result<(), PromiseError>) { // Check if the promise succeeded if call_result.is_err() { log!("There was an error contacting external contract"); } } } ``` *This snippet assumes that the contract is already holding some FTs and that you want to send them to another account.* *** ## Attaching FTs to a Call Natively, only NEAR tokens (Ⓝ) can be attached to a function calls. However, the FT standard enables to **attach fungible tokens** in a call by using the FT-contract as intermediary. This means that, instead of you attaching tokens directly to the call, you ask the FT-contract to do both a transfer and a function call in your name. Let's assume that you need to deposit FTs on [Ref Finance](https://rhea.finance/). ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const TOKEN_CONTRACT_ADDRESS = 'token.v2.ref-finance.near'; const { callFunction } = useNearWallet(); await callFunction({ contractId: TOKEN_CONTRACT_ADDRESS, method: 'ft_transfer_call', args: { receiver_id: 'v2.ref-finance.near', amount: '100000000000000000', msg: '', }, gas: 300000000000000, deposit: 1, }); ```

```json theme={"theme":{"light":"github-light","dark":"github-dark"}} "100000000000000000" ```

Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application
```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call token.v2.ref-finance.near ft_transfer_call '{"receiver_id": "v2.ref-finance.near", "amount": "100000000000000000", "msg": ""}' --gas 300000000000000 --depositYocto 1 --useAccount bob.near ```

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} '100000000000000000' ```

```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} #[payable] pub fn call_with_attached_tokens(&mut self, receiver_id: AccountId, amount: U128) -> Promise { assert_eq!(env::attached_deposit(), 1, "Requires attached deposit of exactly 1 yoctoNEAR"); let promise = ext(self.ft_contract.clone()) .with_static_gas(Gas(150*TGAS)) .with_attached_deposit(YOCTO_NEAR) .ft_transfer_call(receiver_id, amount, None, "".to_string()); return promise.then( // Create a promise to callback query_greeting_callback Self::ext(env::current_account_id()) .with_static_gas(Gas(100*TGAS)) .external_call_callback() ) } ```
How it works: 1. You call `ft_transfer_call` in the FT contract passing: the receiver, a message, and the amount. 2. The FT contract transfers the amount to the receiver. 3. The FT contract calls `receiver.ft_on_transfer(sender, msg, amount)` 4. The FT contract handles errors in the `ft_resolve_transfer` callback. 5. The FT contract returns you how much of the attached amount was actually used. *** ## Handling Deposits If you want your contract to handle deposit in FTs you have to implement the `ft_on_transfer` method. When executed, such method will know: * Which FT was transferred, since it is the predecessor account. * Who is sending the FT, since it is a parameter * How many FT were transferred, since it is a parameter * If there are any parameters encoded as a message The `ft_on_transfer` must return how many FT tokens have to **be refunded**, so the FT contract gives them back to the sender. Here is an example from our [auctions tutorial](../../web3-apps/tutorials/mastering-near/3.2-ft) where we implement `ft_on_transfer` to handle bids in FTs: *Note: The [`near_contract_standards::fungible_token::receiver`](https://docs.rs/near-contract-standards/latest/near_contract_standards/fungible_token/receiver/trait.FungibleTokenReceiver.html) module exposes a `FungibleTokenReceiver` trait that you could implement on your contract* *** ## Burn Tokens While the FT standard does not define a `burn` method, you can simply transfer tokens to an account that no one controls, such as [`0000000000000000000000000000000000000000000000000000000000000000`](https://nearblocks.io/es/address/0000000000000000000000000000000000000000000000000000000000000000) (64 zeros). ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const { callFunction } = useNearWallet(); await callFunction({ contractId: 'token.v2.ref-finance.near', method: 'ft_transfer', args: { receiver_id: '0000000000000000000000000000000000000000000000000000000000000000', amount: '100000000000000000', }, deposit: 1, }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call token.v2.ref-finance.near ft_transfer '{"receiver_id": "0000000000000000000000000000000000000000000000000000000000000000", "amount": "100000000000000000"}' --depositYocto 1 --useAccount bob.near ``` *** ## Additional Resources 1. [NEP-141 standard](https://github.com/near/NEPs/tree/master/neps/nep-0141.md) 2. [NEP-148 standard](https://github.com/near/NEPs/tree/master/neps/nep-0148.md) 3. [FT Event Standards](https://github.com/near/NEPs/blob/master/neps/nep-0300.md) 4. [FT reference implementation](https://github.com/near-examples/FT) 5. [Fungible Tokens 101](../../smart-contracts/tutorials/zero-to-hero/fts) - a set of tutorials that cover how to create a FT contract using Rust. # Creating a FT Contract Source: https://docs.near.org/primitives/ft/sdk-contract-tools Learn how to create a fungible token (FT) using Contract Tools package In this tutorial, we will create a fungible token (FT) using the [NEAR SDK Contract Tools](https://github.com/near/near-sdk-contract-tools) package. This package is a collection of common tools and patterns to simplify smart contract development, including: * Storage fee management * Escrow pattern and derive macro * Owner pattern and derive macro * Pause pattern and derive macro * Role-based access control * Derive macros for [NEP standards](./standard) * NEP-141 (fungible token), extension NEP-148 * NEP-145 (storage management), and integrations for the fungible token and non-fungible token standards * NEP-171 (non-fungible token), extensions NEP-177, NEP-178, NEP-181 * NEP-297 (events) *** ## Introduction While one can create a fungible token (FT) contract from scratch using only the `near-sdk` and `near_contract_standards` (e.g. [FT contract](https://github.com/near-examples/FT)), a simpler approach is to use `near-sdk-contract-tools`. `near-sdk-contract-tools` allows us implement the logic for minting/burning logic, access control, and other FT standards by simply deriving macros on our contract struct, as `OpenZeppelin` does for Ethereum contracts. *** ## Basic FT Methods To derive basic FT methods to our contract, we need to derive `FungibleToken` macro to our contract struct: This will bring all the basic FT methods defined in NEP-141 standard to our contract: * `new` * `contract_source_metadata` * `ft_balance_of` * `ft_metadata` * `ft_total_supply` * `storage_balance_bounds` * `storage_balance_of` * `ft_resolve_transfer` * `ft_transfer` * `ft_transfer_call` * `storage_deposit` * `storage_unregister` * `storage_withdraw` To bring basic owner methods to our contract, we can also derive the `Owner` macro which adds the following methods: * `own_get_owner` * `own_get_proposed_owner` * `own_accept_owner` * `own_propose_owner` * `own_renounce_owner` *** ## Initialization To initialize the basic FT contract with custom owner, metadata and storage bounds implement `new` method: *** ## Transfer Hook If we want to customize how the transfer of tokens work (i.e. modify the `ft_transfer` method), we need to implement a hook. Hooks are a way to **wrap (inject code before and after)** component functions: Then derive it to our contract struct: *** ## Minting By default, the FT standards do not include a minting method. However, we can easily mint tokens for the owner by implementing a `mint` method, which only the owner can call: You can modify this method as you need, for example, to allow minting only when the contract is not paused (requires deriving [`Pausable`](https://github.com/near/near-sdk-contract-tools/tree/develop?tab=readme-ov-file#macro-combinations) hook), or to allow minting only to specific accounts with a certain role or from whitelist with custom limitations *** ## Burning In the same way that minting is not included in the FT standards, burning is also not included. However, we can also easily implement it. To burn tokens from the owner's account, we can add a `burn` method which is also only callable by the owner: *** ## Conclusion Using `near-sdk-contract-tools` is a very simple and flexible way to create FT contract with minimal boilerplate which allows us to focus on the business logic. You can further extend this contract with more features like pausing, role-based access control, escrow pattern, and more by deriving corresponding macros from the package. **Need help?** Visit the [NEAR Discord](https://near.chat) or [NEAR Forum](https://forum.near.org) if you have questions or need support. # The Standard Source: https://docs.near.org/primitives/ft/standard Learn how Fungible Tokens (FT) are defined on NEAR Besides the native NEAR token, users have access to a multitude of tokens created by institutions and other users known as fungible tokens. In contrast with the native token, fungible token (FT) are **not stored** in the user's account, but rather in a smart contract. Such contract is in charge of doing **bookkeeping**, i.e. to track how many tokens each user has, and to handle transfers internally. FT In order for a contract to be considered a FT contract it has to follow the [**NEP-141**](https://github.com/near/NEPs/tree/master/neps/nep-0141.md) and [**NEP-148 standards**](https://github.com/near/NEPs/tree/master/neps/nep-0148.md)which define the **minimum interface** required to be implemented, as well as the expected functionality. *** ## NEP-141 (Fungible Token Interface) [NEP-141](https://github.com/near/NEPs/tree/master/neps/nep-0141.md) is the blueprint for all fungible tokens (e.g. stablecoins, governance tokens, etc.) on NEAR. It defines a **common set of rules** and **functions** that the contract MUST implement to be considered a fungible token contract. Notice that the NEP-141 defines the **interface** and **expected behavior** of a fungible token contract, but it does not dictate how the internal logic should be implemented Different FT contracts can have different internal implementations while still adhering to the NEP-141 standard ### Interface #### `ft_total_supply` (*read-only*) Returns the total supply of the token ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} ft_total_supply(): string ```
#### `ft_balance_of` (*read-only*) Returns the balance of a given account ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} ft_balance_of(account_id: string): string ```
#### `ft_transfer` Transfers `amount` of tokens from the account calling the function to a `receiver_id`, optionally the function can include a `memo` field to provide additional information to the contract > *Requirement: The caller must attach [exactly 1 yoctoNEAR](../../smart-contracts/security/one_yocto) to the call* ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} ft_transfer(receiver_id: string, amount: string, memo: string?): void ```
#### `ft_transfer_call` The function transfers `amount` of tokens to the `receiver_id` **and calls the method `ft_on_transfer(sender_id, amount, msg)`** on `receiver_id`. Optionally the function can include a `memo` for the FT contract, and a `msg` field to which will be sent to the receiver contract. > 📖 This function is useful to transfer tokens to a contract and trigger some action on the receiver side in a single transaction, thus acting as **attaching fungible tokens to a function call**. > *Requirement: The caller must attach [exactly 1 yoctoNEAR](../../smart-contracts/security/one_yocto) to the call* ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} ft_transfer_call(receiver_id: string, amount: string, memo: string?, msg: string): void ``` Smart contracts expecting to **receive** Fungible Tokens **must** implement this method. The method **must** return the amount of tokens that were **NOT used** by the receiver, so that the **sender can be refunded**. ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} ft_on_transfer(sender_id: string, amount: string, msg: string): string ``` ⚠️ Note that this method does not need to be implemented by the FT contract itself, but rather by any contract that expects to receive fungible tokens See a reference implementation in the [using FTs page](./ft#handling-deposits)
#### `ft_resolve_transfer` This method is used as a [callback](../../smart-contracts/anatomy/crosscontract#callback-function) to resolve the `ft_transfer_call` transaction, handling refunds if necessary. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} ft_resolve_transfer(sender_id: string, receiver_id: string, amount: string): string ``` *** ## NEP-145 (Storage Management) On NEAR, accounts need to pay for the storage they use on the network. As more users hold tokens on a fungible token contract, more information needs to be stored, and thus the contract needs to reserve more storage. [NEP-145](https://github.com/near/NEPs/blob/master/neps/nep-0145.md) is a standard that defines a common interface for registering users, allowing FT contracts to **charge users for the storage they use**. While not mandatory, it is highly recommended for FT contracts to implement the NEP-145 standard to avoid running out of storage ### Interface #### `storage_balance_bounds` (*read-only*) Returns the minimum and maximum storage balance required for an account to be registered with the contract ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} storage_balance_bounds(): { min: string, max?: string} | null ``` #### `storage_balance_of` (*read-only*) Returns the storage balance of a given account, or `null` if the account is not registered ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} storage_balance_of(account_id: string): { total: string, available: string } | null ``` #### `storage_unregister` Removes all information from an account from the contract, returning the storage deposit to the user. The function can only be called by the user themselves. ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} storage_unregister(force?: boolean): boolean ``` #### `storage_deposit` Registers an account with the contract, reserving enough storage to keep track of the user's balance. The function can be called by the user themselves **or by a third party** on behalf of the user. ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} storage_deposit(account_id?: string, registration_only?: boolean): { total: string, available: string } ``` #### `storage_withdraw` Unregisters an account from the contract, returning the storage deposit to the user. The function can only be called by the user themselves. ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} storage_withdraw(amount: string): { total: string, available: string } ``` *** ## NEP-148 (Token Metadata) [NEP-148](https://github.com/near/NEPs/tree/master/neps/nep-0141.md) is an extension to the NEP-141 standard that defines the fungible tokens **metadata**. Metadata provides **key information** about the token, such as its **name, symbol, and decimal precision**, particularly, the following fields MUST be included in the token's metadata: * `spec`: a string. Should be `ft-1.0.0` to indicate that a Fungible Token contract adheres to the current versions of this Metadata and the \[Fungible Token Core]\[FT Core] specs * `name`: the human-readable name of the token * `symbol`: the abbreviation, like wETH or AMPL * `decimals`: used in frontends to show the proper significant digits of a token The metadata is useful for wallets and other user interfaces to display the token correctly, for example if a token is defined as: ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "spec": "ft-1.0.0", "name": "My Awesome Token", "symbol": "MAT", "decimals": 4 } ``` A balance of `123456` units of such token should be displayed in a user interface as `12.3456 MAT`. # Using Linkdrops Source: https://docs.near.org/primitives/linkdrop/linkdrop Learn about linkdrops following NEP-452 standard - distribute assets and onboard users to Web3 apps through simple web links using access keys and the Keypom platform. Wanting to use Linkdrops in your dApp? Here you will find all the information you need to get started. The simplest way to create a linkdrop is by interacting with our LinkDrop Generator *** ## AccessKeys In order to create any kind of drop, you need to first generate key pairs. You will need to create **one key per drop**. * The `linkdrop` contract will store the **`public`** part of the key. * You will give the `private` part of the key to the user you want to receive the drop. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { KeyPair } from 'near-api-js'; const newKeyPair = KeyPair.fromRandom('ed25519'); newKeyPair.public_key = newKeyPair.publicKey.toString(); ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near generate-key # Key pair with ed25519:33Vn9VtNEtWQPPd1f4jf5HzJ5weLcvGHU8oz7o5UnPqy public key for an account "1e5b1346bdb4fc5ccd465f6757a9082a84bcacfd396e7d80b0c726252fe8b3e8" ```

Generate a new key on [Lantstool](https://app.lantstool.dev/)

lantstool
*** ## `$NEAR` Drops To create a `$NEAR` drop you will ask the contract to create a drop (`create_drop`), passing the public part of the keys you generated, and how much you want to drop on each key use (`deposit_per_use`). The contract will create a drop and **return the numerical ID** that identifies it. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const KEYPOM_CONTRACT_ADDRESS = "v2.keypom.near"; const DROP_AMOUNT = "10000000000000000000000"; // 0.1 NEAR const { callFunction } = useNearWallet(); await callFunction({ contractId: KEYPOM_CONTRACT_ADDRESS, method: "create_drop", args: { public_keys: state.publicKeys, deposit_per_use: DROP_AMOUNT, }, deposit: "23000000000000000000000", // state.publicKeys.length * dropAmount + 3000000000000000000000 gas: "100000000000000", }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call v2.keypom.near create_drop '{"public_keys": , "deposit_per_use": "10000000000000000000000"}' --depositYocto 23000000000000000000000 --gas 100000000000000 --useAccount bob.near ``` To claim the drop, you will need to send the user a [link with the private key](#building-drop-links) *** ## NFT Drops To drop an existing NFT, you will (1) create a drop, and then (2) **transfer the NFT** to keypom. #### 1. Creating the Drop To create an NFT drop, you will call the `create_drop` method, now passing a `nft` argument, which will tell the linkdrop contract to wait for an NFT to be transferred. The contract will then create a drop and **return the numerical ID** that identifies it. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const KEYPOM_CONTRACT_ADDRESS = "v2.keypom.near"; const NFT_CONTRACT_ADDRESS = "nft.primitives.near"; const DROP_AMOUNT = "10000000000000000000000"; const { callFunction, accountId } = useNearWallet(); await callFunction({ contractId: KEYPOM_CONTRACT_ADDRESS, method: "create_drop", args: { public_keys: state.publicKeys, deposit_per_use: DROP_AMOUNT, nft: { // Who will be sending the NFTs to the Keypom contract sender_id: accountId, // NFT Contract Id that the tokens will come from contract_id: NFT_CONTRACT_ADDRESS, }, }, deposit: "23000000000000000000000", // state.publicKeys.length * dropAmount + 3000000000000000000000 gas: "100000000000000", }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call v2.keypom.near create_drop '{"public_keys": , "deposit_per_use": "10000000000000000000000", "nft": {"sender_id": "bob.near", "contract_id": "nft.primitives.near"}}' --depositYocto 23000000000000000000000 --gas 100000000000000 --useAccount bob.near ``` #### 2. Transferring the NFT Having the Drop ID, you now need to transfer the NFT to the linkdrop contract, specifying to which drop you want to add it. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const KEYPOM_CONTRACT_ADDRESS = "v2.keypom.near"; const NFT_CONTRACT_ADDRESS = "nft.primitives.near"; const NFT_TOKEN_ID = "1"; const { callFunction } = useNearWallet(); await callFunction({ contractId: NFT_CONTRACT_ADDRESS, method: "nft_transfer_call", args: { receiver_id: KEYPOM_CONTRACT_ADDRESS, token_id: NFT_TOKEN_ID, msg: dropId.toString() }, deposit: 1, gas: "100000000000000", }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call nft.primitives.near nft_transfer_call '{"receiver_id": "v2.keypom.near", "token_id": , "msg": }' --depositYocto 1 --gas 100000000000000 --useAccount bob.near ``` The `linkdrop` contract will validate that you are transferring the NFT to a drop that belongs to you The simplest way to create a linkdrop is by interacting with our LinkDrop Generator *** ## FT Drops The process to drop a Fungible Token is very similar to that of creating an [NFT drop](#nft-drops). You will first create the drop, and then fund it with FTs. #### 1.Creating a drop To create a FT drop you will call the `create_drop` method, now passing a `ftData` argument, which will tell the linkdrop contract to wait for a certain amount of FT to be transferred. The contract will then create a drop and **return the numerical ID** that identifies it. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const KEYPOM_CONTRACT_ADDRESS = "v2.keypom.near"; const FT_CONTRACT_ADDRESS = "ft.primitives.near"; const DROP_AMOUNT = "10000000000000000000000"; const { callFunction, accountId } = useNearWallet(); await callFunction({ contractId: KEYPOM_CONTRACT_ADDRESS, method: "create_drop", args: { public_keys: state.publicKeys, deposit_per_use: DROP_AMOUNT, ftData: { contractId: FT_CONTRACT_ADDRESS, senderId: accountId, // This balance per use is balance of human readable FTs per use. amount: "1" // Alternatively, you could use absoluteAmount, which is dependent on the decimals value of the FT // ex. if decimals of an ft = 8, then 1 FT token would be absoluteAmount = 100000000 }, }, deposit: "23000000000000000000000", // state.publicKeys.length * dropAmount + 3000000000000000000000 gas: "100000000000000", }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call v2.keypom.near create_drop '{"public_keys": , "deposit_per_use": "10000000000000000000000", "ftData": {"contractId": "ft.primitives.near","senderId": "bob.near", "amount": "1"}}}' --depositYocto 23000000000000000000000 --gas 100000000000000 --useAccount bob.near ``` #### 2. Transferring FT Having the Drop ID, you now need to transfer the fungible tokens to the linkdrop contract. To transfer FTs to an account, you need to first [register](/primitives/ft/ft#registering-a-user) the receiver account (e.g. the keypom contract) on the FT contract. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const KEYPOM_CONTRACT_ADDRESS = "v2.keypom.near"; const FT_CONTRACT_ADDRESS = "ft.primitives.near"; const { callFunction } = useNearWallet(); await callFunction({ contractId: FT_CONTRACT_ADDRESS, method: "ft_transfer", args: { receiver_id: KEYPOM_CONTRACT_ADDRESS, amount: "1" }, deposit: "1", gas: "100000000000000" }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call ft.primitives.near ft_transfer '{"receiver_id": "v2.keypom.near", "amount": "1"}' --depositYocto 1 --gas 100000000000000 --useAccount bob.near ``` The simplest way to create a linkdrop is by interacting with our LinkDrop Generator *** ## Function Call Drop Linkdrop contracts allow to create `function call` drops. These drops will execute one or more methods on a contract when the user claims the drop. Function call drops can be thought as the abstract version of other drops: you can create a drop that will mint an NFT, register a user in a DAO, or pay for a service. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const KEYPOM_CONTRACT_ADDRESS = "v2.keypom.near"; const NFT_CONTRACT_ADDRESS = "nft.primitives.near"; const NFT_TOKEN_ID = "1"; const DROP_AMOUNT = "10000000000000000000000"; const { callFunction } = useNearWallet(); await callFunction({ contractId: KEYPOM_CONTRACT_ADDRESS, method: "create_drop", args: { public_keys: state.publicKeys, deposit_per_use: DROP_AMOUNT, fcData: { // 2D array of function calls. In this case, there is 1 function call to make for a key use // By default, if only one array of methods is present, this array of function calls will be used for all key uses methods: [ // Array of functions for Key use 1. [{ receiverId: NFT_CONTRACT_ADDRESS, methodName: "nft_mint", args: JSON.stringify({ // Change this token_id if it already exists -> check explorer transaction token_id: NFT_TOKEN_ID, metadata: { title: "My NFT drop", description: "", media: "", } }), accountIdField: "receiver_id", // Attached deposit for when the receiver makes this function call attachedDeposit: "10000000000000000000000" }] ] } }, deposit: "23000000000000000000000", // state.publicKeys.length * dropAmount + 3000000000000000000000 gas: "100000000000000", }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call v2.keypom.near create_drop '{"public_keys": , "deposit_per_use": "10000000000000000000000", "fcData": {"methods": [[{"receiverId": "nft.primitives.near","methodName": "nft_mint","args": {"token_id": "1", "metadata": {"title": "My NFT drop","description": "","media": ""}, "accountIdField": "receiver_id", "attachedDeposit": "10000000000000000000000"}]]}}' --depositYocto 23000000000000000000000 --gas 100000000000000 --useAccount bob.near ``` *** ## Building drop links To create a linkdrop link, simply append the private key to the `claim` page: ```text theme={"theme":{"light":"github-light","dark":"github-dark"}} http://localhost:3001/claim/linkdrop?id=ed25519:5Ly2arHZ4niWBVyEuzpN3J8QQX1BrYfWsirGqdYR3JfqUDhJ3SRK7JeQfVsh4UL8Wn6uf8RzWE4RPHymkePywVVd ``` # The Standard Source: https://docs.near.org/primitives/linkdrop/standard Learn how Linkdrops are defined on NEAR Linkdrops allow users to distribute assets and onboard people to Web3 apps through a simple web link. Linkdrop They work by storing assets and linking [AccessKeys](../../protocol/accounts-contracts/access-keys) to them. The `AccessKeys` are then distributed to users in the form of web links. These links take users to a website that automatically uses the keys to call the `claim` method in the `linkdrop` contract. In order for a contract to be considered a Linkdrop-contract it has to follow the [**NEP-452 standard**](https://github.com/near/NEPs/blob/master/neps/nep-0452.md). The **NEP-452** explains the **minimum interface** required to be implemented, as well as the expected functionality. *** ## NEP-452 (Linkdrop Standard) [NEP-452](https://github.com/near/NEPs/blob/master/neps/nep-0452.md) is the blueprint for all linkdrop contracts on NEAR. It defines a **common set of rules** and **functions** that the contract MUST implement to be considered a linkdrop contract. Notice that the NEP-452 defines the **interface** and **expected behavior** of a linkdrop contract, but it does not dictate how the internal logic should be implemented Different linkdrop contracts can have different internal implementations while still adhering to the NEP-452 standard ### Interface #### `get_key_balance` (*read-only*) Allows to query the amount of NEAR tokens assigned to a specific linkdrop key ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} get_key_balance(key: string): string; ```
#### `get_key_information` (*read-only*) Returns information about a specific linkdrop key, including the amount of NEAR tokens assigned to it, the receiver ID, and whether the key has been claimed ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} interface NFTData { contract_id: string; token_id: string; } interface FTData { contract_id: string; amount: string; } get_key_information(key: string): { required_gas: string, yoctonear: string, nft_list: NFTData[], ft_list: FTData[] }; ```
#### `claim` Allows a user to claim the assets associated with a specific key. The function transfers the NEAR tokens, NFTs, and FTs assigned to the provided `account_id`, which MUST exist prior to calling this method. > ⚠️ Users need to call this method signing the transaction with the **linkdrop key they received**. ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} claim(account_id: string): boolean; ```
#### `create_account_and_claim` Allows a user to **create a new account** and **claim the assets** associated with a specific key. The function creates the new account with the provided `new_account_id` and transfers the NEAR tokens, NFTs, and FTs assigned to it. > ⚠️ Users need to call this method signing the transaction with the **linkdrop key they received**. ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} create_account_and_claim(new_account_id: string, new_public_key: string): Promise; ``` # Deploying Your Own Contract Source: https://docs.near.org/primitives/liquid-staking/deploy-your-own-contract Learn how to deploy your own Liquid Staking Contract on NEAR At its core, the Liquid Staking Contract issues a token that follows the [Fungible Token (NEP-141)](https://github.com/near/NEPs/blob/master/neps/nep-0141.md) standard. When you stake `NEAR`, you don’t just lock it away — you receive a liquid token (for example, `rNEAR`) that behaves like any other fungible token on the network. You can transfer it, swap it, or use it inside DeFi protocols exactly the same way you would with any other token. And, because it’s fully NEP-141 compatible, this token integrates seamlessly with wallets, DEXs, and other smart contracts. That compatibility is what enables the early-exit mechanism — you can instantly convert your liquid token back to `NEAR` by swapping it on an exchange. The swap rate is determined by market supply and demand and usually sits slightly below the on-chain rate (roughly 0.5% lower), which represents the small cost of immediate liquidity. Behind the scenes, the exchange rate of the liquid token is continuously adjusted based on rewards earned by validators. It’s calculated as `exchange_rate = total_staked_near / total_liquid_token_supply`​ and as staking rewards accumulate each epoch, the total amount of staked `NEAR` grows, while the token supply changes only when users deposit or withdraw. That’s why the exchange rate, and therefore the token’s value, steadily increases over time, even if you hold the same balance. *** ## Storage Deposit (NEP-145) Because the liquid staking contract issues a [NEP-141 token](https://github.com/near/NEPs/blob/master/neps/nep-0141.md), it also implements the [Storage Management (NEP-145)](https://github.com/near/NEPs/blob/master/neps/nep-0145.md) standard. Whenever you interact with the contract for the first time, for example, when you deposit `NEAR` and get liquid tokens in return, you need to attach a tiny storage deposit. This deposit covers the space your account information takes up in the contract’s storage. The good thing is that this money isn’t spent, it just stays reserved while you’re using the contract. And if you ever stop using it, you can get your deposit back by unregistering your account. In short, it’s a way to make sure the contract doesn’t pay for users’ data out of its own balance, while still letting everyone safely recover their deposit whenever they leave. *** ## Deploying a Liquid Staking Contract The Liquid Staking Contract can be deployed directly from the [repository](https://github.com/ref-finance/rnear-contract), which contains the implementation maintained by the Rhea.finance team. This contract follows the same principles described above and is already optimized for production use. Before deployment, make sure the target account has at least 20.5 `NEAR` available on its balance. This amount covers the initial storage costs, the minimum staking liquidity required for initialization, and a small gas buffer. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} # Clone the repository git clone https://github.com/ref-finance/rnear-contract.git cd rnear-contract/contracts/lst ## Create and fund the liquid staking account near create-account --useAccount --initialBalance # Build and deploy the liquid staking contract cargo near deploy build-non-reproducible-wasm with-init-call new json-args '{ "metadata": { "decimals": 24, "name": "Test Liquid Near Staking Token", "spec": "ft-1.0.0", "symbol": "tNEAR" }, "owner_id": "owner.near" }' prepaid-gas '100.0 Tgas' attached-deposit '0 NEAR' ``` ### Setting Validator Whitelist Account Before you can add validators, you first need to set the validator whitelist account. This account acts as a single source of truth for which validators are allowed to be used by the contract. The validator whitelist account must implement the following interface that allows the contract to verify if a given validator is approved. ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} #[ext_contract(ext_whitelist)] pub trait ExtWhitelist { fn is_whitelisted(&self, staking_pool_account_id: AccountId) -> bool; } ``` To update the validator whitelist account, please run the following command: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction set_whitelist_contract_id json-args '{ "account_id": "whitelist_source.near" }' prepaid-gas '30.0 Tgas' attached-deposit '1 yoctoNEAR' ``` ### Adding Validators After the whitelist account is in place, you can register a list of validators that the contract will delegate tokens to, along with their weights. Each weight defines a proportion of how much of the total stake should go to a particular validator compared to the others. To add validators, please run the following comand: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction add_validators json-args '{ "validator_ids": ["validator1.pool.near", "validator2.pool.near", "validator3.pool.near"], "weights": [40, 35, 25] }' prepaid-gas '30.0 Tgas' attached-deposit '1 yoctoNEAR' ``` *** ## Token In this section, we’ll go through a few of the most commonly used methods. To explore all available methods, please refer to the full definition of [NEP-141](https://github.com/near/NEPs/blob/master/neps/nep-0141.md). ### Storage Deposit Before you can hold or receive any liquid tokens, your account needs to be registered in the contract’s storage. You only need to do this once, and the amount is fully refundable if you ever unregister your account. To register the account, run the following command: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction storage_deposit json-args '{ "account_id":"", "registration_only": true }' prepaid-gas '30.0 Tgas' attached-deposit '0.00125 NEAR' ``` ### Check Balance To check how many liquid tokens (e.g., `tNEAR`) you own, run the following command: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-read-only ft_balance_of json-args '{"account_id": ""}' ``` ### Check Total Supply To check the total supply of the liquid token (e.g., `tNEAR`), run the following command: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-read-only ft_total_supply json-args '{}' ``` ### Transfer Tokens To transfer tokens to another account directly, run the following command: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction ft_transfer json-args '{ "amount": "10000000000000000000000000", "receiver_id":"" }' prepaid-gas '30.0 Tgas' attached-deposit '1 yoctoNEAR' ``` ### Check Token Price While most methods follow the NEP-141 standard, the liquid staking contract also provides an additional helper method called `ft_price`. This method isn’t part of the standard itself — it’s implemented specifically for this contract to make it easier to check the current exchange rate between the liquid token and `NEAR`, since the price of the token is determined by the formula: `exchange_rate = total_staked_near / total_liquid_token_supply` To query the current price, run the following command: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-read-only ft_price json-args '{}' ``` The returned number shows how much `yoctoNEAR` one unit of the liquid token is currently worth. *** ## Additional Resources For more information, explore the official resources below: * [Liquid Staking Contract Repository](https://github.com/ref-finance/rnear-contract) * [NEAR CLI](https://github.com/near/near-cli-rs) # Using Liquid Staking Source: https://docs.near.org/primitives/liquid-staking/liquid-staking Learn about Liquid Staking on NEAR — a smart contract that issues a fungible token representing staked NEAR, enabling instant liquidity and validator diversification. Liquid staking is a modern alternative to regular staking on NEAR that solves the problem of delayed withdrawing. In regular staking, you can't immediately withdraw funds from a staking pool - first, you need to request an unstake and then wait for 4 epochs (roughly 24-28 hours) before your funds become available for withdrawal. And the liquid staking contract addresses this limitation by giving a flexible approach that keeps your assets liquid. Are you looking to delegate NEAR Tokens to a **liquid staking provider**? Check out the [Metapool](https://www.metapool.app/es/stake?token=near), [Rhea Finance](https://app.rhea.finance/stake) *** ## Staking Pool The liquid staking contract implements a staking pool interface. From a developer’s perspective, interacting with a liquid staking contract feels almost identical to working with a regular staking pool. You can call familiar methods like `deposit_and_stake`, `unstake`, and `withdraw`, and they follow the same lifecycle - the only difference is that your stake is represented by a liquid token instead of being locked inside a single pool. Behind the scenes, the contract delegates tokens across multiple validators, usually selected from the top-performing ones on the network. These validators are actively maintained and closely monitored, which makes them far less likely to experience downtime or performance issues. And because your stake is distributed among many of them, the risk of losing rewards due to a single validator going offline becomes extremely low. It’s also worth noting that, since your stake is spread across several validators, the average reward rate will typically be slightly lower than if you delegated directly to a single, high-performing validator. But in return, you gain better security against validator outages and the ability to exchange your liquid token back to `NEAR` at any time without waiting through the unstaking delay. It’s a balanced trade-off between maximum yield and maximum flexibility. *** ## Using Liquid Staking Below are the most common commands you’ll use to interact with the staking flow, alongside with the contracts for major liquid staking providers on NEAR. | Provider | Testnet Account | Mainnet Account | | ------------ | ------------------------- | ---------------------- | | Metapool | `meta-v2.pool.testnet` | `meta-pool.near` | | Rhea Finance | | `lst.rhealab.near` | | Linear | `linear-protocol.testnet` | `linear-protocol.near` | ### Deposit and Stake Tokens To stake your `NEAR` and receive the liquid token, run the command: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction deposit_and_stake json-args '{}' prepaid-gas '30.0 Tgas' attached-deposit '10 NEAR' ``` From that point, your tokens begin generating rewards through the underlying validators. ### Unstake When you feel ready, simply request unstake with the following command. You will need to wait standard delay of 4 epochs (24-28 hours) for funds to become available for withdrawal. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction unstake_all json-args '{}' prepaid-gas '30.0 Tgas' attached-deposit '0 NEAR' ``` If you need your `NEAR` immediately, you don’t have to wait 4 epochs — you can simply swap your liquid tokens for `NEAR` on DEX like Rhea.finance. ### Withdraw As soon as 4 epochs have gone by, run the following command to withdraw `NEAR` tokens back. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction withdraw_all json-args '{}' prepaid-gas '30.0 Tgas' attached-deposit '0 NEAR' ``` At this point, your liquid tokens will be burned, and you’ll receive the equivalent amount of `NEAR` based on the current exchange rate. # Introduction Source: https://docs.near.org/primitives/lockup/introduction Learn about Lockup contracts on NEAR – smart contracts that escrow tokens with time-based release schedules, supporting lockups, vesting, staking, and termination by foundation. Lockup contracts act as escrows that hold tokens and release them gradually over time. They are widely used to manage employee compensation, investor vesting schedules, or long-term token allocations. Lockup contracts restrict token liquidity until predefined conditions are met by combining two key mechanisms: * **Lockup** – tokens remain locked until a certain date is reached. * **Vesting** – tokens are made available to the user, but might be released gradually. Through lockup and vesting, projects can enforce predictable token release schedules that align incentives and improve transparency. *** ## Lockup Schedule A lockup defines how tokens are released linearly over time. It is described by: * `lockup_timestamp` – when unlocking begins. * `release_duration` – how long the unlocking lasts.\ By the end, all tokens are available. * `finish_timestamp = lockup_timestamp + release_duration` ```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}} --- config: theme: "neutral" xyChart: width: 800 height: 300 showDataLabel: true themeVariables: xyChart: plotColorPalette: '#000000, #FF0000' --- xychart title "Linear Schedule" x-axis [before, lockup_timestamp, finish_timestamp, after] y-axis "Tokens Unlocked (in %)" 0 --> 100 line [0, 0, 100, 100] ``` *** ## Vesting Schedule Vesting adds additional conditions, typically used for employment or investment agreements: * `start_timestamp` – when vesting starts (e.g. hire date). * `cliff_timestamp` – the first time tokens vest (e.g. 1 year). * `end_timestamp` – when vesting completes. Example: A **4-year vesting** with a **1-year cliff** means: * Year 1: nothing vests. * At 1-year mark: 25% vests at once. * Remaining 75% vests linearly for the remaining 3 years. ```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}} --- config: theme: "neutral" xyChart: width: 800 height: 300 showDataLabel: true themeVariables: xyChart: plotColorPalette: '#000000' --- xychart title "Vested Schedule" x-axis [before, start_timestamp, cliff_timestamp, cliff_timestamp, end_timestamp, after] y-axis "Tokens Unlocked (in %)" 0 --> 100 line [0, 0, 0, 25, 100, 100] ``` *** ## Combined Schedule Lockup and vesting can be combined. Tokens become liquid only when both conditions allow: `liquidity_timestamp = max(lockup_timestamp, cliff_timestamp)` Depending on which event comes first, the outcome for the token release differs. ### Scenario A: Lockup before Cliff In this case, the lockup timestamp occurs earlier than the cliff timestamp. Although the lockup schedule would normally allow tokens to start unlocking, the vesting cliff has not yet passed. As a result, no tokens are liquid until the cliff. It introduces three key timestamps: * `lockup_timestamp` – occurs earlier than the vesting cliff * `cliff_timestamp` – comes later, so vesting delays liquidity * `end_timestamp` – when vesting fully completes ```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}} --- config: theme: "neutral" xyChart: width: 800 height: 300 showDataLabel: true themeVariables: xyChart: plotColorPalette: '#000000' --- xychart title "Combined Schedule: #A" x-axis [before, lockup_timestamp, cliff_timestamp, cliff_timestamp, end_timestamp, after] y-axis "Tokens Unlocked (in %)" 0 --> 100 line [0, 0, 0, 25, 100, 100] ``` ### Scenario B: Cliff before Lockup In this case, by the time the cliff is reached, 25% of tokens are considered vested. However, liquidity is still blocked because the lockup period has not ended. It introduces three key timestamps: * `cliff_timestamp` – occurs earlier than lockup * `lockup_timestamp` – comes later and delays liquidity unlock * `end_timestamp` – when vesting fully completes ```mermaid theme={"theme":{"light":"github-light","dark":"github-dark"}} --- config: theme: "neutral" xyChart: width: 800 height: 300 showDataLabel: true themeVariables: xyChart: plotColorPalette: '#000000' --- xychart title "Combined Schedule: #B" x-axis [before,cliff_timestamp, lockup_timestamp, lockup_timestamp, end_timestamp, after] y-axis "Tokens Unlocked (in %)" 0 --> 100 line [0, 0, 0, 25, 100, 100] ``` *** ## Termination by Foundation When the `foundation_account_id` is specified at initialization, this account is granted the right to terminate vesting before its natural completion. The effect of termination depends on whether it happens before or after the vesting cliff. * If termination occurs before the cliff date, none of the tokens are considered vested and the entire allocation is refunded back to the foundation. * If termination happens after the cliff, the portion that has already vested up to that point remains with the owner, while all of the remaining unvested tokens are returned to the foundation. This ensures that the owner never receives more than what has already vested, while giving the foundation a mechanism to reclaim the locked portion in case of early termination of the agreement. You’ll discover real examples as you continue reading. *** ## Staking with Locked Tokens The Lockup contract allows the owner to delegate tokens to a whitelisted staking pool, and it lets the owner to earn additional rewards while their base tokens remain locked. The process works as follows: * The owner selects a validator from the whitelist and stakes tokens through the lockup contract. * The staked amount itself remains locked according to the lockup and vesting schedules. * The validator generates staking rewards over time. A crucial distinction is that staking rewards are liquid immediately. They are not bound by the original lockup or vesting conditions. For example, if 1000 NEAR are locked and staked for one month, and 10 NEAR are earned as rewards, when the owner decides to unstake, the original 1000 NEAR follow the normal lockup and vesting restrictions, while any rewards already earned can be transferred directly to your account. # Lockup Contracts Source: https://docs.near.org/primitives/lockup/lockup Learn about Lockup contracts on NEAR – smart contracts that escrow tokens with time-based release schedules, supporting lockups, vesting, staking, and termination by foundation. Looking to manage token vesting and lockup schedules? NEAR's Lockup contracts provide a robust solution for escrowing tokens with time-based release mechanisms. *** ## Deploying a Lockup Contract The simplest way to deploy a new lockup contract is to use the existing [global contract](../../smart-contracts/global-contracts) already published on NEAR. It is important to understand that the **total amount of tokens to be locked is determined by the balance of the account at the moment of deployment**. Whatever tokens are in the account once you deploy the contract will become locked under the schedule you define. This means that you must always **first create and fund the lockup account** with the intended amount of tokens, and only after that deploy the contract. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} # Create and fund the lockup account near create-account --useAccount --initialBalance # Deploy the lockup contract near contract deploy use-global-hash CAvU5MYQ4xk1SjFvbnQDQUj6qehuW5YhU3FXA6GMddCx with-init-call new json-args '{ "owner_account_id": "employee.near", "lockup_duration": "0", "lockup_timestamp": "1535760000000000000", "release_duration": "126230400000000000", "transfers_information": { "TransfersEnabled": { "transfers_timestamp": "1602614338293769340" } }, "vesting_schedule": { "VestingSchedule": { "start_timestamp": "1535760000000000000", "cliff_timestamp": "1567296000000000000", "end_timestamp": "1661990400000000000" } }, "staking_pool_whitelist_account_id": "staking-pool-whitelist", "foundation_account_id": "foundation.near" }' prepaid-gas '30.0 Tgas' attached-deposit '0 NEAR' ``` * To use lockup only: omit the `vesting_schedule` property. * To use vesting only: set `lockup_timestamp` and `release_duration` to 0 and provide only the `vesting_schedule`. ### Checking Balance To see the owner’s balance, run the following command. The returned amount includes both the total amount of tokens in the contract and any staking rewards that are available for withdrawal. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-read-only get_owners_balance json-args '{}' ``` To see the liquid balance, run the following command. This will return the amount that is available for withdrawal, including unlocked tokens and staking rewards. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-read-only get_liquid_owners_balance json-args '{}' ``` ### Withdraw Tokens To transfer unlocked tokens to your account, please run the following command. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction transfer json-args '{ "amount": "10000000000000000000000000", "receiver_id":"owner.near" }' prepaid-gas '30.0 Tgas' attached-deposit '0 NEAR' ``` Requesting to withdraw amount that is greater than liquid won't go through ### Withdraw Tokens Once Fully Unlocked Once all tokens are fully vested and unlocked, you can convert your lockup account into a regular NEAR account by adding a full access key. This allows you to manage the account directly and withdraw the remaining tokens by leveraging the power of advanced technique, which includes deleting it account completely and specifying your account as beneficiary. Generate a new key pair and run the following command to add it as full access key to account, once the vesting/locking schedule is finished. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction add_full_access_key json-args '{ "new_public_key": "ed25519:8W9CiyPPehz2GRW8AYho9nx1z1GLdeZQCyn2wqYgJjiG" }' prepaid-gas '30.0 Tgas' attached-deposit '0 NEAR' ``` Keep in mind that you never should use the key from the command above. Generate your own key pair. Once the key is added, you’ll be able to delete it and transfer remaining funds to your account (replace `owner.near` with your address) with the following command. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near account delete-account beneficiary owner.near ``` Make sure all staked tokens are fully withdrawn before attempting to delete the account. If any tokens remain delegated to a staking pool, they will be lost once the account is deleted. *** ## Staking The Lockup contract allows the owner to delegate tokens to a whitelisted staking pool, and it lets the owner to earn additional rewards while their base tokens remain locked. Let’s walk through each step slowly, in the order you will typically execute the commands. ### Select Staking Pool Choose a validator from the whitelist configured at initialization, then set it on the lockup contract. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction select_staking_pool json-args '{ "staking_pool_account_id": "pool.testnet" }' prepaid-gas '30.0 Tgas' attached-deposit '0 NEAR' ``` ### Deposit and Stake Tokens Stake part of tokens, available on the lockup contract. The amount must be passed over in yoctoNEAR (1 NEAR = 10^24 yoctoNEAR). ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction deposit_and_stake json-args '{ "amount": "1000000000000000000000000000" }' prepaid-gas '125.0 Tgas' attached-deposit '0 NEAR' ``` ### Refresh Staking Pool Balance The rewards from staking pool won't be automatically reflected in the contract. This command synchronizes the contract’s internal balance with the staking pool. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction refresh_staking_pool_balance json-args '{}' prepaid-gas '30.0 Tgas' attached-deposit '0 NEAR' ``` Once that's done, notice that [liquid balance](#checking-balance) has changed. ### Unstake When you feel ready, simply request unstake with the following command. You will need to wait standard delay of 4 epochs for funds to become withdrawable from the pool. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call unstake_all json-args '{}' prepaid-gas '125.0 Tgas' attached-deposit '0 NEAR' ``` ### Withdraw As soon as 4 epochs have gone by, run the following command to move the funds from the staking pool back to the contract, including earned rewards. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call withdraw_all_from_staking_pool json-args '{}' prepaid-gas '175.0 Tgas' attached-deposit '0 NEAR' ``` Once that's done, earned rewards become part of liquid balance and [can be withdrawn to your account immediately](#withdraw-tokens). *** ## Termination (for Foundations) The lockup can be terminated early by a `foundation_account_id`, if it was specified during the initialization. Before the cliff, the entire allocation is refunded to the foundation. After the cliff, only the unvested portion is refunded, while the vested part remains with the owner. During termination, some owner actions are temporarily paused until the process completes. ### Initiate Start the termination process. After initiation, the contract may restrict owner actions until termination is finalized. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction terminate_vesting json-args '{}' prepaid-gas '25.0 Tgas' attached-deposit '0 NEAR' ``` ### Check Status The status tells you which step is safe to run next and prevents failed calls. For example, a deficit status means there're some tokens left on the staking pool and it [requires additional actions](#resolve-deficit-if-staked) from you. And, once the contract reports "Ready To Withdraw" status, the foundation can proceed to withdraw. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-read-only get_termination_status json-args '{}' ``` ### Resolve Deficit (if staked) If some tokens are staked and the contract shows a deficit (not enough liquid balance to refund the unvested portion), prepare the funds. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction termination_prepare_to_withdraw json-args '{}' prepaid-gas '175.0 Tgas' attached-deposit '0 NEAR' ``` You need to call it twice — once to start unstaking, and again after the 4 epoch delay to withdraw your funds. ### Withdraw Unvested Once the status is ready, withdraw the unvested portion to the foundation account. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract call-function as-transaction termination_withdraw json-args '{ "receiver_id": "foundation.near" }' prepaid-gas '75.0 Tgas' attached-deposit '0 NEAR' ``` *** ## Additional Resources For more information, explore the official resources below: * [Lockup Contract Repository](https://github.com/near/core-contracts/tree/master/lockup) * [NEAR CLI](https://github.com/near/near-cli-rs) # Using NFTs Source: https://docs.near.org/primitives/nft/nft Learn about NEAR non-fungible tokens (NFT) following NEP-171 and NEP-177 standards - mint, transfer, query, and trade unique digital assets with comprehensive examples. Wanting to use Non-Fungible Tokens (NFT) in your dApp? Here you will find all the information you need to get started creating your own tokens, registering users, transferring tokens, and integrating them into your smart contracts. *** ## Deploying a NFT Contract If you want to deploy your own NFT contract, you can create one using our [reference implementation](https://github.com/near-examples/NFT). ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near deploy --wasmFile contract.wasm --initFunction new ``` ### Global Contract You can deploy a new Non-Fungible Token using our global NFT contract - a pre-deployed [standard NFT contract](https://github.com/near-examples/NFT) that you can reuse. [Global contracts](../../smart-contracts/global-contracts) are deployed once and can be reused by any account without incurring high storage costs. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract deploy use-global-account-id nft.globals.primitives.testnet \ with-init-call new \ json-args '{"owner_id": "", "metadata": {"spec": "nft-1.0.0", "name": "MY_NFT", "symbol": "NFT2000", "icon": "data:image/svg+xml,%3Csvg xmlns='\''http://www.w3.org/2000/svg'\'' viewBox='\''0 0 288 288'\''%3E%3Cg id='\''l'\'' data-name='\''l'\''%3E%3Cpath d='\''M187.58,79.81l-30.1,44.69a3.2,3.2,0,0,0,4.75,4.2L191.86,103a1.2,1.2,0,0,1,2,.91v80.46a1.2,1.2,0,0,1-2.12.77L102.18,77.93A15.35,15.35,0,0,0,90.47,72.5H87.34A15.34,15.34,0,0,0,72,87.84V201.16A15.34,15.34,0,0,0,87.34,216.5h0a15.35,15.35,0,0,0,13.08-7.31l30.1-44.69a3.2,3.2,0,0,0-4.75-4.2L96.14,186a1.2,1.2,0,0,1-2-.91V104.61a1.2,1.2,0,0,1,2.12-.77l89.55,107.23a15.35,15.35,0,0,0,11.71,5.43h3.13A15.34,15.34,0,0,0,216,201.16V87.84A15.34,15.34,0,0,0,200.66,72.5h0A15.35,15.35,0,0,0,187.58,79.81Z'\''/%3E%3C/g%3E%3C/svg%3E"}}' \ prepaid-gas '100.0 Tgas' \ attached-deposit '0 NEAR' \ network-config testnet \ sign-with-keychain \ send ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near contract deploy use-global-hash ivu1e9obVRnMJLSvVPRgtYefUYUS1L3f5eYHjS86zL9 \ with-init-call new \ json-args '{"owner_id": "", "metadata": {"spec": "nft-1.0.0", "name": "MY_NFT", "symbol": "NFT2000", "icon": "data:image/svg+xml,%3Csvg xmlns='\''http://www.w3.org/2000/svg'\'' viewBox='\''0 0 288 288'\''%3E%3Cg id='\''l'\'' data-name='\''l'\''%3E%3Cpath d='\''M187.58,79.81l-30.1,44.69a3.2,3.2,0,0,0,4.75,4.2L191.86,103a1.2,1.2,0,0,1,2,.91v80.46a1.2,1.2,0,0,1-2.12.77L102.18,77.93A15.35,15.35,0,0,0,90.47,72.5H87.34A15.34,15.34,0,0,0,72,87.84V201.16A15.34,15.34,0,0,0,87.34,216.5h0a15.35,15.35,0,0,0,13.08-7.31l30.1-44.69a3.2,3.2,0,0,0-4.75-4.2L96.14,186a1.2,1.2,0,0,1-2-.91V104.61a1.2,1.2,0,0,1,2.12-.77l89.55,107.23a15.35,15.35,0,0,0,11.71,5.43h3.13A15.34,15.34,0,0,0,216,201.16V87.84A15.34,15.34,0,0,0,200.66,72.5h0A15.35,15.35,0,0,0,187.58,79.81Z'\''/%3E%3C/g%3E%3C/svg%3E"}}' \ prepaid-gas '100.0 Tgas' \ attached-deposit '0 NEAR' \ network-config testnet \ sign-with-keychain \ send ``` Deploying by **hash** creates an immutable contract that never changes. Deploying by **account ID** creates an updatable contract that changes when the referenced account's contract is updated. Choose based on whether you want your FT contract to be updatable or permanent. *** ## Minting a NFT To create a new NFT (a.k.a. minting it) you will call the `nft_mint` method passing as arguments the metadata that defines the NFT. Use the [NEAR NFT Minting Tool](https://near.org/near/widget/ComponentDetailsPage?src=near/widget/NFTMint) to mint your own NFT directly from your browser. Here is how to directly interact with the factory contract through your application: ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const CONTRACT_ADDRESS = 'nft.primitives.near'; const { callFunction } = useNearWallet(); await callFunction({ contractId: CONTRACT_ADDRESS, method: 'nft_mint', args: { token_id: '1', receiver_id: 'bob.near', token_metadata: { title: 'NFT Primitive Token', description: 'Awesome NFT Primitive Token', media: 'string', // URL to associated media, preferably to decentralized, content-addressed storage }, }, deposit: 10000000000000000000000, }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call nft.primitives.near nft_mint '{"token_id": "1", "receiver_id": "bob.near", "token_metadata": {"title": "NFT Primitive Token", "description": "Awesome NFT Primitive Token", "media": "string"}}' --depositYocto 10000000000000000000000, --useAccount bob.near ``` ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} // Validator interface, for cross-contract calls #[ext_contract(ext_nft_contract)] trait ExternalNftContract { fn nft_mint(&self, token_series_id: String, receiver_id: AccountId) -> Promise; } // Implement the contract structure #[near] impl Contract { #[payable] pub fn nft_mint(&mut self, token_series_id: String, receiver_id: AccountId) -> Promise { let promise = ext_nft_contract::ext(self.nft_contract.clone()) .with_static_gas(Gas(30*TGAS)) .with_attached_deposit(env::attached_deposit()) .nft_mint(token_series_id, receiver_id); return promise.then( // Create a promise to callback query_greeting_callback Self::ext(env::current_account_id()) .with_static_gas(Gas(30*TGAS)) .nft_mint_callback() ) } #[private] // Public - but only callable by env::current_account_id() pub fn nft_mint_callback(&self, #[callback_result] call_result: Result) -> Option { // Check if the promise succeeded if call_result.is_err() { log!("There was an error contacting NFT contract"); return None; } // Return the token data let token_id: TokenId = call_result.unwrap(); return Some(token_id); } } ``` See the [metadata standard](https://github.com/near/NEPs/tree/master/neps/nep-0177.md) for the full list of `TokenMetadata` parameters. Values of gas and deposit might vary depending on which NFT contract you are calling.
### Minting Collections Many times people want to create multiple 100 copies of an NFT (this is called a collection). In such cases, what you actually need to do is to mint 100 different NFTs with the same metadata (but different `token-id`). Notice that [minting in Mintbase](#minting-a-nft) allows you to pass a `num_to_mint` parameter.
### Royalties You might have noticed that one of the parameters is a structure called royalties. Royalties enable you to create a list of users that should get paid when the token is sell in a marketplace. For example, if `anna` has `5%` of royalties, each time the NFT is sell, `anna` should get a 5% of the selling price. *** ## Querying NFT data You can query the NFT's information and metadata by calling the `nft_token`. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const CONTRACT_ADDRESS = 'nft.primitives.near'; const { viewFunction } = useNearWallet(); const response = await viewFunction({ contractId: CONTRACT_ADDRESS, method: 'nft_token', args: { token_id: '1', }, }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "token_id": "1", "owner_id": "bob.near", "metadata": { "title": "string", // ex. "Arch Nemesis: Mail Carrier" or "Parcel #5055" "description": "string", // free-form description "media": "string", // URL to associated media, preferably to decentralized, content-addressed storage "media_hash": "string", // Base64-encoded sha256 hash of content referenced by the `media` field. Required if `media` is included. "copies": 1, // number of copies of this set of metadata in existence when token was minted. "issued_at": 1642053411068358156, // When token was issued or minted, Unix epoch in milliseconds "expires_at": 1642053411168358156, // When token expires, Unix epoch in milliseconds "starts_at": 1642053411068358156, // When token starts being valid, Unix epoch in milliseconds "updated_at": 1642053411068358156, // When token was last updated, Unix epoch in milliseconds "extra": "string", // anything extra the NFT wants to store on-chain. Can be stringified JSON. "reference": "string", // URL to an off-chain JSON file with more info. "reference_hash": "string" // Base64-encoded sha256 hash of JSON from reference field. Required if `reference` is included. } } ``` ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near view nft.primitives.near nft_token '{"token_id": "1"}' ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "token_id": "1", "owner_id": "bob.near", "metadata": { "title": "string", // ex. "Arch Nemesis: Mail Carrier" or "Parcel #5055" "description": "string", // free-form description "media": "string", // URL to associated media, preferably to decentralized, content-addressed storage "media_hash": "string", // Base64-encoded sha256 hash of content referenced by the `media` field. Required if `media` is included. "copies": 1, // number of copies of this set of metadata in existence when token was minted. "issued_at": 1642053411068358156, // When token was issued or minted, Unix epoch in milliseconds "expires_at": 1642053411168358156, // When token expires, Unix epoch in milliseconds "starts_at": 1642053411068358156, // When token starts being valid, Unix epoch in milliseconds "updated_at": 1642053411068358156, // When token was last updated, Unix epoch in milliseconds "extra": "string", // anything extra the NFT wants to store on-chain. Can be stringified JSON. "reference": "string", // URL to an off-chain JSON file with more info. "reference_hash": "string" // Base64-encoded sha256 hash of JSON from reference field. Required if `reference` is included. } } ``` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "token_id": "1", "owner_id": "bob.near", "metadata": { "title": "string", // ex. "Arch Nemesis: Mail Carrier" or "Parcel #5055" "description": "string", // free-form description "media": "string", // URL to associated media, preferably to decentralized, content-addressed storage "media_hash": "string", // Base64-encoded sha256 hash of content referenced by the `media` field. Required if `media` is included. "copies": 1, // number of copies of this set of metadata in existence when token was minted. "issued_at": 1642053411068358156, // When token was issued or minted, Unix epoch in milliseconds "expires_at": 1642053411168358156, // When token expires, Unix epoch in milliseconds "starts_at": 1642053411068358156, // When token starts being valid, Unix epoch in milliseconds "updated_at": 1642053411068358156, // When token was last updated, Unix epoch in milliseconds "extra": "string", // anything extra the NFT wants to store on-chain. Can be stringified JSON. "reference": "string", // URL to an off-chain JSON file with more info. "reference_hash": "string" // Base64-encoded sha256 hash of JSON from reference field. Required if `reference` is included. } } ``` ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} // Validator interface, for cross-contract calls #[ext_contract(ext_nft_contract)] trait ExternalNftContract { fn nft_token(&self, token_id: TokenId) -> Promise; } // Implement the contract structure #[near] impl Contract { pub fn nft_token(&self, token_id: TokenId) -> Promise { let promise = ext_nft_contract::ext(self.nft_contract.clone()) .nft_token(token_id); return promise.then( // Create a promise to callback query_greeting_callback Self::ext(env::current_account_id()) .nft_token_callback() ) } #[private] // Public - but only callable by env::current_account_id() pub fn nft_token_callback(&self, #[callback_result] call_result: Result) -> Option { // Check if the promise succeeded if call_result.is_err() { log!("There was an error contacting NFT contract"); return None; } // Return the token data let token_data: Token = call_result.unwrap(); return Some(token_data); } } ``` *** ## Transferring a NFT Transferring an NFT can happen in two scenarios: (1) you ask to transfer an NFT, and (2) an [authorized account](#approving-users) asks to transfer the NFT. In both cases, it is necessary to invoke the `nft_transfer` method, indicating the token id, the receiver, and an (optionally) an [approval\_id](https://github.com/near/NEPs/tree/master/neps/nep-0178.md). ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const CONTRACT_ADDRESS = 'nft.primitives.near'; const { callFunction } = useNearWallet(); await callFunction({ contractId: CONTRACT_ADDRESS, method: 'nft_transfer', args: { token_id: '1', receiver_id: 'bob.near', }, deposit: 1, }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call nft.primitives.near nft_transfer '{"token_id": "1", "receiver_id": "bob.near"}' --useAccount bob.near --deposit 0.000000000000000000000001 ``` Please notice that a contract can only transfer an NFT that they own, or an NFT that they were approved to transfer. ```rust theme={"theme":{"light":"github-light","dark":"github-dark"}} const YOCTO_NEAR: u128 = 1; #[ext_contract(ext_nft_contract)] trait ExternalNftContract { fn nft_transfer(&self, receiver_id: AccountId, token_id: TokenId) -> Promise; } impl Contract { #[payable] pub fn nft_transfer(&mut self, receiver_id: AccountId, token_id: TokenId) -> Promise { let promise = ext_nft_contract::ext(self.nft_contract.clone()) .with_attached_deposit(YOCTO_NEAR) .nft_transfer(receiver_id, token_id); return promise.then( // Create a promise to callback query_greeting_callback Self::ext(env::current_account_id()) .nft_transfer_callback() ) } #[private] // Public - but only callable by env::current_account_id() pub fn nft_transfer_callback(&self, #[callback_result] call_result: Result<(), PromiseError>) { // Check if the promise succeeded if call_result.is_err() { log!("There was an error contacting NFT contract"); } } } ``` *** ## Attaching NFTs to a Call Natively, only NEAR tokens (Ⓝ) can be attached to a function calls. However, the NFT standard enables to attach a non-fungible tokens in a call by using the NFT-contract as intermediary. This means that, instead of you attaching tokens directly to the call, you ask the NFT-contract to do both a transfer and a function call in your name. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call nft_transfer_call '{"receiver_id": "", "token_id": "", "msg": ""}' --useAccount --depositYocto 1 ``` Optionally, a [`memo` parameter](https://github.com/near/NEPs/tree/master/neps/nep-0171.md#nft-interface) can be passed to provide more information to your contract.
### How Does it Work? Assume you want to attach an NFT (🎫) to a call on the receiver contract. The workflow is as follows: 1. You call `nft_transfer_call` in the NFT-contract passing: the receiver, a message, and the token-id of 🎫. 2. The NFT contract transfers the NFT 🎫 to the receiver. 3. The NFT contract calls **`receiver.nft_on_transfer(sender, token-owner, token-id, msg)`**. 4. The NFT contract handles errors in the `nft_resolve_transfer` callback. 5. The NFT contract returns `true` if it succeeded. #### The nft\_on\_transfer method From the workflow above it follows that the receiver we want to call needs to implement the `nft_on_transfer` method. When executed, such method will know: * Who is sending the NFT, since it is a parameter * Who is the current owner, since it is a parameter * Which NFT was transferred, since it is a parameter. * If there are any parameters encoded as a message The `nft_on_transfer` **must return true** if the NFT has to be **returned to the sender**. *** ## Approving Users You can authorize other users to transfer an NFT you own. This is useful, for example, to enable listing your NFT in a marketplace. In such scenario, you **trust** that the marketplace will only transfer the NFT upon receiving a certain amount of money in exchange. ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call nft_approve '{ "token_id": "", "account_id": "", "msg": "" }' --useAccount --depositYocto 1 ``` If the `msg` parameter is included, then a cross-contract call will be made to `.nft_on_approve(msg)`. Which in turn will make a callback to `nft_resolve_transfer` in your NFT contract. *** ## Burn Tokens While the NFT standard does not define a `burn` method, you can simply transfer tokens to an account that no one controls, such as [`0000000000000000000000000000000000000000000000000000000000000000`](https://nearblocks.io/es/address/0000000000000000000000000000000000000000000000000000000000000000) (64 zeros). ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { useNearWallet } from "near-connect-hooks"; const { callFunction } = useNearWallet(); await callFunction({ contractId: 'nft.primitives.near', method: 'nft_transfer', args: { token_id: '1', receiver_id: '0000000000000000000000000000000000000000000000000000000000000000', }, deposit: 1, }); ``` Learn more about adding [Near Connect](../../web3-apps/tutorials/wallet-login) to your application ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call nft.primitives.near nft_transfer '{"token_id": "1", "receiver_id": "0000000000000000000000000000000000000000000000000000000000000000"}' --useAccount bob.near --deposit 0.000000000000000000000001 ``` *** ## Tutorials * [NFT Tutorial](/smart-contracts/tutorials/zero-to-hero/nfts-js) *Zero to Hero* (JavaScript SDK) - a set of tutorials that cover how to create a NFT contract using JavaScript. * [NFT Tutorial](/smart-contracts/tutorials/zero-to-hero/nfts) *Zero to Hero* (Rust SDK) - a set of tutorials that cover how to create a NFT contract using Rust. # Creating a NFT Contract Source: https://docs.near.org/primitives/nft/sdk-contract-tools Learn how to create a non-fungible token (NFT) using Contract Tools package In this tutorial, you will create a non-fungible token (NFT) using the [NEAR SDK Contract Tools](https://github.com/near/near-sdk-contract-tools) package. This package is a collection of common tools and patterns to simplify smart contract development, including: * Storage fee management * Escrow pattern and derive macro * Owner pattern and derive macro * Pause pattern and derive macro * Role-based access control * Derive macros for [NEP standards](./standard) * [NEP-141](https://github.com/near/NEPs/blob/master/neps/nep-0141.md) (fungible token), extension [NEP-148](https://github.com/near/NEPs/blob/master/neps/nep-0148.md) * [NEP-145](https://github.com/near/NEPs/blob/master/neps/nep-0145.md) (storage management), and integrations for the fungible token and non-fungible token standards * [NEP-171](https://github.com/near/NEPs/blob/master/neps/nep-0171.md) (non-fungible token), extensions [NEP-177](https://github.com/near/NEPs/blob/master/neps/nep-0177.md), [NEP-178](https://github.com/near/NEPs/blob/master/neps/nep-0178.md), [NEP-181](https://github.com/near/NEPs/blob/master/neps/nep-0181.md) * [NEP-297](https://github.com/near/NEPs/blob/master/neps/nep-0297.md) (events) *** ## Introduction While one can create a non-fungible token (NFT) contract from scratch using only the `near-sdk` and `near_contract_standards` (e.g. [NFT contract](https://github.com/near-examples/NFT)), a simpler approach is to use `near-sdk-contract-tools`. `near-sdk-contract-tools` allows you to implement the minting/burning logic, access control, and other NFT standards by simply deriving macros on the contract's `struct`, as `OpenZeppelin` does for Ethereum contracts. *** ## Basic NFT Methods To derive basic NFT methods to your smart contract, you need to derive the `NonFungibleToken` macro to the contract's `struct`: This will bring all the basic NFT methods to the contract: * `new` * `contract_source_metadata` * `nft_is_approved` * `nft_metadata` * `nft_supply_for_owner` * `nft_token` * `nft_tokens` * `nft_tokens_for_owner` * `nft_total_supply` * `nft_approve` * `nft_resolve_transfer` * `nft_revoke` * `nft_revoke_all` * `nft_transfer` * `nft_transfer_call` * `storage_balance_bounds` * `storage_balance_of` * `storage_deposit` * `storage_unregister` * `storage_withdraw` To bring basic owner methods to the contract, you also need to derive the `Owner` macro, which adds the following methods: * `own_get_owner` * `own_get_proposed_owner` * `own_accept_owner` * `own_propose_owner` * `own_renounce_owner` *** ## Initialization To initialize the basic NFT contract with a custom owner, metadata, and storage bounds, implement the `new` method: *** ## Transfer Hook If you want to customize how the token transfer works (i.e., modify the `nft_transfer` method), you need to implement a hook. Hooks are a way to **wrap (inject code before and after)** component functions: Then derive it to our contract struct: *** ## Minting By default, the NFT standards do not include a minting method. However, you can easily mint tokens for the owner by implementing an `nft_mint` method: You can modify this method as you need, for example, to allow minting only when the contract is not paused (requires deriving [`Pausable`](https://github.com/near/near-sdk-contract-tools/tree/develop?tab=readme-ov-file#macro-combinations) hook), or to enable minting only to specific accounts with a certain role or from a whitelist with custom limitations. *** ## Burning In the same way that minting is not included in the NFT standards, burning is also not included. However, you can also easily implement it. To allow users to burn their tokens, you can add a `burn` method: *** ## Conclusion Using `near-sdk-contract-tools` is a simple and flexible way to create an NFT contract with minimal boilerplate, which allows you to focus on the business logic. You can further extend this contract with more features like pausing, role-based access control, escrow pattern, and more by deriving corresponding macros from the package. # The Standard Source: https://docs.near.org/primitives/nft/standard Learn how Non-Fungible Tokens (NFT) are defined on NEAR In contrast with fungible tokens, non-fungible tokens (NFT) are unitary and therefore unique. This makes NFTs ideal to represent ownership of assets such as a piece of digital content, or a ticket for an event. As with fungible tokens, NFTs are **not stored** in the user's wallet, instead, each NFT lives in a **NFT contract**. The NFT contract works as a bookkeeper, being in charge of creating, storing and transferring NFTs. **NFT & Marketplaces** Be mindful of not confusing an NFT with an NFT-marketplace. NFT simply store information (metadata), while NFT-marketplaces are contracts where NFT can be listed and exchanged for a price. *** ## NEP-171 (NFT Interface) [NEP-171](https://github.com/near/NEPs/tree/master/neps/nep-0171.md) is the blueprint for all non-fungible tokens on NEAR. It defines a **common set of rules** and **functions** that the contract MUST implement to be considered a non-fungible token contract. Notice that the NEP-171 defines the **interface** and **expected behavior** of a non-fungible token contract, but it does not dictate how the internal logic should be implemented Different NFT contracts can have different internal implementations while still adhering to the NEP-171 standard ### Interface #### `nft_token` (*read-only*) Returns the token information for a given `token_id` ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} nft_token(token_id: string): { token_id: string, owner_id: string } | null ```
#### `nft_transfer` Transfers the `token_id` from the caller to the `receiver_id`, optionally the function can include a `memo` field to provide additional information to the contract The caller must be the **either** the current owner of the token or an **account** that has been **approved to transfer** the token on behalf of the owner, such as a marketplace contract. The approval mechanism is defined in the [NEP-178 standard](https://github.com/near/NEPs/blob/master/neps/nep-0178.md). > *Requirement: The caller must attach [exactly 1 yoctoNEAR](../../smart-contracts/security/one_yocto) to the call* ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} nft_transfer(receiver_id: string, token_id: string, approval_id?: number, memo: string?): void ```
#### `nft_transfer_call` The function transfers the `token_id` to the `receiver_id` **and calls the method `nft_on_transfer(sender_id, previous_owner_id, token_id, msg)`** on `receiver_id`. Optionally the function can include a `memo` for the NFT contract, and a `msg` field to which will be sent to the receiver contract. > 📖 This function is useful to transfer NFTs to a contract and trigger some action on the receiver side in a single transaction, thus acting as **attaching NFTs to a function call** ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} nft_transfer_call(receiver_id: string, token_id: string, approval_id?: number, memo?: string, msg: string): Promise {} ``` Smart contracts expecting to **receive** Non-Fungible Tokens **must** implement this method. The method **must** return a boolean value indicating whether the token should be returned to the sender (`true`) or not (`false`). ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} nft_on_transfer(sender_id: string, previous_owner_id: string, token_id: string, msg: string): boolean ``` ⚠️ Note that this method does not need to be implemented by the NFT contract itself, but rather by any contract that expects to receive non-fungible tokens
#### `nft_resolve_transfer` This method is used as a [callback](../../smart-contracts/anatomy/crosscontract#callback-function) to resolve the `nft_transfer_call` transaction, handling refunds if necessary. It must return `true` if the token was successfully transferred to `receiver_id`, or `false` if the token was returned to `owner_id`. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} nft_resolve_transfer(owner_id: string, receiver_id: string, token_id: string, approved_account_ids?: Record): boolean ``` *** ## NEP-177 (NFT Metadata) [NEP-177](https://github.com/near/NEPs/blob/master/neps/nep-0177.md) is an extension to the NEP-171 standard that defines the **metadata** for both non-fungible tokens and non-fungible token contracts. Metadata provides **key information** , such as the contract's **name** or the NFT's **title**. Particularly, the following fields MUST be included in the smart contract and token's metadata: ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} type NFTContractMetadata = { spec: string, // required, essentially a version like "nft-1.0.0" name: string, // required, ex. "Mochi Rising — Digital Edition" or "Metaverse 3" symbol: string, // required, ex. "MOCHI" icon: string|null, // Data URL base_uri: string|null, // Centralized gateway known to have reliable access to decentralized storage assets referenced by `reference` or `media` URLs reference: string|null, // URL to a JSON file with more info reference_hash: string|null, // Base64-encoded sha256 hash of JSON from reference field. Required if `reference` is included. } type TokenMetadata = { title: string|null, // ex. "Arch Nemesis: Mail Carrier" or "Parcel #5055" description: string|null, // free-form description media: string|null, // URL to associated media, preferably to decentralized, content-addressed storage media_hash: string|null, // Base64-encoded sha256 hash of content referenced by the `media` field. Required if `media` is included. copies: number|null, // number of copies of this set of metadata in existence when token was minted. issued_at: number|null, // When token was issued or minted, Unix epoch in milliseconds expires_at: number|null, // When token expires, Unix epoch in milliseconds starts_at: number|null, // When token starts being valid, Unix epoch in milliseconds updated_at: number|null, // When token was last updated, Unix epoch in milliseconds extra: string|null, // anything extra the NFT wants to store on-chain. Can be stringified JSON. reference: string|null, // URL to an off-chain JSON file with more info. reference_hash: string|null // Base64-encoded sha256 hash of JSON from reference field. Required if `reference` is included. } ``` *** ## NEP-178 (NFT Approval Management) [NEP-178](https://github.com/near/NEPs/blob/master/neps/nep-0178.md) is an extension to the NEP-171 standard that defines the **approval management** for non-fungible tokens. The approval mechanism allows the owner of an NFT to authorize another account (for example, a marketplace contract) to transfer the token on their behalf. ### Interface #### `nft_is_approved` (*read-only*) Returns whether an `approved_account_id` is actually approved to transfer the `token_id` on behalf of the token owner. If `approval_id` is provided, it will also check that the approval ID matches. ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} nft_is_approved(token_id: string, approved_account_id: string, approval_id?: number): boolean ```
#### `nft_approve` Grants approval to `account_id` to transfer the `token_id` on behalf of the token owner. Optionally, the function can include a `msg` field to provide additional information to the contract. > *Requirement: The caller must attach a deposit of at least `1 yoctoNEAR` plus the storage cost for adding the new approval* ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} nft_approve(token_id: string, account_id: string, msg?: string): void ```
#### `nft_revoke` Revokes approval for `account_id` to transfer the `token_id` on behalf of the token owner. > *Requirement: The caller must attach [exactly 1 yoctoNEAR](../../smart-contracts/security/one_yocto) to the call* ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} nft_revoke(token_id: string, account_id: string): void ```
#### `nft_revoke_all` Revokes all approvals for the `token_id`. > *Requirement: The caller must attach [exactly 1 yoctoNEAR](../../smart-contracts/security/one_yocto) to the call* ```ts theme={"theme":{"light":"github-light","dark":"github-dark"}} nft_revoke_all(token_id: string): void ``` # OutLayer Source: https://docs.near.org/primitives/off-chain-compute/outlayer OutLayer is a verifiable off-chain compute platform for NEAR. Run Rust/WASM code inside Intel TDX enclaves with built-in VRF, secrets, MPC vaults, and payment keys. [OutLayer](https://outlayer.fastnear.com) is a verifiable off-chain compute platform for NEAR, built by [FastNEAR](https://fastnear.com). Smart contracts delegate work to **Intel TDX** enclaves that return results with a cryptographic attestation proving the exact code ran on the exact inputs. * **Website:** [outlayer.fastnear.com](https://outlayer.fastnear.com) * **Source:** [github.com/fastnear/near-outlayer](https://github.com/fastnear/near-outlayer) *** ## How it works 1. You write code in **Rust** and compile it to **WebAssembly** (WASI Preview 1 or 2). 2. The binary is hosted on GitHub. OutLayer clones, compiles, and caches it. 3. A NEAR contract calls OutLayer using NEAR's `yield`/`resume` flow — or any client can call the HTTPS API directly. 4. The worker runs the WASM inside a **TDX enclave** and returns the result with a TEE attestation (code hash, input hash, output, signed by the hardware). *** ## Features | Feature | Description | | ------------------------------- | ---------------------------------------------------------------------- | | **WASI runtime** | Run any Rust code compiled to `wasm32-wasi`. | | **TEE attestation** | Cryptographic proof of code + input + output, signed by Intel TDX. | | **VRF** | Verifiable randomness with Ed25519 signatures. | | **Secrets** | Encrypted API keys and credentials, decrypted only inside the enclave. | | **Confidential Key Derivation** | Keys that exist only inside your TEE code and persist across upgrades. | | **MPC Vaults** | Multi-party computation for shared key custody. | | **Payment Keys** | USDC-based metering for monetized HTTPS endpoints. | | **Persistent storage** | Encrypted storage between executions. | *** ## Example use cases The [examples gallery](https://outlayer.fastnear.com/docs/examples) ships 14+ production-ready demos. A few highlights: * **Price & weather oracles** — fetch off-chain data with a proof of source. * **Coin-flip / lottery** — VRF-based randomness for fair on-chain games. * **AI calls** — invoke OpenAI/GPT from a contract with verifiable output. * **Cross-chain reads** — query Ethereum state without a bridge. * **Private DAO voting** — tally votes inside the enclave; only the result is published. * **NEAR Intents swaps** — execute Intent flows from off-chain logic. * **Encrypted email & CAPTCHA** — end-to-end use cases requiring secrets. Start with the [Getting Started guide](https://outlayer.fastnear.com/docs/getting-started) and the [Dev Guide](https://outlayer.fastnear.com/docs/dev-guide) to set up your first WASM module and call it from a NEAR contract. *** ## Deployed services built on OutLayer | Name | Description | Reference | | ---------------- | --------------------------------------------------------------- | ----------------------------------------------------------- | | **Price Oracle** | TEE-secured, Pyth-compatible price feed on `price-oracle.near`. | See [Oracles](/primitives/oracles#price-oracle-by-outlayer) | OutLayer is a third-party platform. As with any external service, evaluate its operational guarantees, attestation verification flow, and key custody model before relying on it for production assets. # Off-chain Compute Source: https://docs.near.org/primitives/off-chain-compute/what-is Learn how NEAR smart contracts can delegate heavy or impossible-on-chain work to verifiable off-chain computation running inside Trusted Execution Environments (TEEs). Smart contracts run inside a deterministic VM and pay gas for every instruction. That makes some workloads impractical (heavy cryptography, ML inference) and others outright impossible (HTTP requests, accessing API keys, generating true randomness). **Off-chain compute** moves these workloads outside the chain while keeping cryptographic proof that the right code ran on the right inputs. On NEAR, this is typically achieved with **Trusted Execution Environments (TEEs)** — secure enclaves (e.g. Intel TDX) that produce signed attestations of execution. A TEE attestation proves three things: the **code** that ran (hash of the binary), the **inputs** it received, and the **output** it produced — all signed by hardware the operator cannot tamper with. *** ## What it unlocks * **HTTP requests** — fetch from any Web2 API directly from contract logic. * **Secrets management** — encrypted API keys and private keys, only decrypted inside the enclave. * **Verifiable randomness (VRF)** — provably-fair random numbers signed with Ed25519. * **AI integration** — call LLMs and ML models with a proof the result is genuine. * **Cross-chain reads** — query Ethereum or other chains without a bridge contract. * **Heavy cryptography** — zero-knowledge proofs, MPC, custom signature schemes. *** ## How it integrates with NEAR A contract calls into the off-chain layer using NEAR's **`yield`/`resume`** mechanism: the contract pauses, the off-chain worker executes the code in a TEE, then resolves the promise with the result and its attestation — all within a single logical transaction. For workloads that don't need a contract at all, the same compute can also be triggered via direct HTTPS, which is useful for Web2 backends or frontends. *** ## Platforms A verifiable off-chain compute platform for NEAR by FastNEAR. Code runs in Intel TDX enclaves with built-in support for VRF, secrets, MPC vaults, and payment keys. # Oracles Source: https://docs.near.org/primitives/oracles Learn about blockchain oracles on NEAR Protocol, including price feeds, data integration, and using oracle services like Outlayer Price Oracle and Pyth Network. [Blockchain Oracles](https://en.wikipedia.org/wiki/Blockchain_oracle) serve as intermediaries that connect smart contracts with external (off-chain) data. `Example:` * **Price Feeds:** Real-time pricing for cryptocurrencies, stocks, or commodities. * **Event Information:** Updates on real-world events like sports results or weather conditions. * **API Access:** Connections to external web services and systems. Oracles, being external third-party services, require careful consideration of their reliability, security, and decentralization to avoid risks such as incorrect data, manipulation, or single points of failure. *** ## Deployed Oracles on NEAR Here is a directory of third-party oracle services deployed on the NEAR blockchain: | Name | Creator | Description | | -------------------------------------------------------------------------------------------- | ------------------------------------------------- | -------------------------------------------------- | | [Outlayer Price Oracle](#price-oracle-by-outlayer) | [Outlayer](https://github.com/zavodil/oracle-ark) | TEE-Secured Price Oracle based on Outlayer | | [Pyth Network Oracle](#pyth-network-oracle) | [Pyth Network](https://pyth.network/) | High-frequency, low-latency oracle for price feeds | | **[\[Your Project Here\]](https://github.com/near/docs/edit/master/primitives/oracles.mdx)** | - | - | *** ## Price Oracle by Outlayer * **Creator:** [Outlayer](https://github.com/fastnear/near-outlayer) * **Official Documentation:** [Price Oracle Outlayer](https://price-oracle.outlayer.ai/docs/) * **Codebase Repository:** [zavodil/oracle-ark](https://github.com/zavodil/oracle-ark) * **Deployed Addresses:** * **Mainnet:** [price-oracle.near](https://nearblocks.io/address/price-oracle.near) * **Testnet:** [price-oracle.testnet](https://testnet.nearblocks.io/address/price-oracle.testnet) ### How to use / integrate The `price-oracle.near` implements Pyth-compatible view methods natively (see [Pyth Network Oracle](#pyth-network-oracle) below). DeFi contracts using `pyth-oracle.near` can migrate by changing one contract address — no code changes needed. This price oracle is one of several services built on OutLayer, a general-purpose verifiable off-chain compute platform. See [OutLayer](/primitives/off-chain-compute/outlayer) for VRF, AI calls, cross-chain reads, and other off-chain primitives. *** ## Pyth Network Oracle * **Creator:** [Pyth Network](https://pyth.network) * **Official Documentation:** [Pyth NEAR Docs](https://docs.pyth.network/price-feeds/use-real-time-data/near) * **Codebase Repository:** [pyth-network/pyth-crosschain](https://github.com/pyth-network/pyth-crosschain/tree/main/target_chains/near) * **Deployed Addresses:** * **Mainnet:** [pyth-oracle.near](https://nearblocks.io/address/pyth-oracle.near) * **Testnet:** [pyth-oracle.testnet](https://testnet.nearblocks.io/address/pyth-oracle.testnet) *** ## Using Pyth Network Oracle > Pyth Network's NEAR smart contract has two core methods to update & get price feeds of your choice. 1. [`update_price_feeds`](#update_price_feeds) *(updates Pyth smart contract with the price feed you provide)* * args: `data` * type: `object` * example: `{ "data": "504e41...' }` 2. [`get_price`](#get_price) (fetches the most recent price stored in the contract)\_ * args: `price_identifier` * type: `object` * example: `{ price_identifier: 'f9c0172ba10dfa8...' }` For a complete list of endpoints to interact with, see [Pyth's `receiver` contract](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/receiver/src/ext.rs). ### Getting Started To get started with Pyth oracle you will need to gather the following information which differ between networks: * Price ID(s) * HermesAPI Endpoint * Smart contract address | Network | Price Feed IDs | Hermes API Address | Contract Address | | --------- | ------------------------------------------------------------------------------------------------ | -------------------------- | -------------------------------------------------------------------------------- | | `testnet` | [NEAR `testnet` Price Feed IDs](https://www.pyth.network/developers/price-feed-ids#near-testnet) | `hermes-beta.pyth.network` | [pyth-oracle.testnet](https://testnet.nearblocks.io/address/pyth-oracle.testnet) | | `mainnet` | [NEAR `mainnet` Price Feed IDs](https://www.pyth.network/developers/price-feed-ids#near-mainnet) | `hermes.pyth.network` | [pyth-oracle.near](https://nearblocks.io/address/pyth-oracle.near) | When using Price Feed IDs, you will need to remove the `0x` prefix. `Price Feed ID Example (testnet):` *** ### `update_price_feeds` > Updates the Pyth Oracle contract data with the price feed you provide. * args: `data` *(off-chain hex-encoded price feed)* * type: `object` * example: `{ "data": "504e41...' }` Update the Pyth Oracle contract with new price feed data in two main steps: 1. [Fetch off-chain price feed](#1-fetching-off-chain-price-feed) 2. [Update Pyth Oracle contract with off-chain price feed](#2-update-pyth-oracle-contract-price-feed) #### 1) Fetching off-chain price feed You can obtain an off-chain price feed using Pyth's [Hermes API](https://hermes-beta.pyth.network/docs/). To use these endpoints, you will need to provide a Price Feed ID and ensure you are targeting the correct network. See [Getting Started](#getting-started) for more information. Here is a node.js example of fetching the latest price feed using `/v2/updates/price/latest` endpoint: #### 2) Update Pyth Oracle Contract Price Feed After [fetching an off-chain price feed](#1-fetching-off-chain-price-feed), you can now perform a contract call to the Pyth Oracle to update the price feed on-chain. Call `update_price_feeds` on the Pyth Oracle contract with `data` as your arguments. `example args:` ```json theme={"theme":{"light":"github-light","dark":"github-dark"}} { "data": "504e41550100000000a00100000000010070b0ee3a00d1a3c07ee440887eb34a5a35860e6f4b9230fd62f0593fe35c8a3561735a6a37d269c5f166b84ead8918f710dc1be2ee6b51db5b22340ea2c173fc01673d544b00000000001ae101faedac5851e32b9b23b5f9411a8c2bac4aae3ed4dd7b811dd1a72ea4aa7100000000061bc18c014155575600000000000ab0f04600002710f41bc8c224ed983c68dbf5dab7dd34c9129fecfa03005500ca80ba6dc32e08d06f1aa886011eed1d77c77be9eb761cc10d72b7d0a2fd57a600000047e2eb4ef0000000000692480ffffffff800000000673d544b00000000673d544b00000048200e66a00000000005e495a60bb9370c458dd50558b34699b5b179f45e56be22f0a1a0feb1db8469adc8c5efeb53988495bac07bf9efed07f5eee43818150c55055882f6872a228e8e9bc78459ed3ea7fe0b86f3048f6bf0aad34befc46063ab7d200beb8bc9fe5839844d2233546f0742bb665f1e610370fcf8ce5be83d0f47e584b685af87cf3ebcb79e714827dcb99dba579e1a03785052ab3c7c7147d3f7bba822b04dbda159670e9a8d29e7ccf68474b2ca85e00224d29bf65b06b09f95e91703313e053b697b48ac1e4d1c57605a71ab77e7ef276bfe8a369c268333b9a37461bf2b7cb7fd4c005500ecf553770d9b10965f8fb64771e93f5690a182edc32be4a3236e0caaa6e0581a0000000e2ba8cd280000000001b40517fffffff800000000673d544b00000000673d544b0000000e3ea44c6800000000016aee120b47b853f55949284cb8ba0b63824ff9b48cd1da8417f45421b79ee3195fc8d107540a0bbb95c2445b66065754f135cb842db09a7e7ab33f79c546a48db872bd7197b04e3d7b52fbb55b3b9f51707c5a55fac3707cb563dbcde4aadeecc3649c237454cecf519dc567c0da03d81808523aa4fa71815eab25ce7da61b48647bac645d403208135002aab5fde2d7ab3c7c7147d3f7bba822b04dbda159670e9a8d29e7ccf68474b2ca85e00224d29bf65b06b09f95e91703313e053b697b48ac1e4d1c57605a71ab77e7ef276bfe8a369c268333b9a37461bf2b7cb7fd4c" } ``` Example of updating the Pyth Oracle contract's price feed using `near-js/client` and node.js: Although unused deposit will be refunded, you can calculate an estimate by calling the `get_update_fee_estimate` method against the Pyth contract. *** ### `get_price` > Fetches the most recent price feed stored in the Pyth Oracle contract. Is a view method, so does not require a signature or payment. * args: `price_identifier` *(unique price feed identifier)* * type: `object` * example: `{ price_identifier: 'f9c0172ba10dfa8...' }` After [updating the price feed](#update_price_feeds), you can view the feed on-chain by calling `get_price` on the Pyth Oracle contract. Note that this is a view method and does not require a signature or deposit. `Example:` # What are Primitives? Source: https://docs.near.org/primitives/what-is Learn about blockchain primitives including Fungible Tokens (FT), Non-Fungible Tokens (NFT), Decentralized Autonomous Organizations (DAO), and LinkDrops as building blocks for applications. Primitives are fundamental building blocks that can be combined to create a fully functional application. Blockchain primitives include [Fungible Tokens (FT)](#fungible-tokens-ft), [Non Fungible Tokens (NFT)](#non-fungible-tokens-nft), [Decentralized Autonomous organizations (DAO)](#decentralized-autonomous-organizations-dao), [Link Drops](#linkdrops) and more. img *** #### Fungible Tokens (FT) [Fungible tokens](./ft/ft) represent an **asset** on a blockchain that is **interchangeable**. Besides the native NEAR token, users can issue their own fungible tokens or use those that are already present in the ecosystem. Fungible Tokens are ideal to create **reward systems**, **fair tickets** and any other type of **token**. #### Non Fungible Tokens (NFT) In contrast with fungible tokens, each [non-fungible token (NFT)](./nft/nft) is **unitary** and therefore **unique**. Users can create their own non-fungible token, transfer to other users, or exchange them in marketplaces. NFTs are ideal to represent **ownership of assets** such as **collectibles**, **event tickets** and other unique assets. #### Decentralized Autonomous organizations (DAO) [Decentralized Autonomous Organizations (DAOs)](./dao) are **self-organized groups** that form around common purposes. Membership, decision making, and funding are **coordinated** by **publicly voting** on proposals through a smart contract. DAOs are ideal to create **decentralized governance**, **funding**, and **decision-making** tools. ### LinkDrops [LinkDrops](./linkdrop/linkdrop) are an easy way to **distribute digital assets** (NFTs, FTs) via links. You simply **provide a link** for users and they can **claim** your drop. LinkDrops are ideal to do **drops**, and **onboard new users** into Web3 apps. # Access Keys Source: https://docs.near.org/protocol/accounts-contracts/access-keys Learn about NEAR's access key system with Full-Access Keys for complete account control and Function-Call Keys for restricted, shareable permissions to specific contracts. In NEAR, users control their accounts using access keys, which can be full-access keys or function-call keys. Full-access keys allow complete control over the account, while function-call keys restrict actions to specific contracts. This system enables secure sharing of permissions and simplifies user interactions with applications. *** ## Access Keys In most blockchains, users control their accounts by holding a single [`private key`](https://en.wikipedia.org/wiki/Public-key_cryptography) (a secret only they know) and using it to sign [transactions](/protocol/transactions). Access keys In NEAR we distinguish two types of Access Keys: 1. `Full-Access Keys`: Have full control over the account, and should **never be shared** 2. `Function-Call Keys`: Can only sign calls for specific contracts, and are **meant to be shared** Every account in NEAR can hold **multiple keys**, and keys can be added or removed, allowing a fine-grained control over the account's permissions. *** ## Function-Call Keys `Function-Call` keys can only sign transactions calling a **specific contract**, and do **not allow** to **attach NEAR tokens** to the call. They are defined by three attributes: 1. `receiver_id`: The **only contract** which the key allows to call, no other contract can be called with this key 2. `method_names` (Optional): The contract's **methods** the key allows to call. If omitted, all contract's methods can be called 3. `allowance` (Optional): The **amount of NEAR** allowed to be spent on [gas](/protocol/transactions/gas). If omitted, the key can consume **unlimited** gas `Function Call Keys` are meant to be shared with applications, so third-parties can make contract calls in your name. This is useful in multiple scenarios as we will see below. `Function-Call` keys are secure to share, as they only permit calls to a specific contract and prohibit NEAR token transfers *** ## Full-Access Keys As the name suggests, `Full-Access` keys have full control of an account, meaning they can be used to sign [transactions](/protocol/transactions) doing any action in your account's behalf: 1. Transfer NEAR Ⓝ 2. Delete your account or create sub-accounts of it 3. Add or remove Access Keys 4. Deploy a smart contract in the account 5. Call methods on any contract You should never share your `Full-Access`, otherwise you are giving **total control over the account**. [Implicit accounts](./account-id#implicit-address) already have a `Full-Access Key` by default, while for [`named accounts`](./account-id#named-address) their first `Full-Access Key` is added on creation *** ## Limited Access Key Caveats ### Account with Only Function-Call Keys If an account has **no full-access keys** and only function-call keys, it becomes effectively restricted: * It **cannot** transfer NEAR, delete itself, or manage its own keys * It can **only** perform the specific contract calls defined by the key's `receiver_id` and `method_names` This is useful for creating restricted sub-accounts (e.g. for [chain signatures](../../chain-abstraction/chain-signatures)), but be aware the account cannot be recovered or reconfigured through standard transactions. Creating a sub-account with only a single function-call key means that account will **never** be able to remove itself, transfer NEAR out, or add new keys — unless the target contract provides a method to do so. ### Allowance Exhaustion The `allowance` field defines how much NEAR the key can spend on gas fees: * If set to a specific amount and fully consumed → the key becomes **unusable** and no new transactions can be signed * If set to `0` or omitted → **unlimited** allowance (the key has no gas budget restriction) If an account has only function-call keys and the allowance runs out, the account is permanently locked from initiating any transaction. Either use unlimited allowance (`0`) or ensure the account is topped up with NEAR before the allowance is exhausted. *** ## Locked Accounts If you remove all keys from an account, then the account will become **locked**, meaning that no external actor can perform transactions in the account's name. In practice, this means that only the account's smart contract can transfer assets, create sub-accounts, or update its code. Locking an account is very useful when one wants to deploy a contract, and let the community be assured that only the contract is in control of the account. An account could still add keys to itself through a smart contract, effectively allowing the contract to unlock the account. Notice that this can only be done if the contract is deployed before the account is locked # Address (Account ID) Source: https://docs.near.org/protocol/accounts-contracts/account-id Learn all about NEAR account addresses NEAR accounts are identified by a unique address, which can take multiple forms: 1. [**Implicit address**](#implicit-address), which are 64 characters long (e.g. `fb9243ce...`) 2. [**Named address**](#named-address), which act as domains (e.g. `alice.near`, `sub.account.testnet`) 3. An ethereum-like account (e.g. `0x85f17cf997934a597031b2e18a9ab6ebd4b9f6a4`) 4. [**Deterministic address**](#deterministic-address), which start with `0s` (e.g. `0s85f17cf997934a597031b2e18a9ab6ebd4b9f6a4`) In NEAR, accounts can actually be any string as long as they meet the following criteria: * It must have at least 2 characters and can go up to 64 characters * It can only use lowercase letters (`a-z`), digits (`0-9`), and separators (`.`, `-`, `_`) This means that all `root`, `some-unique-string`, `something-to-remember-later`, `0x85f17....`, `fb9243ce` and `user.name` are **all valid account IDs**. However, users can only create accounts that are either a `named address`, an `implicit address`, or an `ethereum-like address` **Searching to create an account?** You have multiple ways to create an account, you can create a [web wallet](https://wallet.meteorwallet.app/wallet), create a mobile wallet through [telegram](https://web.telegram.org/k/#@herewalletbot) or choose any of the available [NEAR wallets](https://wallet.near.org/). *** ## Implicit Address Implicit accounts are denoted by a 64 character address, which corresponds to a unique public/private key-pair. Who controls the [private key](./access-keys) of the implicit account controls the account. For example: * The private key: `ed25519:4x1xiJ6u3sZF3NgrwPUCnHqup2o...` * Corresponds to the public key: `ed25519:CQLP1o1F3Jbdttek3GoRJYhzfT...` * And controls the account: `a96ad3cb539b653e4b869bd7cf26590690e8971...` Implicit accounts always *exist*, and thus do not need to be created. However, in order to use the account you will still need to fund it with NEAR tokens (or get a relayer to pay your transaction's [gas](../transactions/gas)). In NEAR, you can delete the private key of an implicit account, which effectively locks the account and prevents anyone to control it The simplest way to obtain a public / private key that represents an account is using the [NEAR CLI](/tools/cli) ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near account create-account fund-later use-auto-generation save-to-folder ~/.near-credentials/implicit # The file "~/.near-credentials/implicit/8bca86065be487de45e795b2c3154fe834d53ffa07e0a44f29e76a2a5f075df8.json" was saved successfully cat ~/.near-credentials/implicit/8bca86065be487de45e795b2c3154fe834d53ffa07e0a44f29e76a2a5f075df8.json ``` or using the `near-seed-phrase` library: ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} import { generateSeedPhrase } from "near-seed-phrase"; const { seedPhrase, publicKey, secretKey } = generateSeedPhrase(); ``` You can derive the implicit account address from a public key by removing the `ed25519:` prefix, decoding the resulting Base58 string into bytes, and then converting those bytes into a hexadecimal string. ```js theme={"theme":{"light":"github-light","dark":"github-dark"}} // vanilla js import { decode } from 'bs58'; Buffer.from(decode(publicKey.replace('ed25519:', ''))).toString('hex') // or using near-api-js import { utils } from 'near-api-js'; utils.keyToImplicitAddress(publicKey); ``` *** ## Named Address Users can register **named accounts** (e.g. `bob.near`) which are easy to remember and share. An awesome feature of named accounts is that they can create **sub-accounts** of themselves, effectively working as domains: 1. The [`registrar`](https://nearblocks.io/address/registrar) account can create top-level accounts (e.g. `near`, `sweat`, `kaiching`). 2. The `near` account can create sub-accounts such as `bob.near` or `alice.near` 3. `bob.near` can create sub-accounts of itself, such as `app.bob.near` 4. Accounts cannot create sub-accounts of other accounts * `near` **cannot** create `app.bob.near` * `account.near` **cannot** create `sub.another-account.near` 5. Accounts have **no control** over their sub-account, they are different entities Anyone can create a `.near` or `.testnet` account, you just need to call the `create_account` method of the corresponding top-level account - `testnet` on testnet, and `near` on mainnet. In NEAR, named accounts are created using the [`CreateAccount`](../transactions/transaction-anatomy#actions) action. Both `testnet` and `near` accounts expose the function `create_account`, which triggers `CreateAccount` to create sub-accounts of themselves. For example, if we want to create the account `alice.testnet` with `0.1 NEAR`, we would need to call the `create_account` method of `testnet` using an existing account (e.g. `funding-account.testnet`): ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near call testnet create_account '{"new_account_id": "alice.testnet", "new_public_key": "ed25519:"}' --useAccount funding-account.testnet --networkId testnet ``` If we then want to create a sub-account of `alice.testnet` - which we control - we can simply trigger the `CreateAccount` action ourselves: ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}} near create-account sub-acc.new-acc.testnet --useAccount new-acc.testnet ``` > Note: if you want the accounts to have some initial balance, you can add the `--deposit ` flag to the command above **Creating Named Accounts** If you are not going through an intermediary (i.e. the CLI, or a wallet), then you can create an implicit account, fund it, and call `create_account` on `near` / `testnet` *** ## Ethereum-like Address NEAR also supports Ethereum-like accounts which are identified by a hexadecimal address (e.g. `0x85f17cf997934a597031b2e18a9ab6ebd4b9f6a4`). These accounts are automatically created when a user signs in on a NEAR application using an Ethereum wallet such as MetaMask. *** ## Deterministic Address Deterministic accounts are a special type of account whose address is derived deterministically from their initial contract code and state. They are identified by an address starting with `0s` followed by 40 lowercase hexadecimal characters (42 characters total). For example: `0s85f17cf997934a597031b2e18a9ab6ebd4b9f6a4` The key property of a deterministic account is that **its address is computed from its initial state**, meaning you can know the account's address before it is even created. This is useful for protocols and applications that need to reference a contract address before deployment. The deterministic account ID is computed by: 1. Constructing a `DeterministicAccountStateInit` struct containing: * **Code**: a reference to the contract code via a code hash or an existing account ID * **Initial data**: a key-value mapping pre-populating the contract's storage (max 4 MiB per key/value) 2. Borsh-encoding that struct into bytes 3. Applying the formula: `'0s' + keccak256(bytes)[12:32].hex()` This guarantees that two accounts with identical code and initial state will always have the same address. Deterministic accounts are created using the `DeterministicStateInit` action — **not** the standard `CreateAccount` action. The protocol validates that the supplied account ID matches the hash of the provided initial state. Smart contracts can build this action using the following host functions: * `promise_batch_action_state_init` — creates a `DeterministicStateInit` action referencing a code hash * `promise_batch_action_state_init_by_account_id` — creates the action referencing an existing account's code * `set_state_init_data_entry` — adds a key-value entry to the account's initial storage * `current_contract_code` — returns the calling contract's own code hash, useful for deploying clones Any NEAR attached beyond the required storage deposit is refunded to the sender. **Deterministic accounts cannot be deleted** and certain account modifications available to regular accounts are restricted. Once created, the deployed code and pre-initialized storage are permanent. # NEAR Accounts Source: https://docs.near.org/protocol/accounts-contracts/account-model Learn about NEAR Protocol's account model, including named and implicit accounts, access keys, permissions, and how NEAR accounts differ from other blockchain platforms. Users participate in the NEAR ecosystem through their NEAR accounts. These accounts are identified by a [unique address](./account-id), can optionally hold a [smart contract](/smart-contracts/what-is), and are controlled through [Access Keys](./access-keys). By signing [transactions](../transactions) with their account, users can: 1. Send and receive **digital assets** (such as tokens or collectibles) 2. Create and interact with on-chain applications known as **smart contracts** 3. Control accounts in **other chains** (such as Ethereum or Bitcoin) ✨ 4. Help onboard new users by **covering the costs** of their transactions (gas fees) **Want to create an account?** Check out our tutorial on [Creating a NEAR Account](/getting-started/create-account) to get started! *** ## Account Model Overview Let's take a closer look at the different elements that compose the NEAR account model. Account model ### [Account ID](/protocol/accounts-contracts/account-id) NEAR **natively** implements multiple types of accounts, including: 1. **Named accounts** such as `alice.near`, which are simple to remember and share 2. **Implicit accounts** such as `fb9243ce...`, which are derived from a private key 3. **Ethereum-like accounts** which are compatible with Ethereum wallets
### [Multiple Keys](/protocol/accounts-contracts/access-keys) NEAR accounts can have multiple [keys](/protocol/accounts-contracts/access-keys), each with their own set of permissions: * You can easily swap keys if one gets compromised * You can use keys as authorization tokens for third-party applications
### [Smart Contracts](/smart-contracts/what-is) NEAR accounts can optionally hold an application - known as a [smart contract](/smart-contracts/what-is) - which can be written in Javascript or Rust. *** ## Comparison With Ethereum If you're familiar with development on Ethereum, it's worth making a quick note about how accounts are different. The table below summarizes some key differences: | | Ethereum Account | NEAR Account | | --------------- | ------------------------ | -------------------------------------------------------------------------------------- | | Account ID | Public Key (`0x123...`) | - Native named accounts (`alice.near`)
- Implicit accounts (`0x123...`) | | Secret Key | Private Key (`0x456...`) | Multiple key-pairs with permissions:
- `FullAccess` key
- `FunctionCall` key | | Smart Contracts | Synchronous execution | Asynchronous execution | | Gas Fees | In the order of dollars | In the order of tenths of a cent | | Block Time | \~12 seconds | \~600 milliseconds | # NEAR Data Flow Source: https://docs.near.org/protocol/data-flow/near-data-flow Learn how data flows in NEAR Protocol, including transactions, receipts, shards, and cross-shard communication. NEAR Protocol blockchain data flow might be a bit tricky at a glance. But it is pretty straightforward and follows well-defined rules. In this article, we are going to have a closer look at how the data flows in NEAR Protocol blockchain.