Skip to main content

NEAR API

The NEAR API is a set of libraries that allow you to interact with the NEAR blockchain. You can use it to create accounts, send tokens, deploy contracts, and more.

The API is available in multiple languages, including:

For example, you could use near-api-js to create web applications or backend services written in node.js servers.

Wallet Integration

To allow users to login into your web application using a wallet you will need the wallet-selector. Read more in our Web Frontend integration article


Installโ€‹

Include near-api-js as a dependency in your package.

npm i --save near-api-js
Static HTML

If you are building a site without using npm, you can include the library directly in your HTML file through a CDN.

<script src="https://cdn.jsdelivr.net/npm/near-api-js/dist/near-api-js.min.js"></script>

Importโ€‹

You can use the API library in the browser, or in Node.js runtime. Some features are available only in one of the environments. For example, the WalletConnection is only for the browser, and there are different KeyStore providers for each environment.

import * as nearAPI from "near-api-js";

Connecting to NEARโ€‹

The object returned from connect is your entry-point for all commands in the API. To sign a transaction you'll need a KeyStore to create a connection.

const { connect } = nearAPI;

const connectionConfig = {
networkId: "testnet",
keyStore: myKeyStore, // first create a key store
nodeUrl: "https://rpc.testnet.near.org",
walletUrl: "https://testnet.mynearwallet.com/",
helperUrl: "https://helper.testnet.near.org",
explorerUrl: "https://testnet.nearblocks.io",
};
const nearConnection = await connect(connectionConfig);
Mainnet/Localnet connection
// Mainnet config example
const connectionConfig = {
networkId: "mainnet",
keyStore: myKeyStore, // first create a key store
nodeUrl: "https://rpc.mainnet.near.org",
walletUrl: "https://wallet.mainnet.near.org",
helperUrl: "https://helper.mainnet.near.org",
explorerUrl: "https://nearblocks.io",
};

// Localnet config example
const connectionConfig = {
networkId: "local",
nodeUrl: "http://localhost:3030",
walletUrl: "http://localhost:4000/wallet",
};

Key Storeโ€‹

If you sign transactions, you need to create a Key Store. In the browser, the LocalStorage KeyStore will be used once you ask your user to Sign In with the Wallet.

// creates keyStore using private key in local storage

const { keyStores } = nearAPI;
const myKeyStore = new keyStores.BrowserLocalStorageKeyStore();
Window error using Node.js

You're maybe using a KeyStore that's for the browser. Instead, use a filesystem key or private key string.

Browser KeyStore:

const { keyStores } = require("near-api-js");
const keyStore = new keyStores.BrowserLocalStorageKeyStore();

FileSystem KeyStore:

const { keyStores } = require("near-api-js");
const KEY_PATH = "~./near-credentials/testnet/example-account.json";
const keyStore = new keyStores.UnencryptedFileSystemKeyStore(KEY_PATH);

RPC Failoverโ€‹

RPC providers can experience intermittent downtime, connectivity issues, or rate limits that cause client transactions to fail. This can be prevented by using the FailoverRpcProvider that supports multiple RPC providers.

const jsonProviders = [
new JsonRpcProvider({
url: 'https://rpc.mainnet.near.org',
}),
new JsonRpcProvider(
{
url: 'https://another-rpc.cloud.com',
headers: { 'X-Api-Key': 'some string' },
},
{ retries: 3, backoff: 2, wait: 500 }
),
];
const provider = new FailoverRpcProvider(jsonProviders);

await connect({
networkId: 'mainnet',
provider: provider,
// this isn't used if `provider` is specified, but is still required for backward compatibility
nodeUrl: 'https://rpc.mainnet.near.org',
});

Accountโ€‹

Instantiate Accountโ€‹

This will return an Account object for you to interact with.

const account = await nearConnection.account("example-account.testnet");
warning

In order to be able to use the account, its credentials must be stored in the key store


Get Balanceโ€‹

// gets account balance
const account = await nearConnection.account("example-account.testnet");
const accountBalance = await account.getAccountBalance();

Get Detailsโ€‹

Returns information about an account, such as authorized apps.

// gets account details in terms of authorized apps and transactions
const account = await nearConnection.account("example-account.testnet");
const accountDetails = await account.getAccountDetails();

Get Stateโ€‹

Get basic account information, such as amount of tokens the account has or the amount of storage it uses.

const account = await nearConnection.account("example-account.testnet");
const accountState = await account.state();

Create Sub-Accountโ€‹

Create a sub-account.

// creates a sub-account using funds from the account used to create it.
const account = await nearConnection.account("example-account.testnet");
await account.createAccount(
"sub.example-account.testnet", // sub-account name
"8hSHprDq2StXwMtNd43wDTXQYsjXcD4MJTXQYsjXcc", // public key for sub account
"10000000000000000000" // initial balance for new account in yoctoNEAR
);
Creating .near or .testnet accounts

In order to create .near or .testnet accounts, you need to make a function call to the top-level-domain (i.e. near or testnet), calling create_account:

return await creatorAccount.functionCall({
contractId: "testnet",
methodName: "create_account",
args: {
new_account_id: "new-account.testnet",
new_public_key: "ed25519:2ASWccunZMBSygADWG2pXuHM6jWdnzLzWFU6r7wtaHYt",
},
gas: "300000000000000",
attachedDeposit: utils.format.parseNearAmount(amount),
});

Delete Accountโ€‹

// deletes account found in the `account` object
// transfers remaining account balance to the accountId passed as an argument
const account = await nearConnection.account("example-account.testnet");
await account.deleteAccount("beneficiary-account.testnet");

Transactionsโ€‹

Send Tokensโ€‹

Transfer NEAR tokens between accounts. This returns an object with transaction and receipts outcomes and status.

const account = await nearConnection.account("sender-account.testnet");
await account.sendMoney(
"receiver-account.testnet", // receiver account
"1000000000000000000000000" // amount in yoctoNEAR
);

View Functionโ€‹

View functions are read-only functions that don't change the state of the contract. We can call these functions without instantiating an account or a key store.

import { providers } from 'near-api-js';

const url = `https://rpc.${this.networkId}.near.org`;
const provider = new providers.JsonRpcProvider({ url });
const args = { greeting: 'hello' };

const response = await provider.query({
request_type: 'call_function',
account_id: 'hello.near-examples.testnet',
method_name: 'get_greeting',
args_base64: Buffer.from(JSON.stringify(args)).toString('base64'),
finality: 'optimistic',
});

const result = JSON.parse(Buffer.from(res.result).toString());

Call Functionโ€‹

A call function changes the contract's state and does require an account.

import { connect, transactions, keyStores } from "near-api-js";

const account = await nearConnection.account("example-account.testnet");
const result = await account.signAndSendTransaction({
receiverId: "example-contract.testnet",
actions: [
transactions.functionCall(
"new",
Buffer.from(JSON.stringify(newArgs)),
10000000000000,
"0"
),
],
});

Batch Transactionsโ€‹

You may batch send transactions by using the signAndSendTransaction({}) method from account. This method takes an array of transaction actions, and if one fails, the entire operation will fail. Here's a simple example:

const { connect, transactions, keyStores } = require("near-api-js");
const fs = require("fs");
const path = require("path");
const homedir = require("os").homedir();

const CREDENTIALS_DIR = ".near-credentials";
const CONTRACT_NAME = "spf.idea404.testnet";
const WASM_PATH = path.join(__dirname, "../build/uninitialized_nft.wasm");

const credentialsPath = path.join(homedir, CREDENTIALS_DIR);
const keyStore = new keyStores.UnencryptedFileSystemKeyStore(credentialsPath);

const config = {
keyStore,
networkId: "testnet",
nodeUrl: "https://rpc.testnet.near.org",
};

sendTransactions();

async function sendTransactions() {
const near = await connect({ ...config, keyStore });
const account = await near.account(CONTRACT_NAME);
const args = { some_field: 1, another_field: "hello" };

const balanceBefore = await account.getAccountBalance();
console.log("Balance before:", balanceBefore);

try {
const result = await account.signAndSendTransaction({
receiverId: CONTRACT_NAME,
actions: [
transactions.deployContract(fs.readFileSync(WASM_PATH)), // Contract does not get deployed
transactions.functionCall("new", Buffer.from(JSON.stringify(args)), 10000000000000, "0"), // this call fails
transactions.transfer("1" + "0".repeat(24)), // 1 NEAR is not transferred either
],
});
console.log(result);
} catch (e) {
console.log("Error:", e);
}

const balanceAfter = await account.getAccountBalance();
console.log("Balance after:", balanceAfter);
}
Response Example
Balance before: {
total: '49987878054959838200000000',
stateStaked: '4555390000000000000000000',
staked: '0',
available: '45432488054959838200000000'
}
Receipts: 2PPueY6gnA4YmmQUzc8DytNBp4PUpgTDhmEjRSHHVHBd, 3isLCW9SBH1MrPjeEPAmG9saHLj9Z2g7HxzfBdHmaSaG
Failure [spf.idea404.testnet]: Error: {"index":1,"kind":{"ExecutionError":"Smart contract panicked: panicked at 'Failed to deserialize input from JSON.: Error(\"missing field `owner_id`\", line: 1, column: 40)', nft/src/lib.rs:47:1"}}
Error: ServerTransactionError: {"index":1,"kind":{"ExecutionError":"Smart contract panicked: panicked at 'Failed to deserialize input from JSON.: Error(\"missing field `owner_id`\", line: 1, column: 40)', nft/src/lib.rs:47:1"}}
at parseResultError (/Users/dennis/Code/naj-test/node_modules/near-api-js/lib/utils/rpc_errors.js:31:29)
at Account.<anonymous> (/Users/dennis/Code/naj-test/node_modules/near-api-js/lib/account.js:156:61)
at Generator.next (<anonymous>)
at fulfilled (/Users/dennis/Code/naj-test/node_modules/near-api-js/lib/account.js:5:58)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
type: 'FunctionCallError',
context: undefined,
index: 1,
kind: {
ExecutionError: "Smart contract panicked: panicked at \'Failed to deserialize input from JSON.: Error("missing field `owner_id`", line: 1, column: 40)\', nft/src/lib.rs:47:1"
},
transaction_outcome: {
block_hash: '5SUhYcXjXR1svCxL5BhCuw88XNdEjKXqWgA9X4XZW1dW',
id: 'SKQqAgnSN27fyHpncaX3fCUxWknBrMtxxytWLRDQfT3',
outcome: {
executor_id: 'spf.idea404.testnet',
gas_burnt: 4839199843770,
logs: [],
metadata: [Object],
receipt_ids: [Array],
status: [Object],
tokens_burnt: '483919984377000000000'
},
proof: [ [Object], [Object], [Object], [Object], [Object] ]
}
}
Balance after: {
total: '49985119959346682700000000',
stateStaked: '4555390000000000000000000',
staked: '0',
available: '45429729959346682700000000'
}

You may also find an example of batch transactions in the Cookbook.


Deploy a Contractโ€‹

You can deploy a contract from a compiled WASM file. This returns an object with transaction and receipts outcomes and status.

const account = await nearConnection.account("example-account.testnet");
const transactionOutcome = await account.deployContract(
fs.readFileSync("example-file.wasm")
);

Signing Messagesโ€‹


Keysโ€‹

You can get and manage keys for an account.

Add Function Access Keyโ€‹

const account = await nearConnection.account("example-account.testnet");
await account.addKey(
"8hSHprDq2StXwMtNd43wDTXQYsjXcD4MJTXQYsjXcc", // public key for new account
"example-account.testnet", // contract this key is allowed to call (optional)
"example_method", // methods this key is allowed to call (optional)
"2500000000000" // allowance key can use to call methods (optional)
);

Add Full Access Keyโ€‹

// takes public key as string for argument
const account = await nearConnection.account("example-account.testnet");
await account.addKey("8hSHprDq2StXwMtNd43wDTXQYsjXcD4MJTXQYsjXcc");

Get All Access Keysโ€‹

const account = await nearConnection.account("example-account.testnet");
await account.getAccessKeys();

Delete Access Keyโ€‹

const account = await nearConnection.account("example-account.testnet");
await account.deleteKey("8hSHprDq2StXwMtNd43wDTXQYsjXcD4MJTXQYsjXcc");

Utilitiesโ€‹

NEAR => yoctoNEARโ€‹

// converts NEAR amount into yoctoNEAR (10^-24)

const { utils } = nearAPI;
const amountInYocto = utils.format.parseNearAmount("1");

YoctoNEAR => NEARโ€‹

// converts yoctoNEAR (10^-24) amount into NEAR

const { utils } = nearAPI;
const amountInNEAR = utils.format.formatNearAmount("1000000000000000000000000");

Additional resourcesโ€‹

Was this page helpful?