-
In: gas, deposits, and amounts accept a
string,number, orbigint— plus readable unit strings like"100 Tgas"and"0.01 NEAR". -
Out: wide integers (
u64/u128— amounts, gas, nonces) come back as decimal strings, JSON-safe and matching NEAR RPC. -
Inspect a transaction with
near.explain.tx(...)ornear.utils.txToJson(...)— neverJSON.stringifya rawbigint(it throws). -
You never need
BigIntto build, send, or read a transaction.
Build, preview, and send — no BigInt.
A NEAR transaction is a receiverId plus an ordered list of actions. With
@fastnear/api you declare the actions, preview them, and sign from a wallet or a
local key. There is one rule to learn, and it removes the whole class of big-number snags:
you pass amounts in whatever form is handy, and you always get decimal strings back.
near.explain.tx is a pure function — it returns a JSON-safe summary of
exactly what you are about to sign, with no network call and no wallet popup.
// One action: draw a green pixel on berryclub.ek.near.
const actions = [
near.actions.functionCall({
methodName: "draw",
args: { pixels: [{ x: 10, y: 20, color: "00FF00" }] },
gas: "100 Tgas", // or 100000000000000, or 100000000000000n
deposit: "0.01 NEAR", // or a yocto string like "10000000000000000000000"
}),
];
// Preview before signing — JSON-safe, gas/deposit stay as you wrote them.
near.print(near.explain.tx({
signerId: "alice.near",
receiverId: "berryclub.ek.near",
actions,
}));
The same actions, two signers.
Once the actions are declared, sending is one call. In a browser the wallet holds the key; in Node you sign locally with a full-access key. Both accept the identical action shape and the same unit strings.
After nearWallet.connect(...), the wallet signs. Load the IIFE globals
(near.js, wallet.js) or import @fastnear/api +
@fastnear/wallet.
// Wallet-signed. Units in, no BigInt — the popup confirms the deposit.
const result = await near.recipes.functionCall({
receiverId: "berryclub.ek.near",
methodName: "draw",
args: { pixels: [{ x: 10, y: 20, color: "00FF00" }] },
gas: "100 Tgas",
deposit: "0.01 NEAR",
});
near.print(result); // outcome amounts/gas are decimal strings
Sign with a full-access key from @fastnear/utils. Keep the key in
server-side secret storage — never ship it to a browser.
import { actions, config, sendTx } from "@fastnear/api";
import { signerFromPrivateKey } from "@fastnear/utils";
config({ networkId: "mainnet" });
const result = await sendTx({
signerId: "alice.near",
signer: signerFromPrivateKey(privateKey), // full-access key
receiverId: "berryclub.ek.near",
actions: [
actions.functionCall({
methodName: "draw",
args: { pixels: [{ x: 10, y: 20, color: "00FF00" }] },
gas: "100 Tgas",
deposit: "0.01 NEAR",
}),
],
waitUntil: "FINAL",
});
Big numbers are strings, everywhere.
NEAR amounts exceed Number's safe range, so they are never plain JS numbers.
Across @fastnear they are decimal strings on the way out — the
same shape NEAR JSON-RPC uses — so a decoded transaction survives JSON.stringify
and re-encodes to identical bytes. Reach for BigInt only if you need arithmetic.
-
JSON.stringify(tx)never throws — there is nobigintto trip on. -
Values from
near.view,near.ft.balance, and decoded borsh are all strings, so they interoperate without conversion. -
Serializing accepts
string | number | bigint, so a value you read can be sent straight back.
-
@fastnear/borshdeserializereturnsu64/u128as decimal strings by default. -
Pass
deserialize(schema, bytes, { bigints: "bigint" })to opt into nativebigintwhen you want arithmetic. -
u8/u16/u32stay JS numbers (they fit safely).
AI agents: the "Result shapes" section of
llms-full.txt
states the wide-integers rule, and
recipes.json
is the structured task catalog (see the explain-transaction,
function-call, and transfer recipes). Rate-limited? Free trial
credits are at
dashboard.fastnear.com
— set near.config({ apiKey }) once you have one.