Keys and accounts

Make a key, recover it anywhere.

A NEAR account is controlled by keys. Generate one from a BIP-39 seed phrase you can write down and recover in near-cli or any wallet, derive the implicit account it controls, or create and fund a fresh testnet account — all with @fastnear.

Why a separate package
  • Seed-phrase support lives in @fastnear/seed-phrase, so the bip39 wordlist and HD-derivation code never bloat the @fastnear/api core.
  • Derivation matches near-seed-phrase / near-cli exactly (SLIP-0010 ed25519 at m/44'/397'/0') — a phrase recovers the same key across every NEAR tool.
  • Load it in a browser with <script src="https://js.fastnear.com/seed-phrase.js"></script> next to near.js — it defines the NearSeedPhrase global (generateSeedPhrase, parseSeedPhrase, NEAR_DERIVATION_PATH) — or import it in ESM / Node.
Generate + recover

generateSeedPhrase makes a fresh key and its phrase; parseSeedPhrase recovers the exact same key. Both return ed25519: key strings.

import { generateSeedPhrase, parseSeedPhrase } from "@fastnear/seed-phrase";

// Create a fresh key pair and its 12-word recovery phrase.
const { seedPhrase, publicKey, privateKey } = generateSeedPhrase();

// Recover the exact same keys later — byte-identical to near-cli.
const recovered = parseSeedPhrase(seedPhrase);
// recovered.publicKey === publicKey, recovered.privateKey === privateKey

// generateSeedPhrase(256) makes a 24-word phrase.
Implicit and funded accounts

Derive an address, or fund a testnet account.

Every ed25519 key already controls an implicit account — the 64-char hex of its public key — with no on-chain setup. To get a named testnet account, let the testnet faucet create and fund it for your key in one call.

Implicit + funded testnet

near.implicitAccountId is pure. near.createFundedTestnetAccount POSTs to the NEAR testnet helper faucet — testnet only, there is no mainnet faucet.

import * as near from "@fastnear/api";

// The faucet is testnet-only, and the default active network is mainnet —
// pin testnet so the key and later sends land on the same network.
near.config({ networkId: "testnet" });

const privateKey = near.utils.privateKeyFromRandom();
const publicKey = near.utils.publicKeyFromPrivate(privateKey);

// The account this key controls with no AddKey — 64-char hex.
near.print(near.implicitAccountId(publicKey));

// Or create + fund a named testnet account via the faucet.
const result = await near.createFundedTestnetAccount({
  newAccountId: "my-agent.testnet",
  publicKey,
});

// Persist the key in the *testnet* slot — account state is per network and
// the default active network is mainnet. After this,
// near.sendTx({ network: "testnet", ... }) signs for this account locally,
// with no wallet. Needs @fastnear/api 2.1.1+.
near.state.updateAccountState(
  { accountId: "my-agent.testnet", privateKey },
  "testnet",
);
near.print(result);
Which key helper?
  • Recoverable: @fastnear/seed-phrase — a human-writable phrase backs up the key.
  • Throwaway: near.utils.privateKeyFromRandom() — a fresh key with no phrase.
  • Hand privateKey to near.state.updateAccountState and near.sendTx signs for that account locally — no wallet, no popup. A full-access key signs any action this way.
  • Version floor: that persisted-key path needs @fastnear/api 2.1.1 or newer. Earlier releases ignored the stored key and threw Must sign in. Passing signer: signerFromPrivateKey(privateKey) to sendTx works on any version.
Go deeper

AI agents: recipes.json carries the account-from-seed-phrase and create-testnet-account recipes. Sign a transaction with the new key on the transactions page, or sign gaslessly on meta-transactions. Rate-limited? Free trial credits are at dashboard.fastnear.com.