@anywalletkit/wallet-near

中文文档
0.4.0发布于 2026/11/03Apache-2.0TypeScriptESM + CJS构建来源已验证近 30 天下载 2440

NEAR wallet for Any Wallet Kit: SLIP-10 m/44'/397'/i' accounts (NEAR Wallet path), implicit and named accounts, NEAR and NEP-141 transfers over JSON-RPC, hand-written borsh, NEP-413 message signing.

原始使用文档
文档目录6 节
  1. Install
  2. What happens before a signature
  3. NEP-141 tokens
  4. Accounts
  5. Network
  6. Activity history

@anywalletkit/wallet-near

npm

NEAR accounts at m/44'/397'/i' (SLIP-10 ed25519 — the NEAR Wallet / near-seed-phrase path; index 0 is what every NEAR wallet derives), pinned by golden vectors in @anywalletkit/conformance. No near-api-js: borsh is hand-written against the nearcore schema (byte-for-byte checked against @near-js/transactions), the node answers JSON-RPC, the account signs sha256(borsh(tx)) with noble ed25519 and broadcasts with send_tx.

Install

npm install @anywalletkit/wallet-near
# or: pnpm add @anywalletkit/wallet-near  ·  yarn add @anywalletkit/wallet-near

On npm: @anywalletkit/wallet-near, published from the release workflow with provenance.

import WalletManagerNear from '@anywalletkit/wallet-near'

const wallet = new WalletManagerNear(seedPhrase, { provider: ['https://free.rpc.fastnear.com', 'https://rpc.mainnet.near.org'] })
const account = await wallet.getAccount(0)          // implicit account: 64-hex id = the public key
await account.transfer({ recipient: 'alice.near', amount: 10n ** 24n })                              // 1 NEAR (yocto)
await account.transfer({ token: 'usdt.tether-token.near', recipient: 'alice.near', amount: 1_000_000n, memo: 'rent' }) // NEP-141
await account.sendTransaction({ receiverId: 'wrap.near', actions: [{ functionCall: { methodName: 'near_deposit', args: {}, gas: 30n * 10n ** 12n, deposit: 10n ** 24n } }] })
const sig = await account.sign('hello')             // "ed25519:<base58>" over the raw bytes; 32 bytes are refused (MessageIsTransactionError: a tx hash)
const nep413 = await account.signNep413({ message, nonce, recipient: 'intents.near' }) // what NEAR Intents / dApps ask for
const named = await wallet.getNamedAccount('alice.near') // same key, bound to a named account
wallet.dispose()

What happens before a signature

Every signTransaction / sendTransaction / transfer goes through the same gate:

  1. Build: signerId / publicKey are the account's; nonce = access-key nonce + 1 and blockHash = the latest final block come from the node (so needsNetwork is true).
  2. Hard checks (UnsafeTransactionError, with a code): the signer and key are this account; at least one action; no dangerous action — AddKey, DeleteKey, DeleteAccount, DeployContract, Stake, CreateAccount, global-contract actions, SignedDelegate — unless allowDangerousActions: true; a valid receiver id; prepaid gas ≤ 300 Tgas; fee ≤ transactionMaxFee when set.
  3. Preflight (SimulationError, off with simulate: false) — NEAR has no dry-run RPC, so this is what makes a transaction fail before a fee is paid: the signer account and its access key exist and allow the call, the spendable balance (total − locked − storage) covers deposits + fee, a named recipient exists (an implicit one may be created, for ≥ 0.002 NEAR), the NEP-141 balance covers an ft_transfer, the recipient is registered on the token or a storage_deposit rides along.
  4. Fee estimate (upper bound: prepaid gas counts in full; unused gas is refunded; a native transfer that creates an implicit account adds the protocol's ~0.007 NEAR creation charge — measured on mainnet, not derivable from gas) and the transferMaxFee / transactionMaxFee cap.

signBuilt(tx) signs a transaction you built yourself (nonce, block hash and all). It runs the same step 2 hard checks — this account's signer and key, no dangerous action unless allowDangerousActions: true, well-formed actions, gas ≤ 300 Tgas — but makes no node call, so there is no preflight and no fee cap.

Measured on mainnet (2026-10-10): ft_transfer 11.6 Tgas / 0.00041 NEAR; native transfer creating the recipient 15.9 Tgas / 0.0071 NEAR.

describeTransaction(tx) tells you what a transaction does, offline: near-transfer, ft-transfer (recipient / amount / memo decoded from the args), ft-storage-deposit, function-call, batch, or the dangerous kinds — with warnings (dangerous-action, full-access-key, zero-amount, self-transfer, high-gas, unknown-method, invalid-account). account.describeTransactionOnline(tx) adds implicit-new-account.

NEP-141 tokens

transfer({ token, recipient, amount, memo }) sends ft_transfer with 1 yoctoNEAR and 30 Tgas. When the recipient is not registered on the token (storage_balance_of is null) a storage_deposit for storage_balance_bounds.min (0.00125 NEAR on most tokens) is prepended in the same transaction. getTokenBalance(token) is ft_balance_of.

Accounts

An implicit account exists from the first NEAR it receives; an account holding only tokens and no NEAR cannot sign (nothing pays gas) — simulateTransaction reports that. A named account (alice.near) that lists this key as a full-access key works through getNamedAccount. getBalance() is the total; getAvailableBalance() is what can be spent.

Network

provider is one or more JSON-RPC urls (or custom transports); a list fails over in order, except for definitive node answers (unknown account, invalid transaction) which are returned as they are. Every url request times out after timeoutMs (default 15 000), so a node that never answers fails over. send_tx is never re-sent to another RPC: without a definitive answer (no response, a node timeout) it throws BroadcastUnknownError with the locally computed hash — watch it, do not sign again. rpc.mainnet.near.org is rate-limited and deprecated for production — use FastNear / a provider / your own proxy. CAIP-2: near:mainnet (default) or near:testnet.

Activity history

createNearHistory is the chain's HistorySource (@anywalletkit/core) over the nearblocks API, optionally sharpened by an archival RPC.

import { createNearHistory } from '@anywalletkit/wallet-near/history'

const history = createNearHistory({ apiKey: process.env.NEARBLOCKS_KEY, rpcUrl: 'https://archival-rpc.mainnet.near.org' })
const page = await history.listActivity('fc647e203e0e099212485017b78a0e77dc330019d4b532a4d44408adc0bfd9a1', { limit: 25 })
const older = await history.listActivity(address, { cursor: page.cursor })
const one = await history.getTransaction(page.items[0].hash, address)
history.explorerTxUrl(one.hash) // https://nearblocks.io/txns/…
optiondefaultnotes
nearblocksUrlhttps://api.nearblocks.io (api-testnet.nearblocks.io)
apiKeynoneBearer key. Keyless nearblocks is limited to a few requests per minute.
rpcUrlnoneEXPERIMENTAL_tx_status for getTransaction. Must be archival for anything older than a few days: rpc.mainnet.near.org answered UNKNOWN_TRANSACTION for a two-week-old hash, archival-rpc.mainnet.near.org served it.
networkmainnetnear:mainnet / near:testnet.
rateLimit0.1 rps (6/min) keyless, 5 with a keynearblocks requests per second; a page needs two.
fetch, timeoutMsglobal, 15 000

Lists. GET /v1/account/{id}/txns?per_page=&order=desc&cursor= (receipt-level rows, asked for twice the limit since a transaction usually has a call and a refund receipt) and GET /v1/account/{id}/ft-txns?per_page=&order=desc&cursor= (NEP-141 movements), grouped by transaction_hash. nearblocks writes large yoctoNEAR values as JSON numbers; bodies go through parseJsonPreservingBigInts, which re-quotes 16+ digit integer literals before JSON.parse so they stay exact, while values nearblocks had already rounded to a double (7e+23) are used as-is and flag the row raw.approximate. delta_amount of NEP-141 rows is a string and always exact.

Mapping. Receipt rows whose predecessor is system (gas refunds) carry no transfers. TRANSFER actions and FUNCTION_CALL deposits (other than the NEP-141 one-yoctoNEAR formality) become native transfers predecessor → receiver; the first non-transfer action of the receipt addressed to someone else becomes call (to = receiver, method, programs = every method in order). NEP-141 rows become nep141 transfers with the contract as token, symbol / decimals from ft (an ft_transfer_call into intents.near is own → intents.near, what @anywalletkit/protocol-swap2-near-intents looks for). status from outcomes.status, fee from outcomes_agg.transaction_fee, block = the lowest block_height of the group, time from the transaction's block_timestamp.

Cursor. Base64 JSON { v: 1, tx, ft }: the id / event_index of the last consumed row of each list ('' = not started, null = exhausted) — nearblocks' cursor= is a keyset, so the page can take the top limit transactions by block time plus ties and resume each list exactly where it stopped; a list that came back short and fully consumed is not asked again. Receipts of one transaction share the transaction's block_timestamp, so a transaction is never split across pages (an NEP-141 row carries its receipt's block time and may land one page later as a row of its own).

Single transaction. GET /v1/txns/{hash} (transaction-level actions, signer / receiver, receipts[].fts with double deltas → raw.approximate). With rpcUrl, EXPERIMENTAL_tx_status(hash, signer) rebuilds the row exactly: native legs from Transfer / FunctionCall deposits (delegate actions unwrapped, so call.to is the real receiver), NEP-141 legs from receipt logs (EVENT_JSON nep141 ft_transfer / ft_mint / ft_burn and the legacy Transfer N from A to B line wrap.near emits), fee = Σ tokens_burnt, status from Failure; raw.rpc holds the result. An RPC that does not know the hash or is down leaves the nearblocks row in place.

Fixtures in test/fixtures/history/ were captured on 2026-10-14 from api.nearblocks.io (keyless) and archival-rpc.mainnet.near.org: the test wallet's /txns page (a NEAR send with its refund receipt, a storage_deposit + ft_transfer call, a receive from intents.near) and its empty /ft-txns, plus — because the test wallet has no NEP-141 rows — the /txns, /ft-txns, /v1/txns/{hash} and RPC EXPERIMENTAL_tx_status of the NEAR Intents module's fixture transaction Fdk3i7f9… (20.5 wNEAR ft_transfer_call into intents.near by b1633df6…). test/history.test.ts checks that the near-intents module describes both the list row and the RPC-refined row as Bridged wNEAR.

版本与发布记录

@anywalletkit/wallet-near 共发布 13 个版本,首次发布于 2026/10/25;过去 12 个月发布了 13 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.4.0latest2026/11/035 天前
0.3.12026/10/308 天前
0.3.02026/10/309 天前
0.2.02026/10/2810 天前
0.1.92026/10/2811 天前
0.1.82026/10/2712 天前

关于 @anywalletkit/wallet-near 的常见问题

@anywalletkit/wallet-near 是什么?

NEAR wallet for Any Wallet Kit: SLIP-10 m/44'/397'/i' accounts (NEAR Wallet path), implicit and named accounts, NEAR and NEP-141 transfers over JSON-RPC, hand-written borsh, NEP-413 message signing.

如何安装 @anywalletkit/wallet-near?

在项目目录运行 npm install @anywalletkit/wallet-near,或使用 pnpm add / yarn add / bun add。

@anywalletkit/wallet-near 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@anywalletkit/wallet-near 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@anywalletkit/wallet-near 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@anywalletkit/wallet-near 可以商用吗?

@anywalletkit/wallet-near 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@anywalletkit/wallet-near 的下载量有多少?

根据 npm 官方下载统计,@anywalletkit/wallet-near 在 2026/10/06 – 2026/11/04 这 30 天内被下载 2,440 次,日均约 81 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@anywalletkit/wallet-near 还在维护吗?

最新版本 0.4.0 发布于 2026/11/03(5 天前);至今共发布 13 个版本,其中过去 12 个月发布了 13 个;首次发布于 2026/10/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。