Using JavaScript API to interact with NEAR
What is near-api-js
โ
near-api-js
is a complete library to interact with the NEAR blockchain. You can use it in the browser, or in Node.js runtime.
You'll typically first create a connection to NEAR with connect
. If you need to sign transaction, you also create a KeyStore
.
With the connection object you now can:
- Interact with the Wallet in a browser.
- Instantiate an Account object to inspect, create or delete accounts, and also send tokens, deploy contracts and manage keys for accounts.
- Instantiate an Contract object to call smart contract methods.
The library also contains some utils functions.
Note the difference between near-api-js
and near-sdk-js
:
The JavaScript SDK is a library for developing smart contracts. It contains classes and functions you use to write your smart contract code.
The JavaScript API is a complete library for all possible commands to interact with NEAR. Itโs a wrapper for the RPC endpoints, a library to interact with NEAR Wallet in the browser, and a tool for keys management.
Installโ
Include near-api-js
as a dependency in your package.
npm i --save near-api-js
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.
- Browser
- Node
import * as nearAPI from "near-api-js";
const nearAPI = require("near-api-js");
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.
- Using Browser
- Using Credentials Directory
- Using a File
- Using a private key string
// creates keyStore using private key in local storage
const { keyStores } = nearAPI;
const myKeyStore = new keyStores.BrowserLocalStorageKeyStore();
// creates a keyStore that searches for keys in .near-credentials
// requires credentials stored locally by using a NEAR-CLI command: `near login`
// https://docs.near.org/tools/cli#near-login
const { keyStores } = nearAPI;
const homedir = require("os").homedir();
const CREDENTIALS_DIR = ".near-credentials";
const credentialsPath = require("path").join(homedir, CREDENTIALS_DIR);
const myKeyStore = new keyStores.UnencryptedFileSystemKeyStore(credentialsPath);
// creates keyStore from a provided file
// you will need to pass the location of the .json key pair
const { KeyPair, keyStores } = require("near-api-js");
const fs = require("fs");
const homedir = require("os").homedir();
const ACCOUNT_ID = "near-example.testnet"; // NEAR account tied to the keyPair
const NETWORK_ID = "testnet";
// path to your custom keyPair location (ex. function access key for example account)
const KEY_PATH = '/.near-credentials/near-example-testnet/get_token_price.json';
const credentials = JSON.parse(fs.readFileSync(homedir + KEY_PATH));
const myKeyStore = new keyStores.InMemoryKeyStore();
myKeyStore.setKey(NETWORK_ID, ACCOUNT_ID, KeyPair.fromString(credentials.private_key));
// creates keyStore from a private key string
// you can define your key here or use an environment variable
const { keyStores, KeyPair } = nearAPI;
const myKeyStore = new keyStores.InMemoryKeyStore();
const PRIVATE_KEY =
"by8kdJoJHu7uUkKfoaLd2J2Dp1q1TigeWMG123pHdu9UREqPcshCM223kWadm";
// creates a public / private key pair using the provided private key
const keyPair = KeyPair.fromString(PRIVATE_KEY);
// adds the keyPair you created to keyStore
await myKeyStore.setKey("testnet", "example-account.testnet", keyPair);
Key store is not required if you are not signing transactions (meaning - you are only calling read-only view methods on a contract)
Connecting to NEARโ
The object returned from connect
is your entry-point for all commands in the API.
If you need to sign transaction, you'll need a KeyStore
to create a connection.
- TestNet
- MainNet
- BetaNet
- LocalNet
const { connect } = nearAPI;
const connectionConfig = {
networkId: "testnet",
keyStore: myKeyStore, // first create a key store
nodeUrl: "https://rpc.testnet.near.org",
walletUrl: "https://wallet.testnet.near.org",
helperUrl: "https://helper.testnet.near.org",
explorerUrl: "https://explorer.testnet.near.org",
};
const nearConnection = await connect(connectionConfig);
const { connect } = nearAPI;
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://explorer.mainnet.near.org",
};
const nearConnection = await connect(connectionConfig);
const { connect } = nearAPI;
const connectionConfig = {
networkId: "betanet",
keyStore: myKeyStore, // first create a key store
nodeUrl: "https://rpc.betanet.near.org",
walletUrl: "https://wallet.betanet.near.org",
helperUrl: "https://helper.betanet.near.org",
explorerUrl: "https://explorer.betanet.near.org",
};
const nearConnection = await connect(connectionConfig);
const { connect } = nearAPI;
const connectionConfig = {
networkId: "local",
nodeUrl: "http://localhost:3030",
walletUrl: "http://localhost:4000/wallet",
};
const nearConnection = await connect(connectionConfig);
Interacting with the Walletโ
Wallet interaction is possible only in the browser, because NEAR's Wallet is web-based.
Creating Wallet Connectionโ
In Wallet connection you use a LocalStorage KeyStore
.
- TestNet
- MainNet
- BetaNet
const { connect, keyStores, WalletConnection } = nearAPI;
const connectionConfig = {
networkId: "testnet",
keyStore: new keyStores.BrowserLocalStorageKeyStore(),
nodeUrl: "https://rpc.testnet.near.org",
walletUrl: "https://wallet.testnet.near.org",
helperUrl: "https://helper.testnet.near.org",
explorerUrl: "https://explorer.testnet.near.org",
};
// connect to NEAR
const nearConnection = await connect(connectionConfig);
// create wallet connection
const walletConnection = new WalletConnection(nearConnection);
const { connect, keyStores, WalletConnection } = nearAPI;
const connectionConfig = {
networkId: "mainnet",
keyStore: new keyStores.BrowserLocalStorageKeyStore(),
nodeUrl: "https://rpc.mainnet.near.org",
walletUrl: "https://wallet.mainnet.near.org",
helperUrl: "https://helper.mainnet.near.org",
explorerUrl: "https://explorer.mainnet.near.org",
};
// connect to NEAR
const nearConnection = await connect(connectionConfig);
// create wallet connection
const walletConnection = new WalletConnection(nearConnection);
const { connect, keyStores, WalletConnection } = nearAPI;
const connectionConfig = {
networkId: "betanet",
keyStore: new keyStores.BrowserLocalStorageKeyStore(),
nodeUrl: "https://rpc.betanet.near.org",
walletUrl: "https://wallet.betanet.near.org",
helperUrl: "https://helper.betanet.near.org",
explorerUrl: "https://explorer.betanet.near.org",
};
// connect to NEAR
const nearConnection = await connect(connectionConfig);
// create wallet connection
const walletConnection = new WalletConnection(nearConnection);
Module browserConnect
ย ย ย
Class WalletConnection
Ask your user to Sign Inโ
You first create a WalletConnection, and then call requestSignIn
.
This will redirect the current page to the Wallet authentication page.
You can configure success and failure redirect URLs.
This action creates an access key that will be stored in the browser's local storage. The access key can then be used to connect to NEAR and sign transactions via the KeyStore.
// const walletConnection = new WalletConnection(nearConnection);
walletConnection.requestSignIn(
"example-contract.testnet", // contract requesting access
"Example App", // optional title
"http://YOUR-URL.com/success", // optional redirect URL on success
"http://YOUR-URL.com/failure" // optional redirect URL on failure
);
Method WalletConnection.requestSignIn
Sign In is not required if you are using an alternative key store to local storage, or you are not signing transactions (meaning - you are only calling read-only view methods on a contract)
Sign Out on behalf of your userโ
// const walletConnection = new WalletConnection(nearConnection);
walletConnection.signOut();
Method WalletConnection.signOut
Check if Signed Inโ
// const walletConnection = new WalletConnection(nearConnection);
if (walletConnection.isSignedIn()) {
// user is signed in
}
Method WalletConnection.isSignedId
Get Authorized Account Idโ
// const walletConnection = new WalletConnection(nearConnection);
const walletAccountId = walletConnection.getAccountId();
Method WalletConnection.getAccountId
Get Authorized Account Objectโ
This will return an instance of Account that this wallet is authorized for.
// const walletConnection = new WalletConnection(nearConnection);
const walletAccountObj = walletConnection.account();
Method WalletConnection.account
ย ย ย
Class ConnectedWalletAccount
Accountโ
You can create, delete and interact with accounts with the Account module.
Load Accountโ
This will return an Account object for you to interact with.
const account = await nearConnection.account("example-account.testnet");
Create Accountโ
// create a new account using funds from the account used to create it.
const account = await nearConnection.account("example-account.testnet");
await account.createAccount(
"example-account2.testnet", // new account name
"8hSHprDq2StXwMtNd43wDTXQYsjXcD4MJTXQYsjXcc", // public key for new account
"10000000000000000000" // initial balance for new account in yoctoNEAR
);
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");
Get Account Balanceโ
// gets account balance
const account = await nearConnection.account("example-account.testnet");
await account.getAccountBalance();
Method Account.getAccountBalance
Get Account detailsโ
// gets account details in terms of authorized apps and transactions
const account = await nearConnection.account("example-account.testnet");
await account.getAccountDetails();
Method Account.getAccountDetails
Deploy a Contractโ
const account = await nearConnection.account("example-account.testnet");
const response = await account.deployContract(fs.readFileSync('./wasm_files/status_message.wasm'));
console.log(response);
Send Tokensโ
// sends NEAR tokens
const account = await nearConnection.account("sender-account.testnet");
await account.sendMoney(
"receiver-account.testnet", // receiver account
"1000000000000000000000000" // amount in yoctoNEAR
);
Stateโ
// gets the state of the account
const account = await nearConnection.account("example-account.testnet");
const response = await account.state();
console.log(response);
Access Keysโ
Add Full Access Keyโ
// takes public key as string for argument
const account = await nearConnection.account("example-account.testnet");
await account.addKey("8hSHprDq2StXwMtNd43wDTXQYsjXcD4MJTXQYsjXcc");
Add Function Access Keyโ
// adds 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)
);
Get All Access Keysโ
// returns all access keys associated with an account
const account = await nearConnection.account("example-account.testnet");
await account.getAccessKeys();
Delete Access Keyโ
// takes public key as string for argument
const account = await nearConnection.account("example-account.testnet");
await account.deleteKey("8hSHprDq2StXwMtNd43wDTXQYsjXcD4MJTXQYsjXcc");
Contractโ
When you instantiate an instance of Contract
it includes the smart-contract functions as methods of the instance.
For example if you deployed a contract with my_method
function on it, then this will work:
const contract = new Contract(account, {
changeMethods: ["my_method"],
sender: account
});
// `contract` object has `my_method` on it:
contract.my_method()
Load Contractโ
- Standard
- Using Wallet
const { Contract } = nearAPI;
const contract = new Contract(
account, // the account object that is connecting
"example-contract.testnet",
{
// name of contract you're connecting to
viewMethods: ["getMessages"], // view methods do not change state but usually return a value
changeMethods: ["addMessage"], // change methods modify state
sender: account, // account object to initialize and sign transactions.
}
);
const { Contract } = nearAPI;
const contract = new Contract(
wallet.account(), // the account object that is connecting
"example-contract.testnet",
{
// name of contract you're connecting to
viewMethods: ["getMessages"], // view methods do not change state but usually return a value
changeMethods: ["addMessage"], // change methods modify state
sender: wallet.account(), // account object to initialize and sign transactions.
}
);
Call Contractโ
- Change Method
- Change Method w/ callbackUrl and meta
- View Method
- View Method w/ args
await contract.method_name(
{
arg_name: "value", // argument name and value - pass empty object if no args required
},
"300000000000000", // attached GAS (optional)
"1000000000000000000000000" // attached deposit in yoctoNEAR (optional)
);
await contract.method_name(
{
callbackUrl: 'https://example.com/callback', // callbackUrl after the transaction approved (optional)
meta: 'some info', // meta information NEAR Wallet will send back to the application. `meta` will be attached to the `callbackUrl` as a url search param
args: {
arg_name: "value" // argument name and value - pass empty object if no args required
},
gas: 300000000000000, // attached GAS (optional)
amount: 1000000000000000000000000 // attached deposit in yoctoNEAR (optional)
}
);
const response = await contract.view_method_name();
console.log(response);
const response = await contract.view_method_name({ arg_name: "arg_value" });
console.log(response);
Utilsโ
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");