UNPKG

@fastnear/api

Version:

Interact with NEAR Protocol blockchain including transaction signing, utilities, and more.

1,328 lines 46.3 kB
/* ⋈ 🏃🏻💨 FastNear API - CJS (@fastnear/api version 1.2.0) */ /* https://www.npmjs.com/package/@fastnear/api/v/1.2.0 */ "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var near_exports = {}; __export(near_exports, { MaxBlockDelayMs: () => MaxBlockDelayMs, accountId: () => accountId, actions: () => actions, afterTxSent: () => afterTxSent, api: () => api, authStatus: () => authStatus, config: () => config, event: () => event, exp: () => exp, explain: () => explain, fastdata: () => fastdata, ft: () => ft, generateTxId: () => generateTxId, getPublicKeyForContract: () => getPublicKeyForContract, localTxHistory: () => localTxHistory, neardata: () => neardata, nft: () => nft, print: () => print, publicKey: () => publicKey, queryAccessKey: () => queryAccessKey, queryAccount: () => queryAccount, queryBlock: () => queryBlock, queryTx: () => queryTx, recipes: () => recipes, requestSignIn: () => requestSignIn, selected: () => selected, sendRpc: () => sendRpc, sendTx: () => sendTx, sendTxToRpc: () => sendTxToRpc, signMessage: () => signMessage, signOut: () => signOut, state: () => state, transfers: () => transfers, tx: () => tx, useWallet: () => useWallet, utils: () => utils, view: () => view, withBlockId: () => withBlockId }); module.exports = __toCommonJS(near_exports); var import_utils = require("@fastnear/utils"); var import_state = require("./state.js"); var import_state2 = require("./state.js"); var import_sha2 = require("@noble/hashes/sha2.js"); var reExportAllUtils = __toESM(require("@fastnear/utils"), 1); var stateExports = __toESM(require("./state.js"), 1); const MaxBlockDelayMs = 1e3 * 60 * 60 * 6; function normalizeActionParams(action) { if (!action || typeof action !== "object") { return {}; } if (action.params && typeof action.params === "object") { return { ...action.params }; } const { type, ...rest } = action; return { ...rest }; } __name(normalizeActionParams, "normalizeActionParams"); function looksRetryable(message, code, kind) { if (kind === "transport_error") { return true; } if (typeof code === "number" && [408, 429, 500, 502, 503, 504, -32e3].includes(code)) { return true; } return /timeout|temporar|temporarily|rate limit|unavailable|network|gateway/i.test(message); } __name(looksRetryable, "looksRetryable"); function parseErrorPayload(error) { const fallbackMessage = error instanceof Error ? error.message : typeof error === "string" ? error : "Unknown error"; const parsedMessage = (0, import_utils.tryParseJson)(fallbackMessage); const parsedObject = parsedMessage && typeof parsedMessage === "object" ? parsedMessage : error && typeof error === "object" ? error : null; const code = parsedObject && "code" in parsedObject ? parsedObject.code : null; const data = parsedObject && "data" in parsedObject ? parsedObject.data : parsedMessage && parsedMessage !== parsedObject ? parsedMessage : null; const name = error instanceof Error ? error.name : parsedObject && "name" in parsedObject ? String(parsedObject.name) : "Error"; const message = parsedObject && "message" in parsedObject ? String(parsedObject.message) : fallbackMessage; let kind = "error"; if (parsedObject && ("code" in parsedObject || "data" in parsedObject)) { kind = "rpc_error"; } else if (/wallet/i.test(message)) { kind = "wallet_error"; } else if (/network|timeout|fetch|gateway|unavailable/i.test(message)) { kind = "transport_error"; } return { code, name, message, data, kind }; } __name(parseErrorPayload, "parseErrorPayload"); function withBlockId(params, blockId) { if (blockId === "final" || blockId === "optimistic") { return { ...params, finality: blockId }; } return blockId ? { ...params, block_id: blockId } : { ...params, finality: "optimistic" }; } __name(withBlockId, "withBlockId"); const SERVICE_AUTH_STYLES = { rpc: "query", api: "bearer", tx: "bearer", transfers: "bearer", neardata: "query", "fastdata.kv": "bearer" }; function omitUndefinedEntries(value) { if (!value) { return void 0; } return Object.fromEntries( Object.entries(value).filter(([, entry]) => entry !== void 0) ); } __name(omitUndefinedEntries, "omitUndefinedEntries"); function trimTrailingSlash(value) { return value.replace(/\/+$/, ""); } __name(trimTrailingSlash, "trimTrailingSlash"); function trimLeadingSlash(value) { return value.replace(/^\/+/, ""); } __name(trimLeadingSlash, "trimLeadingSlash"); function appendQueryParams(url, query) { if (!query) { return url; } for (const [key, value] of Object.entries(query)) { if (value === void 0 || value === null) { continue; } if (Array.isArray(value)) { value.forEach((item) => { if (item !== void 0 && item !== null) { url.searchParams.append(key, String(item)); } }); continue; } url.searchParams.set(key, String(value)); } return url; } __name(appendQueryParams, "appendQueryParams"); function buildUrl(baseUrl, path, query) { const url = new URL(trimLeadingSlash(path), `${trimTrailingSlash(baseUrl)}/`); return appendQueryParams(url, query).toString(); } __name(buildUrl, "buildUrl"); async function parseResponsePayload(response) { const text = await response.text(); if (!text) { return null; } try { return JSON.parse(text); } catch { return text; } } __name(parseResponsePayload, "parseResponsePayload"); function buildHttpError(service, response, payload) { return new Error( JSON.stringify({ code: response.status, name: `${service}.http_error`, message: `${service} request failed with ${response.status} ${response.statusText}`, data: payload }) ); } __name(buildHttpError, "buildHttpError"); function resolveConfigForCall(network) { const active = (0, import_state2.getConfig)(); if (!network || network === active.networkId) { return active; } return (0, import_state2.resolveConfig)({ apiKey: active.apiKey ?? null }, import_state.NETWORKS[network]); } __name(resolveConfigForCall, "resolveConfigForCall"); function resolveServiceBaseUrl(family, config2) { let baseUrl; switch (family) { case "api": baseUrl = config2.services?.api?.baseUrl; break; case "tx": baseUrl = config2.services?.tx?.baseUrl; break; case "transfers": baseUrl = config2.services?.transfers?.baseUrl; break; case "neardata": baseUrl = config2.services?.neardata?.baseUrl; break; case "fastdata.kv": baseUrl = config2.services?.fastdata?.kvBaseUrl; break; } if (!baseUrl) { if (family === "transfers" && config2.networkId === "testnet") { throw new Error( 'fastnear: transfers service is not configured for testnet. Provide near.config({ services: { transfers: { baseUrl: "https://..." } } }) to override.' ); } throw new Error(`fastnear: ${family} service is not configured for ${config2.networkId}.`); } return baseUrl; } __name(resolveServiceBaseUrl, "resolveServiceBaseUrl"); function resolveRpcUrl(config2) { const rpcUrl = config2.nodeUrl || config2.services?.rpc?.baseUrl; if (!rpcUrl) { throw new Error("fastnear: getConfig() returned invalid config: missing nodeUrl."); } return rpcUrl; } __name(resolveRpcUrl, "resolveRpcUrl"); function resolveArchivalUrl(config2) { return config2.services?.archival?.baseUrl || resolveRpcUrl(config2); } __name(resolveArchivalUrl, "resolveArchivalUrl"); function buildAuthedUrl(service, baseUrl, path = "", query, config2 = (0, import_state2.getConfig)()) { const authStyle = SERVICE_AUTH_STYLES[service]; const authQuery = authStyle === "query" && config2.apiKey ? { ...query || {}, apiKey: config2.apiKey } : query; return buildUrl(baseUrl, path, authQuery); } __name(buildAuthedUrl, "buildAuthedUrl"); async function sendServiceRequest({ family, path, method = "GET", query, body, headers = {}, network }) { const config2 = resolveConfigForCall(network); const authStyle = SERVICE_AUTH_STYLES[family]; const url = buildAuthedUrl(family, resolveServiceBaseUrl(family, config2), path, query, config2); const requestHeaders = { ...headers }; if (authStyle === "bearer" && config2.apiKey) { requestHeaders.Authorization = `Bearer ${config2.apiKey}`; } let requestBody; if (body !== void 0) { requestHeaders["Content-Type"] = requestHeaders["Content-Type"] || "application/json"; requestBody = JSON.stringify(body); } const response = await fetch(url, { method, headers: requestHeaders, body: requestBody }); const payload = await parseResponsePayload(response); if (!response.ok) { throw buildHttpError(family, response, payload); } return payload; } __name(sendServiceRequest, "sendServiceRequest"); async function sendRpc(method, params, options) { const config2 = resolveConfigForCall(options?.network); const baseUrl = options?.useArchival ? resolveArchivalUrl(config2) : resolveRpcUrl(config2); const response = await fetch(buildAuthedUrl("rpc", baseUrl, "", void 0, config2), { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: `fastnear-${Date.now()}`, method, params }) }); const result = await parseResponsePayload(response); if (!response.ok) { throw buildHttpError("rpc", response, result); } if (result && typeof result === "object" && "error" in result && result.error) { throw new Error(JSON.stringify(result.error)); } return result; } __name(sendRpc, "sendRpc"); function afterTxSent(txId, network) { const txHistory = (0, import_state.getTxHistory)(); sendRpc("tx", { tx_hash: txHistory[txId]?.txHash, sender_account_id: txHistory[txId]?.tx?.signerId, wait_until: "EXECUTED_OPTIMISTIC" }, { network }).then((result) => { const successValue = result?.result?.status?.SuccessValue; (0, import_state.updateTxHistory)({ txId, status: "Executed", result, successValue: successValue ? (0, import_utils.tryParseJson)((0, import_utils.fromBase64)(successValue)) : void 0, finalState: true }); }).catch((error) => { (0, import_state.updateTxHistory)({ txId, status: "ErrorAfterIncluded", error: (0, import_utils.tryParseJson)(error.message) ?? error.message, finalState: true }); }); } __name(afterTxSent, "afterTxSent"); async function sendTxToRpc(signedTxBase64, waitUntil, txId, network) { waitUntil = waitUntil || "INCLUDED"; try { const sendTxRes = await sendRpc("send_tx", { signed_tx_base64: signedTxBase64, wait_until: waitUntil }, { network }); (0, import_state.updateTxHistory)({ txId, status: "Included", finalState: false }); afterTxSent(txId, network); return sendTxRes; } catch (error) { const errorMessage = error instanceof Error ? error.message : "Unknown error"; (0, import_state.updateTxHistory)({ txId, status: "Error", error: (0, import_utils.tryParseJson)(errorMessage) ?? errorMessage, finalState: false }); throw new Error(errorMessage); } } __name(sendTxToRpc, "sendTxToRpc"); function generateTxId() { const randomPart = crypto.getRandomValues(new Uint32Array(2)).join(""); return `tx-${Date.now()}-${parseInt(randomPart, 10).toString(36)}`; } __name(generateTxId, "generateTxId"); const accountId = /* @__PURE__ */ __name((options = {}) => (0, import_state.getAccountState)(options.network).accountId, "accountId"); const publicKey = /* @__PURE__ */ __name((options = {}) => (0, import_state.getAccountState)(options.network).publicKey, "publicKey"); const config = /* @__PURE__ */ __name((newConfig) => { const current = (0, import_state2.getConfig)(); if (newConfig) { const networkChanging = !!newConfig.networkId && current.networkId !== newConfig.networkId; (0, import_state2.setConfig)(newConfig); if (networkChanging) { (0, import_state2.resetTxHistory)(); } if (newConfig.networkId) { (0, import_state.setActiveNetwork)((0, import_state2.getConfig)().networkId); } } return (0, import_state2.getConfig)(); }, "config"); const authStatus = /* @__PURE__ */ __name((options = {}) => { return (0, import_state.getAccountState)(options.network).accountId ? "SignedIn" : "SignedOut"; }, "authStatus"); const getPublicKeyForContract = /* @__PURE__ */ __name((options = {}) => { return publicKey(options); }, "getPublicKeyForContract"); const selected = /* @__PURE__ */ __name((options = {}) => { const network = options.network ?? (0, import_state2.getConfig)().networkId; const slot = (0, import_state.getAccountState)(network); return { network, nodeUrl: (0, import_state2.getConfig)().nodeUrl, walletUrl: (0, import_state2.getConfig)().walletUrl, helperUrl: (0, import_state2.getConfig)().helperUrl, explorerUrl: (0, import_state2.getConfig)().explorerUrl, account: slot.accountId, contract: slot.accessKeyContractId, publicKey: slot.publicKey }; }, "selected"); const requestSignIn = /* @__PURE__ */ __name(async ({ contractId, excludedWallets, features, network } = {}) => { const provider = (0, import_state.getWalletProvider)(); if (!provider) { throw new Error("No wallet provider set. Call useWallet() first or load the @fastnear/wallet IIFE bundle."); } const targetNetwork = network ?? (0, import_state2.getConfig)().networkId; if (provider.isConnected({ network: targetNetwork })) { await provider.disconnect({ network: targetNetwork }); } const result = await provider.connect({ contractId, network: targetNetwork, excludedWallets, features }); if (!result) { return void 0; } (0, import_state.updateAccountState)({ accountId: result.accountId }, targetNetwork); (0, import_state.setActiveNetwork)(targetNetwork); return result; }, "requestSignIn"); const view = /* @__PURE__ */ __name(async ({ contractId, methodName, args, argsBase64, blockId, useArchival, network }) => { const encodedArgs = argsBase64 || (args ? (0, import_utils.toBase64)(JSON.stringify(args)) : ""); const queryResult = await sendRpc( "query", withBlockId( { request_type: "call_function", account_id: contractId, method_name: methodName, args_base64: encodedArgs }, blockId ), { useArchival, network } ); return (0, import_utils.parseJsonFromBytes)(queryResult.result.result); }, "view"); const queryAccount = /* @__PURE__ */ __name(async ({ accountId: accountId2, blockId, useArchival, network }) => { return sendRpc( "query", withBlockId({ request_type: "view_account", account_id: accountId2 }, blockId), { useArchival, network } ); }, "queryAccount"); const queryBlock = /* @__PURE__ */ __name(async ({ blockId, useArchival, network }) => { return sendRpc("block", withBlockId({}, blockId), { useArchival, network }); }, "queryBlock"); const queryAccessKey = /* @__PURE__ */ __name(async ({ accountId: accountId2, publicKey: publicKey2, blockId, useArchival, network }) => { return sendRpc( "query", withBlockId( { request_type: "view_access_key", account_id: accountId2, public_key: publicKey2 }, blockId ), { useArchival, network } ); }, "queryAccessKey"); const queryTx = /* @__PURE__ */ __name(async ({ txHash, accountId: accountId2, useArchival, network }) => { return sendRpc("tx", [txHash, accountId2], { useArchival, network }); }, "queryTx"); function shouldPrintInteractiveSeparator() { if (typeof process === "undefined") { return false; } return Boolean(process.stdout?.isTTY); } __name(shouldPrintInteractiveSeparator, "shouldPrintInteractiveSeparator"); function print(value) { if (shouldPrintInteractiveSeparator()) { console.log(""); } if (value === null || value === void 0 || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") { console.log(value); return; } try { console.log(JSON.stringify(value, null, 2)); } catch { console.log(value); } } __name(print, "print"); function requiredParam(value, name) { if (value === void 0 || value === null || value === "") { throw new Error(`fastnear: missing required parameter "${name}"`); } return value; } __name(requiredParam, "requiredParam"); function encodePathParam(value, name) { return encodeURIComponent(String(requiredParam(value, name))); } __name(encodePathParam, "encodePathParam"); function withAliases(params, aliases) { const next = { ...params }; for (const [from, to] of Object.entries(aliases)) { if (next[from] !== void 0 && next[to] === void 0) { next[to] = next[from]; } delete next[from]; } return next; } __name(withAliases, "withAliases"); const tx = { transactions: /* @__PURE__ */ __name(({ txHashes, network, ...filters }) => sendServiceRequest({ family: "tx", path: "/v0/transactions", method: "POST", network, body: omitUndefinedEntries({ ...filters, tx_hashes: requiredParam(txHashes, "txHashes") }) }), "transactions"), receipt: /* @__PURE__ */ __name(({ receiptId, network, ...filters }) => sendServiceRequest({ family: "tx", path: "/v0/receipt", method: "POST", network, body: omitUndefinedEntries({ ...filters, receipt_id: requiredParam(receiptId, "receiptId") }) }), "receipt"), account: /* @__PURE__ */ __name(({ accountId: accountId2, network, ...filters }) => sendServiceRequest({ family: "tx", path: "/v0/account", method: "POST", network, body: omitUndefinedEntries({ ...filters, account_id: requiredParam(accountId2, "accountId") }) }), "account"), block: /* @__PURE__ */ __name(({ network, ...params } = {}) => sendServiceRequest({ family: "tx", path: "/v0/block", method: "POST", network, body: omitUndefinedEntries(params) }), "block"), blocks: /* @__PURE__ */ __name(({ network, ...params } = {}) => sendServiceRequest({ family: "tx", path: "/v0/blocks", method: "POST", network, body: omitUndefinedEntries(params) }), "blocks") }; const api = { v1: { accountFull: /* @__PURE__ */ __name(({ accountId: accountId2, network, ...query }) => sendServiceRequest({ family: "api", path: `/v1/account/${encodePathParam(accountId2, "accountId")}/full`, network, query: omitUndefinedEntries(query) }), "accountFull"), accountFt: /* @__PURE__ */ __name(({ accountId: accountId2, network, ...query }) => sendServiceRequest({ family: "api", path: `/v1/account/${encodePathParam(accountId2, "accountId")}/ft`, network, query: omitUndefinedEntries(query) }), "accountFt"), accountNft: /* @__PURE__ */ __name(({ accountId: accountId2, network, ...query }) => sendServiceRequest({ family: "api", path: `/v1/account/${encodePathParam(accountId2, "accountId")}/nft`, network, query: omitUndefinedEntries(query) }), "accountNft"), accountStaking: /* @__PURE__ */ __name(({ accountId: accountId2, network, ...query }) => sendServiceRequest({ family: "api", path: `/v1/account/${encodePathParam(accountId2, "accountId")}/staking`, network, query: omitUndefinedEntries(query) }), "accountStaking"), publicKey: /* @__PURE__ */ __name(({ publicKey: publicKey2, network, ...query }) => sendServiceRequest({ family: "api", path: `/v1/public_key/${encodePathParam(publicKey2, "publicKey")}`, network, query: omitUndefinedEntries(query) }), "publicKey"), publicKeyAll: /* @__PURE__ */ __name(({ publicKey: publicKey2, network, ...query }) => sendServiceRequest({ family: "api", path: `/v1/public_key/${encodePathParam(publicKey2, "publicKey")}/all`, network, query: omitUndefinedEntries(query) }), "publicKeyAll"), ftTop: /* @__PURE__ */ __name(({ tokenId, network, ...query }) => sendServiceRequest({ family: "api", path: `/v1/ft/${encodePathParam(tokenId, "tokenId")}/top`, network, query: omitUndefinedEntries(query) }), "ftTop") } }; const transfers = { query: /* @__PURE__ */ __name(({ network, ...params } = {}) => sendServiceRequest({ family: "transfers", path: "/v0/transfers", method: "POST", network, body: omitUndefinedEntries(withAliases(params, { accountId: "account_id", resumeToken: "resume_token" })) }), "query") }; const ft = { balance: /* @__PURE__ */ __name(({ contractId, accountId: accountId2, blockId, useArchival, network }) => view({ contractId, methodName: "ft_balance_of", args: { account_id: accountId2 }, blockId, useArchival, network }), "balance"), metadata: /* @__PURE__ */ __name(({ contractId, blockId, useArchival, network }) => view({ contractId, methodName: "ft_metadata", args: {}, blockId, useArchival, network }), "metadata"), totalSupply: /* @__PURE__ */ __name(({ contractId, blockId, useArchival, network }) => view({ contractId, methodName: "ft_total_supply", args: {}, blockId, useArchival, network }), "totalSupply"), // NEP-145 storage-management read; many wallet/dApp flows need to know // whether an account is registered with the FT contract before transferring. storageBalance: /* @__PURE__ */ __name(({ contractId, accountId: accountId2, blockId, useArchival, network }) => view({ contractId, methodName: "storage_balance_of", args: { account_id: accountId2 }, blockId, useArchival, network }), "storageBalance"), // Cross-contract: list every FT contract this account holds, served by // the FastNear indexer. Layer-mixed but the natural name from the // agent's perspective. inventory: /* @__PURE__ */ __name(({ accountId: accountId2, network, ...query }) => sendServiceRequest({ family: "api", path: `/v1/account/${encodePathParam(accountId2, "accountId")}/ft`, network, query: omitUndefinedEntries(query) }), "inventory") }; const nft = { metadata: /* @__PURE__ */ __name(({ contractId, blockId, useArchival, network }) => view({ contractId, methodName: "nft_metadata", args: {}, blockId, useArchival, network }), "metadata"), token: /* @__PURE__ */ __name(({ contractId, tokenId, blockId, useArchival, network }) => view({ contractId, methodName: "nft_token", args: { token_id: tokenId }, blockId, useArchival, network }), "token"), forOwner: /* @__PURE__ */ __name(({ contractId, accountId: accountId2, fromIndex, limit, blockId, useArchival, network }) => view({ contractId, methodName: "nft_tokens_for_owner", args: omitUndefinedEntries({ account_id: accountId2, from_index: fromIndex, limit }), blockId, useArchival, network }), "forOwner"), supplyForOwner: /* @__PURE__ */ __name(({ contractId, accountId: accountId2, blockId, useArchival, network }) => view({ contractId, methodName: "nft_supply_for_owner", args: { account_id: accountId2 }, blockId, useArchival, network }), "supplyForOwner"), totalSupply: /* @__PURE__ */ __name(({ contractId, blockId, useArchival, network }) => view({ contractId, methodName: "nft_total_supply", args: {}, blockId, useArchival, network }), "totalSupply"), tokens: /* @__PURE__ */ __name(({ contractId, fromIndex, limit, blockId, useArchival, network }) => view({ contractId, methodName: "nft_tokens", args: omitUndefinedEntries({ from_index: fromIndex, limit }), blockId, useArchival, network }), "tokens"), // List every NFT contract this account holds, served by the FastNear indexer. inventory: /* @__PURE__ */ __name(({ accountId: accountId2, network, ...query }) => sendServiceRequest({ family: "api", path: `/v1/account/${encodePathParam(accountId2, "accountId")}/nft`, network, query: omitUndefinedEntries(query) }), "inventory") }; const neardata = { lastBlockFinal: /* @__PURE__ */ __name(({ network, ...query } = {}) => sendServiceRequest({ family: "neardata", path: "/v0/last_block/final", network, query: omitUndefinedEntries(query) }), "lastBlockFinal"), lastBlockOptimistic: /* @__PURE__ */ __name(({ network, ...query } = {}) => sendServiceRequest({ family: "neardata", path: "/v0/last_block/optimistic", network, query: omitUndefinedEntries(query) }), "lastBlockOptimistic"), block: /* @__PURE__ */ __name(({ blockHeight, network, ...query }) => sendServiceRequest({ family: "neardata", path: `/v0/block/${encodePathParam(blockHeight, "blockHeight")}`, network, query: omitUndefinedEntries(query) }), "block"), blockHeaders: /* @__PURE__ */ __name(({ blockHeight, network, ...query }) => sendServiceRequest({ family: "neardata", path: `/v0/block/${encodePathParam(blockHeight, "blockHeight")}/headers`, network, query: omitUndefinedEntries(query) }), "blockHeaders"), blockShard: /* @__PURE__ */ __name(({ blockHeight, shardId, network, ...query }) => sendServiceRequest({ family: "neardata", path: `/v0/block/${encodePathParam(blockHeight, "blockHeight")}/shard/${encodePathParam(shardId, "shardId")}`, network, query: omitUndefinedEntries(query) }), "blockShard"), blockChunk: /* @__PURE__ */ __name(({ blockHeight, shardId, network, ...query }) => sendServiceRequest({ family: "neardata", path: `/v0/block/${encodePathParam(blockHeight, "blockHeight")}/chunk/${encodePathParam(shardId, "shardId")}`, network, query: omitUndefinedEntries(query) }), "blockChunk"), blockOptimistic: /* @__PURE__ */ __name(({ blockHeight, network, ...query }) => sendServiceRequest({ family: "neardata", path: `/v0/block_opt/${encodePathParam(blockHeight, "blockHeight")}`, network, query: omitUndefinedEntries(query) }), "blockOptimistic"), firstBlock: /* @__PURE__ */ __name(({ network, ...query } = {}) => sendServiceRequest({ family: "neardata", path: "/v0/first_block", network, query: omitUndefinedEntries(query) }), "firstBlock"), health: /* @__PURE__ */ __name(({ network, ...query } = {}) => sendServiceRequest({ family: "neardata", path: "/health", network, query: omitUndefinedEntries(query) }), "health") }; const fastdata = { kv: { getLatestKey: /* @__PURE__ */ __name(({ currentAccountId, predecessorId, key, network, ...query }) => sendServiceRequest({ family: "fastdata.kv", path: `/v0/latest/${encodePathParam(currentAccountId, "currentAccountId")}/${encodePathParam(predecessorId, "predecessorId")}/${encodePathParam(key, "key")}`, network, query: omitUndefinedEntries(query) }), "getLatestKey"), getHistoryKey: /* @__PURE__ */ __name(({ currentAccountId, predecessorId, key, network, ...query }) => sendServiceRequest({ family: "fastdata.kv", path: `/v0/history/${encodePathParam(currentAccountId, "currentAccountId")}/${encodePathParam(predecessorId, "predecessorId")}/${encodePathParam(key, "key")}`, network, query: omitUndefinedEntries(query) }), "getHistoryKey"), latestByAccount: /* @__PURE__ */ __name(({ accountId: accountId2, network, ...body }) => sendServiceRequest({ family: "fastdata.kv", path: `/v0/latest/${encodePathParam(accountId2, "accountId")}`, method: "POST", network, body: omitUndefinedEntries(body) }), "latestByAccount"), historyByAccount: /* @__PURE__ */ __name(({ accountId: accountId2, network, ...body }) => sendServiceRequest({ family: "fastdata.kv", path: `/v0/history/${encodePathParam(accountId2, "accountId")}`, method: "POST", network, body: omitUndefinedEntries(body) }), "historyByAccount"), latestByPredecessor: /* @__PURE__ */ __name(({ currentAccountId, predecessorId, network, ...body }) => sendServiceRequest({ family: "fastdata.kv", path: `/v0/latest/${encodePathParam(currentAccountId, "currentAccountId")}/${encodePathParam(predecessorId, "predecessorId")}`, method: "POST", network, body: omitUndefinedEntries(body) }), "latestByPredecessor"), historyByPredecessor: /* @__PURE__ */ __name(({ currentAccountId, predecessorId, network, ...body }) => sendServiceRequest({ family: "fastdata.kv", path: `/v0/history/${encodePathParam(currentAccountId, "currentAccountId")}/${encodePathParam(predecessorId, "predecessorId")}`, method: "POST", network, body: omitUndefinedEntries(body) }), "historyByPredecessor"), allByPredecessor: /* @__PURE__ */ __name(({ predecessorId, network, ...body }) => sendServiceRequest({ family: "fastdata.kv", path: `/v0/all/${encodePathParam(predecessorId, "predecessorId")}`, method: "POST", network, body: omitUndefinedEntries(body) }), "allByPredecessor"), multi: /* @__PURE__ */ __name(({ network, ...body }) => sendServiceRequest({ family: "fastdata.kv", path: "/v0/multi", method: "POST", network, body: omitUndefinedEntries(body) }), "multi") } }; const localTxHistory = /* @__PURE__ */ __name(() => { return (0, import_state.getTxHistory)(); }, "localTxHistory"); const signOut = /* @__PURE__ */ __name(async ({ network } = {}) => { const provider = (0, import_state.getWalletProvider)(); const targetNetwork = network ?? (0, import_state2.getConfig)().networkId; if (provider?.isConnected({ network: targetNetwork })) { await provider.disconnect({ network: targetNetwork }); } (0, import_state.updateAccountState)( { accountId: null, privateKey: null, accessKeyContractId: null, lastWalletId: null }, targetNetwork ); if (network === void 0) { (0, import_state2.setConfig)(import_state.NETWORKS[import_state.DEFAULT_NETWORK_ID]); (0, import_state.setActiveNetwork)(import_state.DEFAULT_NETWORK_ID); } }, "signOut"); const sendTx = /* @__PURE__ */ __name(async ({ receiverId, actions: actions2, waitUntil, network }) => { const targetNetwork = network ?? (0, import_state2.getConfig)().networkId; const slot = (0, import_state.getAccountState)(targetNetwork); const signerId = slot.accountId; if (!signerId) throw new Error("Must sign in"); const pubKey = slot.publicKey ?? ""; const privKey = slot.privateKey; const txId = generateTxId(); if (!privKey || receiverId !== slot.accessKeyContractId || !(0, import_utils.canSignWithLAK)(actions2)) { const jsonTx = { signerId, receiverId, actions: actions2 }; (0, import_state.updateTxHistory)({ status: "Pending", txId, tx: jsonTx, finalState: false }); try { const provider = (0, import_state.getWalletProvider)(); if (!provider?.isConnected({ network: targetNetwork })) { throw new Error("Must sign in"); } const result = await provider.sendTransaction({ ...jsonTx, network: targetNetwork }); if (!result) { (0, import_state.updateTxHistory)({ txId, status: "RejectedByUser", finalState: true }); return { rejected: true }; } if (result.outcomes?.length) { result.outcomes.forEach( (r) => (0, import_state.updateTxHistory)({ txId, status: "Executed", result: r, txHash: r.transaction?.hash, finalState: true }) ); } return result; } catch (err) { console.error("fastnear: error sending tx using wallet provider:", err); (0, import_state.updateTxHistory)({ txId, status: "Error", error: (0, import_utils.tryParseJson)(err.message), finalState: true }); return Promise.reject(err); } } const nonceKey = `nonce.${targetNetwork}`; const blockKey = `block.${targetNetwork}`; let nonce = (0, import_utils.lsGet)(nonceKey); if (nonce == null) { const accessKey = await queryAccessKey({ accountId: signerId, publicKey: pubKey, network: targetNetwork }); if (accessKey.result.error) { throw new Error(`Access key error: ${accessKey.result.error} when attempting to get nonce for ${signerId} for public key ${pubKey}`); } nonce = accessKey.result.nonce; (0, import_utils.lsSet)(nonceKey, nonce); } let lastKnownBlock = (0, import_utils.lsGet)(blockKey); if (!lastKnownBlock || parseFloat(lastKnownBlock.header.timestamp_nanosec) / 1e6 + MaxBlockDelayMs < Date.now()) { const latestBlock = await queryBlock({ blockId: "final", network: targetNetwork }); lastKnownBlock = { header: { hash: latestBlock.result.header.hash, timestamp_nanosec: latestBlock.result.header.timestamp_nanosec } }; (0, import_utils.lsSet)(blockKey, lastKnownBlock); } nonce += 1; (0, import_utils.lsSet)(nonceKey, nonce); const blockHash = lastKnownBlock.header.hash; const plainTransactionObj = { signerId, publicKey: pubKey, nonce, receiverId, blockHash, actions: actions2 }; const txBytes = (0, import_utils.serializeTransaction)(plainTransactionObj); const txHashBytes = (0, import_sha2.sha256)(txBytes); const txHash58 = (0, import_utils.toBase58)(txHashBytes); const signatureBase58 = (0, import_utils.signHash)(txHashBytes, privKey, { returnBase58: true }); const signedTransactionBytes = (0, import_utils.serializeSignedTransaction)(plainTransactionObj, signatureBase58); const signedTxBase64 = (0, import_utils.bytesToBase64)(signedTransactionBytes); (0, import_state.updateTxHistory)({ status: "Pending", txId, tx: plainTransactionObj, signature: signatureBase58, signedTxBase64, txHash: txHash58, finalState: false }); return await sendTxToRpc(signedTxBase64, waitUntil, txId, targetNetwork); }, "sendTx"); const signMessage = /* @__PURE__ */ __name(async (message, options = {}) => { const provider = (0, import_state.getWalletProvider)(); const targetNetwork = options.network ?? (0, import_state2.getConfig)().networkId; if (!provider?.isConnected({ network: targetNetwork })) { throw new Error("Must sign in"); } if (!provider.signMessage) { throw new Error("Connected wallet does not support signMessage"); } return provider.signMessage({ ...message, network: targetNetwork }); }, "signMessage"); const useWallet = /* @__PURE__ */ __name((provider) => { (0, import_state.setWalletProvider)(provider); }, "useWallet"); const utils = reExportAllUtils; const event = stateExports.events; const state = (() => { const ns = { DEFAULT_NETWORK_ID: stateExports.DEFAULT_NETWORK_ID, NETWORKS: stateExports.NETWORKS, _config: stateExports._config, _txHistory: stateExports._txHistory, _unbroadcastedEvents: stateExports._unbroadcastedEvents, setWalletProvider: stateExports.setWalletProvider, getWalletProvider: stateExports.getWalletProvider, update: stateExports.update, updateAccountState: stateExports.updateAccountState, getAccountState: stateExports.getAccountState, getActiveNetwork: stateExports.getActiveNetwork, setActiveNetwork: stateExports.setActiveNetwork, updateTxHistory: stateExports.updateTxHistory, getConfig: stateExports.getConfig, getTxHistory: stateExports.getTxHistory, setConfig: stateExports.setConfig, resetTxHistory: stateExports.resetTxHistory }; Object.defineProperty(ns, "_state", { get: /* @__PURE__ */ __name(() => stateExports._state, "get"), enumerable: true }); return ns; })(); const exp = { utils, borsh: reExportAllUtils.exp.borsh, borshSchema: reExportAllUtils.exp.borshSchema.getBorshSchema() }; const actions = { functionCall: /* @__PURE__ */ __name(({ methodName, gas, deposit, args, argsBase64 }) => ({ type: "FunctionCall", methodName, args, argsBase64, gas, deposit }), "functionCall"), transfer: /* @__PURE__ */ __name((yoctoAmount) => ({ type: "Transfer", deposit: yoctoAmount }), "transfer"), stakeNEAR: /* @__PURE__ */ __name(({ amount, publicKey: publicKey2 }) => ({ type: "Stake", stake: amount, publicKey: publicKey2 }), "stakeNEAR"), addFullAccessKey: /* @__PURE__ */ __name(({ publicKey: publicKey2 }) => ({ type: "AddKey", publicKey: publicKey2, accessKey: { permission: "FullAccess" } }), "addFullAccessKey"), addLimitedAccessKey: /* @__PURE__ */ __name(({ publicKey: publicKey2, allowance, accountId: accountId2, methodNames }) => ({ type: "AddKey", publicKey: publicKey2, accessKey: { permission: "FunctionCall", allowance, receiverId: accountId2, methodNames } }), "addLimitedAccessKey"), deleteKey: /* @__PURE__ */ __name(({ publicKey: publicKey2 }) => ({ type: "DeleteKey", publicKey: publicKey2 }), "deleteKey"), deleteAccount: /* @__PURE__ */ __name(({ beneficiaryId }) => ({ type: "DeleteAccount", beneficiaryId }), "deleteAccount"), createAccount: /* @__PURE__ */ __name(() => ({ type: "CreateAccount" }), "createAccount"), deployContract: /* @__PURE__ */ __name(({ codeBase64 }) => ({ type: "DeployContract", codeBase64 }), "deployContract") }; const explain = { action: /* @__PURE__ */ __name((action) => { const type = action?.type ?? "Unknown"; const params = normalizeActionParams(action); switch (type) { case "FunctionCall": return { kind: "action", type, methodName: params.methodName ?? null, gas: params.gas ?? null, deposit: params.deposit ?? "0", args: params.args ?? null, argsBase64: params.argsBase64 ?? null, params }; case "Transfer": return { kind: "action", type, deposit: params.deposit ?? null, params }; case "Stake": return { kind: "action", type, stake: params.stake ?? null, publicKey: params.publicKey ?? null, params }; case "AddKey": return { kind: "action", type, publicKey: params.publicKey ?? null, accessKey: params.accessKey ?? null, params }; case "DeleteKey": return { kind: "action", type, publicKey: params.publicKey ?? null, params }; case "DeleteAccount": return { kind: "action", type, beneficiaryId: params.beneficiaryId ?? null, params }; case "DeployContract": return { kind: "action", type, codeBase64: params.codeBase64 ?? params.code ?? null, codeLength: typeof (params.codeBase64 ?? params.code) === "string" ? (params.codeBase64 ?? params.code).length : null, params }; case "CreateAccount": default: return { kind: "action", type, params }; } }, "action"), tx: /* @__PURE__ */ __name(({ signerId, receiverId, actions: actions2 }) => ({ kind: "transaction", signerId: signerId ?? null, receiverId, actionCount: actions2.length, actions: actions2.map((action) => explain.action(action)) }), "tx"), error: /* @__PURE__ */ __name((error) => { const parsed = parseErrorPayload(error); return { ...parsed, retryable: looksRetryable(parsed.message, parsed.code, parsed.kind) }; }, "error") }; function normalizeRecipeViewAccountParams(input) { return typeof input === "string" ? { accountId: input } : input; } __name(normalizeRecipeViewAccountParams, "normalizeRecipeViewAccountParams"); function normalizeRecipeInspectTransactionParams(input) { return typeof input === "string" ? { txHash: input } : input; } __name(normalizeRecipeInspectTransactionParams, "normalizeRecipeInspectTransactionParams"); const recipeDiscoveryEntries = [ { id: "view-contract", api: "near.recipes.viewContract", title: "What does this contract method return?" }, { id: "view-account", api: "near.recipes.viewAccount", title: "What does this account look like on chain?" }, { id: "inspect-transaction", api: "near.tx.transactions", title: "What happened in this transaction?" }, { id: "account-full", api: "near.api.v1.accountFull", title: "What does this account own?" }, { id: "transfers-query", api: "near.transfers.query", title: "What is this account's recent transfer activity?" }, { id: "last-block-final", api: "near.neardata.lastBlockFinal", title: "What block is NEAR on right now?" }, { id: "kv-latest-key", api: "near.fastdata.kv.getLatestKey", title: "What is the latest indexed value for this exact key?" }, { id: "connect-wallet", api: "near.recipes.connect", title: "How do I connect a wallet?" }, { id: "function-call", api: "near.recipes.functionCall", title: "How do I send one function call?" }, { id: "transfer", api: "near.recipes.transfer", title: "How do I transfer NEAR?" }, { id: "sign-message", api: "near.recipes.signMessage", title: "How do I sign a message?" }, { id: "sign-delegate-actions", api: "nearWallet.signDelegateActions", title: "How do I sign delegate actions for gasless transactions?" }, { id: "ft-balance", api: "near.ft.balance", title: "What is this account's FT balance?" }, { id: "ft-metadata", api: "near.ft.metadata", title: "What does this NEP-141 token call itself?" }, { id: "ft-inventory", api: "near.ft.inventory", title: "Which fungible tokens does this account hold?" }, { id: "nft-for-owner", api: "near.nft.forOwner", title: "Which NFTs does this account own on this contract?" }, { id: "nft-inventory", api: "near.nft.inventory", title: "Which NFT contracts does this account hold tokens on?" }, { id: "archival-snapshot", api: "near.queryAccount", title: "What did this account look like at a specific block?" }, { id: "connect-testnet", api: "near.recipes.connect", title: "How do I open a testnet wallet session alongside mainnet?" }, { id: "function-call-testnet", api: "near.recipes.functionCall", title: "How do I send a function call on testnet without losing my mainnet session?" } ]; function listRecipes() { return recipeDiscoveryEntries.map((entry) => ({ ...entry })); } __name(listRecipes, "listRecipes"); async function viewAccountRecipe(input) { const result = await queryAccount(normalizeRecipeViewAccountParams(input)); return result.result; } __name(viewAccountRecipe, "viewAccountRecipe"); async function inspectTransactionRecipe(input) { const { txHash } = normalizeRecipeInspectTransactionParams(input); const result = await tx.transactions({ txHashes: [txHash] }); return result?.transactions?.[0] ?? null; } __name(inspectTransactionRecipe, "inspectTransactionRecipe"); const recipes = { viewContract: /* @__PURE__ */ __name((params) => view(params), "viewContract"), viewAccount: viewAccountRecipe, inspectTransaction: inspectTransactionRecipe, functionCall: /* @__PURE__ */ __name(({ receiverId, methodName, args, argsBase64, gas, deposit, waitUntil, network }) => sendTx({ receiverId, waitUntil, network, actions: [ actions.functionCall({ methodName, args, argsBase64, gas, deposit }) ] }), "functionCall"), transfer: /* @__PURE__ */ __name(({ receiverId, amount, waitUntil, network }) => sendTx({ receiverId, waitUntil, network, actions: [actions.transfer(amount)] }), "transfer"), connect: /* @__PURE__ */ __name((params = {}) => requestSignIn(params), "connect"), signMessage: /* @__PURE__ */ __name((message, options) => signMessage(message, options), "signMessage"), list: listRecipes, toJSON: listRecipes }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { MaxBlockDelayMs, accountId, actions, afterTxSent, api, authStatus, config, event, exp, explain, fastdata, ft, generateTxId, getPublicKeyForContract, localTxHistory, neardata, nft, print, publicKey, queryAccessKey, queryAccount, queryBlock, queryTx, recipes, requestSignIn, selected, sendRpc, sendTx, sendTxToRpc, signMessage, signOut, state, transfers, tx, useWallet, utils, view, withBlockId }); //# sourceMappingURL=near.cjs.map