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 lower-level FastNear families when the question is about direct RPC, indexed transactions, transfers, recent blocks, or contract storage history.

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.

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.