FastNear
Built for agents

Answer NEAR RPC and API questions with one library.

FastNear JS gives agents and developers a fast path from a NEAR data question to a working answer. Start with copyable snippets; open the docs only when you need the full reference.

  • Copy a starter snippet
  • Pick the right API family
  • Go deeper in the docs
Try it in DevTools

Drive the target contract from the browser console.

Open DevTools and paste any of these. They reference app.contractId, so they follow whatever target contract is set via the ⚙ gear in the navbar — change it once, and these snippets retarget. NEP-standard reads have shorthand under near.ft.* and near.nft.*; the recipe-driven equivalents live under near.recipes.* and accept an optional { network } override (so a testnet read from a mainnet-active page is one call, not a config flip).

Read total supply

Calls a common FT view method against the active contract.

await near.ft.totalSupply({ contractId: app.contractId })
Read your account state

Reads get_account for the signed-in account — swap the argument for any account id.

await near.view({
  contractId: app.contractId,
  methodName: "get_account",
  args: { account_id: nearWallet.accountId() },
})
Send a function call

Template for any signed transaction — replace methodName and args.

await near.recipes.functionCall({
  receiverId: app.contractId,
  methodName: "your_method",
  args: {},
  gas: near.utils.convertUnit("100 Tgas"),
  deposit: "0",
})
Cross-network read

Pass { network } to retarget any helper for a single call — no near.config() flip, mainnet stays the active network.

await near.ft.balance({
  network: "testnet",
  contractId: "wrap.testnet",
  accountId: "mike.testnet",
})
Pick the right API

Start with the FastNear family that matches the question.

Use these FastNear families when the question is about direct RPC, indexed transactions, transfers, recent blocks, or contract storage history — plus the wallet surface when the answer needs a user to approve a signature in their own wallet.

Go deeper in the docs

Open the full reference only when you need it.

These links connect the JS quickstart to the full FastNear docs for RPC, indexed APIs, auth, and agent workflows.

Common tasks

Copy the smallest snippet that gets you a useful answer.

These task helpers are layered on top of the lower-level APIs and come from the same machine-readable catalog behind recipes.json, llms.txt, and the terminal wrapper.

Multichain swaps New

Swap anything, anywhere, with NEAR Intents.

Sign a declarative statement of the outcome you want — "1 wNEAR for USDC" — and a network of solvers competes to fulfill it, settling atomically on the intents.near verifier across 30+ chains. @fastnear/intents wraps the hosted 1Click API, NEP-413 intent signing (wallet or raw key), and the verifier's deposit/balance/withdraw surface. Package-only: not part of near.js or agents.js.

How it works
  • Quote with createOneClickClient() — dry: true previews live pricing for free, keyless, and commitment-free; dry: false returns the deposit address that drives the swap.
  • Intents are authorized by NEP-413 signed messages — no gas, no transaction, but strictly full-access keys: FunctionCall session keys cannot sign intents.
  • The signers re-encode the wallet's base64 signature to the ed25519:<base58> MultiPayload the verifier expects — the most common integration bug, handled for you.
  • Verifier helpers cover the rest: ftDepositAction / wrapNearAction deposits, mtBatchBalances NEP-245 ledger views, and refundable ftWithdrawAction exits.
Live quote from the console

IIFE global from intents.js. Real solver pricing — 1 wNEAR to USDC on NEAR — with no key, no funds, and no commitment.

<script src="https://js.fastnear.com/intents.js"></script>
<script type="module">
  const oneClick = nearIntents.createOneClickClient();

  const quote = await oneClick.quote({
    dry: true,
    swapType: "EXACT_INPUT",
    slippageTolerance: 100,
    originAsset: "nep141:wrap.near",
    destinationAsset:
      "nep141:17208628f84f5d6ad33f0da3bbbeb27ffcb398eac501a31bd6ad2011e36133a1",
    amount: "1000000000000000000000000",
    depositType: "ORIGIN_CHAIN",
    refundTo: "you.near",
    refundType: "ORIGIN_CHAIN",
    recipient: "you.near",
    recipientType: "DESTINATION_CHAIN",
    deadline: new Date(Date.now() + 10 * 60_000).toISOString(),
  });

  console.log(quote.quote.amountOutFormatted, "USDC for 1 wNEAR");
</script>
Mainnet-only, with a signing caveat

The intents stack has no public testnet deployment, and browser signing rides nearWallet.signMessage with the account's full-access key. Read the full explainer for the swap flow, signing details, and guardrails, or go straight to the intents key in recipes.json and the @fastnear/intents README.

Gas keys New

Give an access key its own gas balance.

A gas key (NEP-611, protocol version 85) is an access key with a prepaid balance that pays the gas for whatever the key signs. Deposits still come from the account; gas refunds return to the key. Any account can top it up with TransferToGasKey, so a sponsor funds a user once instead of relaying every transaction, and num_nonces gives one key up to 1,024 independent nonce lanes for parallel sends. It ships in @fastnear/api 2.4.0+ with no extra package.

How it works
  • Add it with the ordinary AddKey and a GasKeyFullAccess or GasKeyFunctionCall permission — addFullAccessGasKey / addLimitedAccessGasKey on near.actions. The balance starts at "0"; a function-call gas key has no allowance — the balance is the limit.
  • Fund it from any account with transferToGasKey({ publicKey, deposit }); the receiver is the key's owner. Only the owner can withdrawFromGasKey.
  • Sign with sendTx({ signer, signerId, nonceIndex }). On a gas key it emits a TransactionV1 scoped to that lane, and lanes don't wait on each other. Read lanes with near.queryGasKeyNonces — view_access_key reports nonce 0 for a gas key.
  • Drain with WithdrawFromGasKey before DeleteKey, which burns what's left (refusing above 1 NEAR). Adding, funding and draining through a wallet needs one that advertises features.gasKeys in near-connect — Meteor today; signing with the key stays local.
Send on a lane, read the lanes back

From the gasKeys quickstarts (ESM). sendTx reads the key's GasKey* permission, fetches the chosen lane's nonce, and signs a TransactionV1; gas comes from the key balance. Needs @fastnear/api 2.4.0+ and an RPC on protocol 85.

import { actions, queryGasKeyNonces, sendTx } from "@fastnear/api";

export async function sendWithGasKey({ accountId, gasSigner, receiverId, nonceIndex = 0 }) {
  const result = await sendTx({
    signerId: accountId,
    signer: gasSigner,
    receiverId,
    actions: [actions.functionCall({ methodName: "ping", args: {}, gas: "30 Tgas", deposit: "0" })],
    nonceIndex,
    waitUntil: "FINAL",
    network: "testnet",
  });

  const nonces = await queryGasKeyNonces({
    accountId,
    publicKey: gasSigner.publicKey,
    blockId: "final",
    network: "testnet",
  });
  return { txHash: result.transaction?.hash ?? null, nonces: nonces.result.nonces };
}

// Lanes are independent nonce sequences, so these do not serialize behind each other.
export const sendOnTwoLanes = (params) =>
  Promise.all([0, 1].map((nonceIndex) => sendWithGasKey({ ...params, nonceIndex })));
Local signing, protocol 85

Gas keys need an RPC on protocol version 85 or later (queryProtocolVersion()) — signing with one is local, while adding, funding and draining through a wallet works with @fastnear/wallet 2.5.0+ and Meteor (near-connect features.gasKeys). Read the full explainer for the sponsored-counter and lanes walkthroughs, the wire format, and the drain-before-delete rule. All five quickstarts — add, fund, send, inspect, withdraw-delete — live under gasKeys in recipes.json.

Post-quantum keys New

Sign NEAR transactions with post-quantum ML-DSA-65 keys.

NEAR adds ML-DSA-65 (NIST FIPS 204, the lattice signature scheme also known as Dilithium) as an account access-key and transaction-signing type alongside Ed25519 and secp256k1, starting at protocol version 85. FastNear ships it opt-in in a standalone @fastnear/ml-dsa-65 package, so apps that only use classical keys never download the post-quantum implementation.

How it works
  • Generate an in-memory signer with generateSigner(), then enroll its full public key with a classical full-access AddKey — enrollment always starts from an existing classical signer.
  • Sign and submit through sendTx({ signerId, signer, … }) in @fastnear/api; the signer is bridged in via a structural TransactionSigner, and queryProtocolVersion() enforces v85.
  • Two key forms: the full ml-dsa-65:<base58> for AddKey, lookup, signing, and DeleteKey, and the compact ml-dsa-65-hash:<base58> handle NEAR stores on-chain — reconcile them with publicKeyToHandle().
  • Wire facts: 1,952-byte public keys, 3,309-byte signatures, and a 100 Ggas charge per verification. Scope is access keys and transaction signatures only — validator and staking keys stay Ed25519.
Enroll and sign

The flow from the @fastnear/ml-dsa-65 quickstarts (ESM). Requires the package and an RPC on protocol v85.

import { generateSigner } from "@fastnear/ml-dsa-65";
import { actions, queryProtocolVersion, sendTx } from "@fastnear/api";

// 1. Create an in-memory post-quantum signer.
const signer = generateSigner();

// 2. Enroll signer.publicKey with a classical full-access AddKey
//    (this step needs an existing classical signer).

// 3. Require an RPC on protocol v85, then sign + submit.
if ((await queryProtocolVersion({ network: "testnet" })) < 85) {
  throw new Error("RPC does not support ML-DSA-65 yet");
}

await sendTx({
  signerId: "device.testnet",
  signer,
  receiverId: "device.testnet",
  actions: [actions.transfer("1")],
  waitUntil: "FINAL",
  network: "testnet",
});
Opt-in, with a security caveat

Add @fastnear/ml-dsa-65 alongside @fastnear/api to enable it. The reference backend (@noble/post-quantum) is self-audited and not constant-time — use a hardware or WASM signer for stronger threat models, and never log or persist a generated seed or secret key. Read the full explainer for key forms, wire sizes, and safety rules. Full quickstarts — generate, explicit-send, enroll-delete, reconcile — live in recipes.json, with the scheme defined in NIST FIPS 204.

HTTP payments New

Pay x402-protected URLs with NEAR.

x402 turns HTTP 402 Payment Required into a machine-payable flow: the server answers with a payment challenge, the client pays, and the same request retries with proof of payment. @fastnear/x402 implements the official x402 v2 exact scheme on near:mainnet and near:testnet — payments settle as NEP-141 token transfers authorized with a NEP-366 SignedDelegate. The package ships separately and is not part of near.js or agents.js.

How it works
  • Every payer path ends in createNearPaymentFetch — a drop-in fetch that answers a 402 challenge by paying, then retries the request.
  • Settlement is one NEP-141 ft_transfer (30 TGas, 1 yoctoNEAR deposit) relayed by a facilitator that pays gas on the payer's behalf; payers sign with full-access keys.
  • Four focused entrypoints keep secrets out of the wallet page: the root for browser wallet payers (global nearX402), /node for local-key payers, /server for sellers, and /facilitator for relayer operators.
  • Sellers always configure a facilitator explicitly — there is no hidden default — and browser payments only happen on explicit user actions.
Browser paid fetch

IIFE globals from wallet.js and x402.js. Connect and pay must be explicit user actions — never auto-connect or auto-pay.

<script src="https://js.fastnear.com/wallet.js"></script>
<script src="https://js.fastnear.com/x402.js"></script>
<script type="module">
  // Wire these to buttons: connect first, pay second.
  await nearWallet.connect();

  const signer = nearX402.createFastNearWalletSigner({
    wallet: nearWallet,
  });

  const paidFetch = nearX402.createNearPaymentFetch({
    signer,
    network: "near:testnet",
  });

  const response = await paidFetch("https://seller.example.com/paid");
</script>
Wallet compatibility, and where to go deeper

The browser path is stable with tested Meteor Wallet support; other wallets must advertise both timeout-aware delegate-signing capabilities and pass the x402 testnet harness before being documented as compatible. Read the full explainer for the seller and facilitator roles, or go straight to the x402 key in recipes.json and the @fastnear/x402 README or the package on npm.

Browser example

Berry Club and berry.fast show the same library working in real apps.

The same FastNear JS runtime driving a live app — a berry.fast board crop and wallet-backed Berry Club actions (or a testnet counter on testnet).

Live example

berry.fast board preview

Open berry.fast

Loading live berry.fast crop…

Wallet-backed example

Draw or buy tokens

Example app

The same library you used in the terminal — now driving a browser app.

Total supply —
Your balance —
Custom contract connected

Signed in as —

Custom

Target contract —. Use the browser DevTools console with near.recipes.viewContract({ … }) or near.view({ … }) for reads, and near.recipes.functionCall({ … }) for writes — both accept an optional { network } override so a one-off testnet call from a mainnet-active page doesn't need a config flip.