@anywalletkit/wallet-near 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/{chunk-ZWMEZA5A.js → chunk-5UHDSFWA.js} +10 -3
- package/dist/chunk-5UHDSFWA.js.map +1 -0
- package/dist/history.cjs.map +1 -1
- package/dist/history.js +1 -1
- package/dist/index.cjs +120 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -4
- package/dist/index.d.ts +31 -4
- package/dist/index.js +114 -20
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/chunk-ZWMEZA5A.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -401,6 +401,13 @@ declare function actionKey(a: NearAction): NearActionKey;
|
|
|
401
401
|
declare function isPlainObject(v: unknown): v is Record<string, unknown>;
|
|
402
402
|
/** Function-call args as bytes: raw bytes pass through; plain objects / strings become UTF-8 JSON / UTF-8. Anything else throws. */
|
|
403
403
|
declare function argsBytes(args: Uint8Array | Record<string, unknown> | string): Uint8Array;
|
|
404
|
+
/**
|
|
405
|
+
* The borsh tag of an access-key permission (0 FunctionCall, 1 FullAccess), read from a permission of
|
|
406
|
+
* exactly one known variant: `{ fullAccess: {} }` or `{ functionCall: { receiverId, methodNames, allowance? } }`.
|
|
407
|
+
* Anything else throws, so an empty, misspelled, unknown or doubled variant is never encoded as
|
|
408
|
+
* FullAccess. The encoder, `assertWellFormed` and the description all read this one tag (scan 2026-10-30 F9).
|
|
409
|
+
*/
|
|
410
|
+
declare function accessKeyPermissionTag(permission: unknown): 0 | 1;
|
|
404
411
|
declare function writeAction(w: BorshWriter, a: NearAction): void;
|
|
405
412
|
declare function readAction(r: BorshReader): NearAction;
|
|
406
413
|
/** Borsh bytes of an unsigned transaction. */
|
|
@@ -619,12 +626,19 @@ declare class WalletAccountReadOnlyNear implements IWalletAccountReadOnly {
|
|
|
619
626
|
static hashOf(tx: NearBuiltTransaction): Uint8Array;
|
|
620
627
|
static txHash(tx: NearBuiltTransaction): string;
|
|
621
628
|
}
|
|
622
|
-
|
|
629
|
+
/**
|
|
630
|
+
* The receipt of a `tx` / `send_tx` outcome: status 0 when the transaction or any receipt failed,
|
|
631
|
+
* 1 when it executed (`SuccessValue` / `SuccessReceiptId`), `undefined` while it is not executed
|
|
632
|
+
* yet (no execution status, `NotStarted` / `Started`, or `final_execution_status` NONE / INCLUDED /
|
|
633
|
+
* INCLUDED_FINAL).
|
|
634
|
+
*/
|
|
635
|
+
declare function receiptOf(hash: string, o: RawFinalOutcome): NearReceipt | undefined;
|
|
623
636
|
declare function parseSignature(signature: string): Uint8Array;
|
|
624
637
|
/**
|
|
625
638
|
* An object transaction has exactly the shape the encoder writes, before it is built or signed (also
|
|
626
639
|
* `signBuilt`): every action one known key; a function call's `methodName` a string of the method
|
|
627
|
-
* grammar, `args` bytes, a string or a plain object, `gas` / `deposit` bigints;
|
|
640
|
+
* grammar, `args` bytes, a string or a plain object, `gas` / `deposit` bigints; an AddKey permission
|
|
641
|
+
* exactly one known variant (scan 2026-10-30 F9); every account id and
|
|
628
642
|
* method name well formed. What the policies read is then what gets encoded (scan 2026-10-27 F6, F28).
|
|
629
643
|
*/
|
|
630
644
|
declare function assertWellFormed(tx: Pick<NearBuiltTransaction, 'receiverId' | 'actions'>): void;
|
|
@@ -652,6 +666,15 @@ declare class WalletAccountNear extends WalletAccountReadOnlyNear implements IWa
|
|
|
652
666
|
readonly signerKind: Signer['kind'];
|
|
653
667
|
private _disposed;
|
|
654
668
|
private _readOnly;
|
|
669
|
+
/**
|
|
670
|
+
* Highest nonce this account has broadcast (accepted, or maybe sent). The access key is read at
|
|
671
|
+
* `final`, which lags the block that holds our last transaction, so a second send right after
|
|
672
|
+
* the first would sign the same nonce and be refused. A filled-in nonce is never below it + 1;
|
|
673
|
+
* NEAR only needs nonces to increase, so a gap left by a transaction that never landed is harmless.
|
|
674
|
+
*/
|
|
675
|
+
private _nonceFloor;
|
|
676
|
+
/** Tail of this account's send queue: prepare → sign → broadcast runs one send at a time. */
|
|
677
|
+
private _sendTail;
|
|
655
678
|
constructor(signer: Signer, publicKey: Uint8Array, path: string, config?: NearConfig, accountId?: string);
|
|
656
679
|
/** Wrap a raw derived key (takes ownership; zeroized on dispose). */
|
|
657
680
|
static fromPrivateKey(privateKey: Uint8Array, publicKey: Uint8Array, path: string, config?: NearConfig, accountId?: string): WalletAccountNear;
|
|
@@ -671,7 +694,11 @@ declare class WalletAccountNear extends WalletAccountReadOnlyNear implements IWa
|
|
|
671
694
|
sign(message: string | Uint8Array): Promise<string>;
|
|
672
695
|
/** NEP-413 off-chain message (what NEAR Intents and dApps ask wallets to sign). */
|
|
673
696
|
signNep413(payload: Nep413Payload): Promise<Nep413Signed>;
|
|
674
|
-
/**
|
|
697
|
+
/**
|
|
698
|
+
* Sign a fully built transaction. It gets the same hard checks as `signTransaction` (this
|
|
699
|
+
* account's signer and key, no dangerous action unless `allowDangerousActions`, gas limit) but
|
|
700
|
+
* no node round-trip: no preflight and no fee check.
|
|
701
|
+
*/
|
|
675
702
|
signBuilt(tx: NearBuiltTransaction): Promise<NearSignedTransaction>;
|
|
676
703
|
/** Build → hard checks → preflight → fee cap. Shared by sign / send / transfer. */
|
|
677
704
|
private prepare;
|
|
@@ -719,4 +746,4 @@ declare class WalletManagerNear extends WalletManager<WalletAccountNear, NearCon
|
|
|
719
746
|
getFeeRates(): Promise<FeeRates>;
|
|
720
747
|
}
|
|
721
748
|
|
|
722
|
-
export { ACTION_TAG, BorshReader, BorshWriter, BroadcastUnknownError, CAIP2, DANGEROUS_ACTIONS, type DescribeContext, FT_TRANSFER_GAS, IMPLICIT_ACCOUNT_MIN_DEPOSIT, MAX_GAS, MessageIsTransactionError, NEAR_BASE_PATH, NEP413_PREFIX, type NearAccessKey, type NearAccountView, type NearAction, type NearAddKeyAction, type NearBuiltTransaction, type NearConfig, type NearCreateAccountAction, type NearDelegateAction, type NearDeleteAccountAction, type NearDeleteKeyAction, type NearDeployContractAction, type NearDeployGlobalContractAction, type NearFeeEstimate, type NearFetch, type NearFunctionCallAction, type NearProvider, type NearPublicKey, type NearQuote, type NearReceipt, NearRpc, NearRpcError, type NearSignature, type NearSignedDelegateAction, type NearSignedTransaction, type NearSimulation, type NearStakeAction, type NearTransaction, type NearTransferAction, type NearTransferOptions, type NearTransferResult, type NearTxDescription, type NearTxKind, type NearTxWarning, type NearTxWarningCode, type NearUseGlobalContractAction, type Nep413Payload, type Nep413Signed, ONE_YOCTO, type RawAccessKeyView, type RawAccountView, type RawFinalOutcome, STORAGE_DEPOSIT_GAS, STORAGE_PRICE_PER_BYTE, SimulationError, TGAS, type UnsafeTransactionCode, UnsafeTransactionError, WalletAccountNear, WalletAccountReadOnlyNear, WalletManagerNear, YOCTO, actionKey, argsBytes, assertWellFormed, base58ToBytes, bytesToBase58, createClient, decodeAnyTransaction, decodeSignedTransaction, decodeTransaction, WalletManagerNear as default, describeTransaction, ed25519Key, encodeSignedTransaction, encodeTransaction, failureOf, fromBase64, implicitAccountId, isDangerous, isImplicitAccountId, isPlainObject, isValidAccountId, nep413Bytes, nep413Hash, outcomeFailed, parsePublicKey, parseSignature, publicKeyOfImplicit, publicKeyToString, readAction, readPublicKey, readSignature, receiptOf, toBase64, writeAction, writePublicKey, writeSignature };
|
|
749
|
+
export { ACTION_TAG, BorshReader, BorshWriter, BroadcastUnknownError, CAIP2, DANGEROUS_ACTIONS, type DescribeContext, FT_TRANSFER_GAS, IMPLICIT_ACCOUNT_MIN_DEPOSIT, MAX_GAS, MessageIsTransactionError, NEAR_BASE_PATH, NEP413_PREFIX, type NearAccessKey, type NearAccountView, type NearAction, type NearAddKeyAction, type NearBuiltTransaction, type NearConfig, type NearCreateAccountAction, type NearDelegateAction, type NearDeleteAccountAction, type NearDeleteKeyAction, type NearDeployContractAction, type NearDeployGlobalContractAction, type NearFeeEstimate, type NearFetch, type NearFunctionCallAction, type NearProvider, type NearPublicKey, type NearQuote, type NearReceipt, NearRpc, NearRpcError, type NearSignature, type NearSignedDelegateAction, type NearSignedTransaction, type NearSimulation, type NearStakeAction, type NearTransaction, type NearTransferAction, type NearTransferOptions, type NearTransferResult, type NearTxDescription, type NearTxKind, type NearTxWarning, type NearTxWarningCode, type NearUseGlobalContractAction, type Nep413Payload, type Nep413Signed, ONE_YOCTO, type RawAccessKeyView, type RawAccountView, type RawFinalOutcome, STORAGE_DEPOSIT_GAS, STORAGE_PRICE_PER_BYTE, SimulationError, TGAS, type UnsafeTransactionCode, UnsafeTransactionError, WalletAccountNear, WalletAccountReadOnlyNear, WalletManagerNear, YOCTO, accessKeyPermissionTag, actionKey, argsBytes, assertWellFormed, base58ToBytes, bytesToBase58, createClient, decodeAnyTransaction, decodeSignedTransaction, decodeTransaction, WalletManagerNear as default, describeTransaction, ed25519Key, encodeSignedTransaction, encodeTransaction, failureOf, fromBase64, implicitAccountId, isDangerous, isImplicitAccountId, isPlainObject, isValidAccountId, nep413Bytes, nep413Hash, outcomeFailed, parsePublicKey, parseSignature, publicKeyOfImplicit, publicKeyToString, readAction, readPublicKey, readSignature, receiptOf, toBase64, writeAction, writePublicKey, writeSignature };
|
package/dist/index.d.ts
CHANGED
|
@@ -401,6 +401,13 @@ declare function actionKey(a: NearAction): NearActionKey;
|
|
|
401
401
|
declare function isPlainObject(v: unknown): v is Record<string, unknown>;
|
|
402
402
|
/** Function-call args as bytes: raw bytes pass through; plain objects / strings become UTF-8 JSON / UTF-8. Anything else throws. */
|
|
403
403
|
declare function argsBytes(args: Uint8Array | Record<string, unknown> | string): Uint8Array;
|
|
404
|
+
/**
|
|
405
|
+
* The borsh tag of an access-key permission (0 FunctionCall, 1 FullAccess), read from a permission of
|
|
406
|
+
* exactly one known variant: `{ fullAccess: {} }` or `{ functionCall: { receiverId, methodNames, allowance? } }`.
|
|
407
|
+
* Anything else throws, so an empty, misspelled, unknown or doubled variant is never encoded as
|
|
408
|
+
* FullAccess. The encoder, `assertWellFormed` and the description all read this one tag (scan 2026-10-30 F9).
|
|
409
|
+
*/
|
|
410
|
+
declare function accessKeyPermissionTag(permission: unknown): 0 | 1;
|
|
404
411
|
declare function writeAction(w: BorshWriter, a: NearAction): void;
|
|
405
412
|
declare function readAction(r: BorshReader): NearAction;
|
|
406
413
|
/** Borsh bytes of an unsigned transaction. */
|
|
@@ -619,12 +626,19 @@ declare class WalletAccountReadOnlyNear implements IWalletAccountReadOnly {
|
|
|
619
626
|
static hashOf(tx: NearBuiltTransaction): Uint8Array;
|
|
620
627
|
static txHash(tx: NearBuiltTransaction): string;
|
|
621
628
|
}
|
|
622
|
-
|
|
629
|
+
/**
|
|
630
|
+
* The receipt of a `tx` / `send_tx` outcome: status 0 when the transaction or any receipt failed,
|
|
631
|
+
* 1 when it executed (`SuccessValue` / `SuccessReceiptId`), `undefined` while it is not executed
|
|
632
|
+
* yet (no execution status, `NotStarted` / `Started`, or `final_execution_status` NONE / INCLUDED /
|
|
633
|
+
* INCLUDED_FINAL).
|
|
634
|
+
*/
|
|
635
|
+
declare function receiptOf(hash: string, o: RawFinalOutcome): NearReceipt | undefined;
|
|
623
636
|
declare function parseSignature(signature: string): Uint8Array;
|
|
624
637
|
/**
|
|
625
638
|
* An object transaction has exactly the shape the encoder writes, before it is built or signed (also
|
|
626
639
|
* `signBuilt`): every action one known key; a function call's `methodName` a string of the method
|
|
627
|
-
* grammar, `args` bytes, a string or a plain object, `gas` / `deposit` bigints;
|
|
640
|
+
* grammar, `args` bytes, a string or a plain object, `gas` / `deposit` bigints; an AddKey permission
|
|
641
|
+
* exactly one known variant (scan 2026-10-30 F9); every account id and
|
|
628
642
|
* method name well formed. What the policies read is then what gets encoded (scan 2026-10-27 F6, F28).
|
|
629
643
|
*/
|
|
630
644
|
declare function assertWellFormed(tx: Pick<NearBuiltTransaction, 'receiverId' | 'actions'>): void;
|
|
@@ -652,6 +666,15 @@ declare class WalletAccountNear extends WalletAccountReadOnlyNear implements IWa
|
|
|
652
666
|
readonly signerKind: Signer['kind'];
|
|
653
667
|
private _disposed;
|
|
654
668
|
private _readOnly;
|
|
669
|
+
/**
|
|
670
|
+
* Highest nonce this account has broadcast (accepted, or maybe sent). The access key is read at
|
|
671
|
+
* `final`, which lags the block that holds our last transaction, so a second send right after
|
|
672
|
+
* the first would sign the same nonce and be refused. A filled-in nonce is never below it + 1;
|
|
673
|
+
* NEAR only needs nonces to increase, so a gap left by a transaction that never landed is harmless.
|
|
674
|
+
*/
|
|
675
|
+
private _nonceFloor;
|
|
676
|
+
/** Tail of this account's send queue: prepare → sign → broadcast runs one send at a time. */
|
|
677
|
+
private _sendTail;
|
|
655
678
|
constructor(signer: Signer, publicKey: Uint8Array, path: string, config?: NearConfig, accountId?: string);
|
|
656
679
|
/** Wrap a raw derived key (takes ownership; zeroized on dispose). */
|
|
657
680
|
static fromPrivateKey(privateKey: Uint8Array, publicKey: Uint8Array, path: string, config?: NearConfig, accountId?: string): WalletAccountNear;
|
|
@@ -671,7 +694,11 @@ declare class WalletAccountNear extends WalletAccountReadOnlyNear implements IWa
|
|
|
671
694
|
sign(message: string | Uint8Array): Promise<string>;
|
|
672
695
|
/** NEP-413 off-chain message (what NEAR Intents and dApps ask wallets to sign). */
|
|
673
696
|
signNep413(payload: Nep413Payload): Promise<Nep413Signed>;
|
|
674
|
-
/**
|
|
697
|
+
/**
|
|
698
|
+
* Sign a fully built transaction. It gets the same hard checks as `signTransaction` (this
|
|
699
|
+
* account's signer and key, no dangerous action unless `allowDangerousActions`, gas limit) but
|
|
700
|
+
* no node round-trip: no preflight and no fee check.
|
|
701
|
+
*/
|
|
675
702
|
signBuilt(tx: NearBuiltTransaction): Promise<NearSignedTransaction>;
|
|
676
703
|
/** Build → hard checks → preflight → fee cap. Shared by sign / send / transfer. */
|
|
677
704
|
private prepare;
|
|
@@ -719,4 +746,4 @@ declare class WalletManagerNear extends WalletManager<WalletAccountNear, NearCon
|
|
|
719
746
|
getFeeRates(): Promise<FeeRates>;
|
|
720
747
|
}
|
|
721
748
|
|
|
722
|
-
export { ACTION_TAG, BorshReader, BorshWriter, BroadcastUnknownError, CAIP2, DANGEROUS_ACTIONS, type DescribeContext, FT_TRANSFER_GAS, IMPLICIT_ACCOUNT_MIN_DEPOSIT, MAX_GAS, MessageIsTransactionError, NEAR_BASE_PATH, NEP413_PREFIX, type NearAccessKey, type NearAccountView, type NearAction, type NearAddKeyAction, type NearBuiltTransaction, type NearConfig, type NearCreateAccountAction, type NearDelegateAction, type NearDeleteAccountAction, type NearDeleteKeyAction, type NearDeployContractAction, type NearDeployGlobalContractAction, type NearFeeEstimate, type NearFetch, type NearFunctionCallAction, type NearProvider, type NearPublicKey, type NearQuote, type NearReceipt, NearRpc, NearRpcError, type NearSignature, type NearSignedDelegateAction, type NearSignedTransaction, type NearSimulation, type NearStakeAction, type NearTransaction, type NearTransferAction, type NearTransferOptions, type NearTransferResult, type NearTxDescription, type NearTxKind, type NearTxWarning, type NearTxWarningCode, type NearUseGlobalContractAction, type Nep413Payload, type Nep413Signed, ONE_YOCTO, type RawAccessKeyView, type RawAccountView, type RawFinalOutcome, STORAGE_DEPOSIT_GAS, STORAGE_PRICE_PER_BYTE, SimulationError, TGAS, type UnsafeTransactionCode, UnsafeTransactionError, WalletAccountNear, WalletAccountReadOnlyNear, WalletManagerNear, YOCTO, actionKey, argsBytes, assertWellFormed, base58ToBytes, bytesToBase58, createClient, decodeAnyTransaction, decodeSignedTransaction, decodeTransaction, WalletManagerNear as default, describeTransaction, ed25519Key, encodeSignedTransaction, encodeTransaction, failureOf, fromBase64, implicitAccountId, isDangerous, isImplicitAccountId, isPlainObject, isValidAccountId, nep413Bytes, nep413Hash, outcomeFailed, parsePublicKey, parseSignature, publicKeyOfImplicit, publicKeyToString, readAction, readPublicKey, readSignature, receiptOf, toBase64, writeAction, writePublicKey, writeSignature };
|
|
749
|
+
export { ACTION_TAG, BorshReader, BorshWriter, BroadcastUnknownError, CAIP2, DANGEROUS_ACTIONS, type DescribeContext, FT_TRANSFER_GAS, IMPLICIT_ACCOUNT_MIN_DEPOSIT, MAX_GAS, MessageIsTransactionError, NEAR_BASE_PATH, NEP413_PREFIX, type NearAccessKey, type NearAccountView, type NearAction, type NearAddKeyAction, type NearBuiltTransaction, type NearConfig, type NearCreateAccountAction, type NearDelegateAction, type NearDeleteAccountAction, type NearDeleteKeyAction, type NearDeployContractAction, type NearDeployGlobalContractAction, type NearFeeEstimate, type NearFetch, type NearFunctionCallAction, type NearProvider, type NearPublicKey, type NearQuote, type NearReceipt, NearRpc, NearRpcError, type NearSignature, type NearSignedDelegateAction, type NearSignedTransaction, type NearSimulation, type NearStakeAction, type NearTransaction, type NearTransferAction, type NearTransferOptions, type NearTransferResult, type NearTxDescription, type NearTxKind, type NearTxWarning, type NearTxWarningCode, type NearUseGlobalContractAction, type Nep413Payload, type Nep413Signed, ONE_YOCTO, type RawAccessKeyView, type RawAccountView, type RawFinalOutcome, STORAGE_DEPOSIT_GAS, STORAGE_PRICE_PER_BYTE, SimulationError, TGAS, type UnsafeTransactionCode, UnsafeTransactionError, WalletAccountNear, WalletAccountReadOnlyNear, WalletManagerNear, YOCTO, accessKeyPermissionTag, actionKey, argsBytes, assertWellFormed, base58ToBytes, bytesToBase58, createClient, decodeAnyTransaction, decodeSignedTransaction, decodeTransaction, WalletManagerNear as default, describeTransaction, ed25519Key, encodeSignedTransaction, encodeTransaction, failureOf, fromBase64, implicitAccountId, isDangerous, isImplicitAccountId, isPlainObject, isValidAccountId, nep413Bytes, nep413Hash, outcomeFailed, parsePublicKey, parseSignature, publicKeyOfImplicit, publicKeyToString, readAction, readPublicKey, readSignature, receiptOf, toBase64, writeAction, writePublicKey, writeSignature };
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
encodeCursor,
|
|
23
23
|
failureOf,
|
|
24
24
|
fromBase64,
|
|
25
|
-
|
|
25
|
+
isDefinitiveBroadcast,
|
|
26
26
|
mapNearblocksGroup,
|
|
27
27
|
mapNearblocksTxn,
|
|
28
28
|
mapRpcTxStatus,
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
outcomeFailed,
|
|
31
31
|
parseJsonPreservingBigInts,
|
|
32
32
|
toBase64
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-5UHDSFWA.js";
|
|
34
34
|
|
|
35
35
|
// src/address.ts
|
|
36
36
|
import { base58 } from "@scure/base";
|
|
@@ -239,17 +239,34 @@ function argsBytes(args) {
|
|
|
239
239
|
if (!isPlainObject(args)) throw new TypeError("function-call args must be bytes, a string or a plain object");
|
|
240
240
|
return utf8.encode(JSON.stringify(args));
|
|
241
241
|
}
|
|
242
|
+
var FUNCTION_CALL_PERMISSION_KEYS = /* @__PURE__ */ new Set(["allowance", "receiverId", "methodNames"]);
|
|
243
|
+
function accessKeyPermissionTag(permission) {
|
|
244
|
+
const keys = isPlainObject(permission) ? Object.keys(permission) : [];
|
|
245
|
+
if (keys.length !== 1) throw new TypeError(`an access-key permission must have exactly one variant, fullAccess or functionCall (has: ${keys.join(", ") || "none"})`);
|
|
246
|
+
const variant = permission[keys[0]];
|
|
247
|
+
if (keys[0] === "fullAccess") {
|
|
248
|
+
if (!isPlainObject(variant)) throw new TypeError("fullAccess must be a plain object");
|
|
249
|
+
return 1;
|
|
250
|
+
}
|
|
251
|
+
if (keys[0] === "functionCall") {
|
|
252
|
+
if (!isPlainObject(variant) || Object.keys(variant).some((k) => !FUNCTION_CALL_PERMISSION_KEYS.has(k))) throw new TypeError("functionCall must be a plain { receiverId, methodNames, allowance? } object");
|
|
253
|
+
if (typeof variant.receiverId !== "string") throw new TypeError("functionCall.receiverId must be a string");
|
|
254
|
+
if (!Array.isArray(variant.methodNames) || !variant.methodNames.every((m) => typeof m === "string")) throw new TypeError("functionCall.methodNames must be an array of strings");
|
|
255
|
+
if (variant.allowance !== void 0 && typeof variant.allowance !== "bigint") throw new TypeError("functionCall.allowance must be a bigint or absent");
|
|
256
|
+
return 0;
|
|
257
|
+
}
|
|
258
|
+
throw new TypeError(`unknown access-key permission ${JSON.stringify(keys[0])}`);
|
|
259
|
+
}
|
|
242
260
|
function writeAccessKey(w, k) {
|
|
243
261
|
w.u64(k.nonce);
|
|
244
|
-
|
|
262
|
+
const tag = accessKeyPermissionTag(k.permission);
|
|
263
|
+
w.u8(tag);
|
|
264
|
+
if (tag === 0) {
|
|
245
265
|
const p = k.permission.functionCall;
|
|
246
|
-
w.u8(0);
|
|
247
266
|
w.option(p.allowance, (a) => w.u128(a));
|
|
248
267
|
w.string(p.receiverId);
|
|
249
268
|
w.u32(p.methodNames.length);
|
|
250
269
|
for (const m of p.methodNames) w.string(m);
|
|
251
|
-
} else {
|
|
252
|
-
w.u8(1);
|
|
253
270
|
}
|
|
254
271
|
}
|
|
255
272
|
function readAccessKey(r) {
|
|
@@ -489,8 +506,15 @@ function describeTransaction(tx, ctx = {}) {
|
|
|
489
506
|
if (DANGEROUS_ACTIONS.has(key)) {
|
|
490
507
|
dangerous ??= KIND_OF_DANGEROUS[key];
|
|
491
508
|
warnings.push({ code: "dangerous-action", message: `${key} changes the account, its keys or its code.` });
|
|
492
|
-
if (key === "addKey"
|
|
493
|
-
|
|
509
|
+
if (key === "addKey") {
|
|
510
|
+
let tag;
|
|
511
|
+
try {
|
|
512
|
+
tag = accessKeyPermissionTag(a.addKey?.accessKey?.permission);
|
|
513
|
+
} catch {
|
|
514
|
+
tag = void 0;
|
|
515
|
+
}
|
|
516
|
+
if (tag === 1) warnings.push({ code: "full-access-key", message: "Adds a FULL ACCESS key: whoever holds it owns the account." });
|
|
517
|
+
else if (tag === void 0) warnings.push({ code: "dangerous-action", message: "Malformed access-key permission: neither fullAccess nor functionCall. The wallet refuses to sign it." });
|
|
494
518
|
}
|
|
495
519
|
continue;
|
|
496
520
|
}
|
|
@@ -838,8 +862,7 @@ var WalletAccountReadOnlyNear = class _WalletAccountReadOnlyNear {
|
|
|
838
862
|
/** Status of one of this account's transactions (the `tx` RPC needs the sender). */
|
|
839
863
|
async getTransactionReceipt(hash) {
|
|
840
864
|
const o = await this.requireRpc("fetch transaction receipts").txStatus(hash, this.address);
|
|
841
|
-
|
|
842
|
-
return receiptOf(hash, o);
|
|
865
|
+
return o ? receiptOf(hash, o) : void 0;
|
|
843
866
|
}
|
|
844
867
|
/** Verify an `ed25519:<base58>` (or bare base58 / hex) signature produced by `sign`. */
|
|
845
868
|
async verify(message, signature) {
|
|
@@ -860,8 +883,10 @@ var WalletAccountReadOnlyNear = class _WalletAccountReadOnlyNear {
|
|
|
860
883
|
};
|
|
861
884
|
function receiptOf(hash, o) {
|
|
862
885
|
const failure = outcomeFailed(o);
|
|
863
|
-
|
|
864
|
-
|
|
886
|
+
if (failure) return { hash, status: 0, failure, raw: { ...o } };
|
|
887
|
+
if (o.final_execution_status !== void 0 && /^(?:NONE|INCLUDED|INCLUDED_FINAL)$/.test(o.final_execution_status)) return void 0;
|
|
888
|
+
const executed = typeof o.status === "object" && o.status !== null && ("SuccessValue" in o.status || "SuccessReceiptId" in o.status);
|
|
889
|
+
return executed ? { hash, status: 1, raw: { ...o } } : void 0;
|
|
865
890
|
}
|
|
866
891
|
function parseSignature(signature) {
|
|
867
892
|
const s = signature.startsWith("ed25519:") ? signature.slice("ed25519:".length) : signature;
|
|
@@ -888,6 +913,15 @@ function assertShape(actions, depth = 0) {
|
|
|
888
913
|
if (!(f.args instanceof Uint8Array) && typeof f.args !== "string" && !isPlainObject(f.args)) throw new UnsafeTransactionError("malformed-action", "Function-call args must be bytes, a string or a plain object.");
|
|
889
914
|
if (f.gas !== void 0 && typeof f.gas !== "bigint" || f.deposit !== void 0 && typeof f.deposit !== "bigint") throw new UnsafeTransactionError("malformed-action", "Function-call gas and deposit must be bigints.");
|
|
890
915
|
}
|
|
916
|
+
if ("addKey" in a) {
|
|
917
|
+
const k = a.addKey;
|
|
918
|
+
if (!isPlainObject(k) || !isPlainObject(k.accessKey)) throw new UnsafeTransactionError("malformed-action", "addKey must carry an accessKey object.");
|
|
919
|
+
try {
|
|
920
|
+
accessKeyPermissionTag(k.accessKey.permission);
|
|
921
|
+
} catch (e) {
|
|
922
|
+
throw new UnsafeTransactionError("malformed-action", `AddKey: ${e.message}.`);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
891
925
|
if ("signedDelegate" in a && depth === 0) assertShape(a.signedDelegate.delegateAction.actions, depth + 1);
|
|
892
926
|
}
|
|
893
927
|
}
|
|
@@ -960,6 +994,15 @@ var WalletAccountNear = class _WalletAccountNear extends WalletAccountReadOnlyNe
|
|
|
960
994
|
signerKind;
|
|
961
995
|
_disposed = false;
|
|
962
996
|
_readOnly;
|
|
997
|
+
/**
|
|
998
|
+
* Highest nonce this account has broadcast (accepted, or maybe sent). The access key is read at
|
|
999
|
+
* `final`, which lags the block that holds our last transaction, so a second send right after
|
|
1000
|
+
* the first would sign the same nonce and be refused. A filled-in nonce is never below it + 1;
|
|
1001
|
+
* NEAR only needs nonces to increase, so a gap left by a transaction that never landed is harmless.
|
|
1002
|
+
*/
|
|
1003
|
+
_nonceFloor;
|
|
1004
|
+
/** Tail of this account's send queue: prepare → sign → broadcast runs one send at a time. */
|
|
1005
|
+
_sendTail = Promise.resolve();
|
|
963
1006
|
constructor(signer, publicKey, path, config = {}, accountId) {
|
|
964
1007
|
super(accountId ?? implicitAccountId(publicKey), config, ed25519Key(publicKey));
|
|
965
1008
|
this.#signer = requireCurve(signer, "ed25519");
|
|
@@ -1004,15 +1047,44 @@ var WalletAccountNear = class _WalletAccountNear extends WalletAccountReadOnlyNe
|
|
|
1004
1047
|
const sig = await this.#signBytes(nep413Hash(payload), "near-nep413");
|
|
1005
1048
|
return { signature: toBase64(sig), publicKey: publicKeyToString(this.publicKey), accountId: this.address };
|
|
1006
1049
|
}
|
|
1007
|
-
/**
|
|
1050
|
+
/**
|
|
1051
|
+
* Sign a fully built transaction. It gets the same hard checks as `signTransaction` (this
|
|
1052
|
+
* account's signer and key, no dangerous action unless `allowDangerousActions`, gas limit) but
|
|
1053
|
+
* no node round-trip: no preflight and no fee check.
|
|
1054
|
+
*/
|
|
1008
1055
|
async signBuilt(tx) {
|
|
1056
|
+
const own = this.#ownCopy(tx);
|
|
1057
|
+
this.assertSafe(own);
|
|
1058
|
+
return this.#signChecked(own);
|
|
1059
|
+
}
|
|
1060
|
+
/**
|
|
1061
|
+
* A plain copy of `tx`, decoded from its borsh bytes: the object the checks read is the one that
|
|
1062
|
+
* gets hashed and signed, whatever the caller does with its own object (a getter, or an array
|
|
1063
|
+
* changed while a node call is awaited).
|
|
1064
|
+
*/
|
|
1065
|
+
#ownCopy(tx) {
|
|
1066
|
+
let copy;
|
|
1067
|
+
try {
|
|
1068
|
+
copy = decodeTransaction(encodeTransaction(tx));
|
|
1069
|
+
} catch (e) {
|
|
1070
|
+
this.assertSafe(tx);
|
|
1071
|
+
throw new UnsafeTransactionError("non-canonical", `Not an encodable NEAR transaction: ${e.message}`);
|
|
1072
|
+
}
|
|
1073
|
+
return copy;
|
|
1074
|
+
}
|
|
1075
|
+
/** Sign a transaction that has already been through `assertSafe`. */
|
|
1076
|
+
async #signChecked(tx) {
|
|
1009
1077
|
assertWellFormed(tx);
|
|
1010
1078
|
const sig = await this.#signBytes(WalletAccountReadOnlyNear.hashOf(tx), "near-tx");
|
|
1011
1079
|
return { transaction: tx, signature: { keyType: "ed25519", data: sig } };
|
|
1012
1080
|
}
|
|
1013
1081
|
/** Build → hard checks → preflight → fee cap. Shared by sign / send / transfer. */
|
|
1014
1082
|
async prepare(tx, maxFee, op) {
|
|
1015
|
-
|
|
1083
|
+
let built = await this.buildTransaction(tx);
|
|
1084
|
+
if (typeof tx !== "string" && tx.nonce === void 0 && this._nonceFloor !== void 0 && built.nonce <= this._nonceFloor) {
|
|
1085
|
+
built = { ...built, nonce: this._nonceFloor + 1n };
|
|
1086
|
+
}
|
|
1087
|
+
built = this.#ownCopy(built);
|
|
1016
1088
|
this.assertSafe(built);
|
|
1017
1089
|
const estimate = await this.estimate(built);
|
|
1018
1090
|
this.assertSafe(built, estimate.fee);
|
|
@@ -1028,18 +1100,24 @@ var WalletAccountNear = class _WalletAccountNear extends WalletAccountReadOnlyNe
|
|
|
1028
1100
|
this.key();
|
|
1029
1101
|
this.requireRpc("sign transactions");
|
|
1030
1102
|
const { built } = await this.prepare(tx, feeLimit(this._config.transactionMaxFee, options), "transaction");
|
|
1031
|
-
return toBase64(encodeSignedTransaction(await this
|
|
1103
|
+
return toBase64(encodeSignedTransaction(await this.#signChecked(built)));
|
|
1032
1104
|
}
|
|
1033
1105
|
async broadcast(signed) {
|
|
1034
1106
|
const hash = WalletAccountReadOnlyNear.txHash(signed.transaction);
|
|
1035
1107
|
const rpc = this.requireRpc("broadcast");
|
|
1108
|
+
const used = () => {
|
|
1109
|
+
const n = signed.transaction.nonce;
|
|
1110
|
+
if (this._nonceFloor === void 0 || n > this._nonceFloor) this._nonceFloor = n;
|
|
1111
|
+
};
|
|
1036
1112
|
let outcome;
|
|
1037
1113
|
try {
|
|
1038
1114
|
outcome = await rpc.sendTx(toBase64(encodeSignedTransaction(signed)));
|
|
1039
1115
|
} catch (e) {
|
|
1040
|
-
if (
|
|
1116
|
+
if (isDefinitiveBroadcast(e)) throw e;
|
|
1117
|
+
used();
|
|
1041
1118
|
throw new BroadcastUnknownError(hash, e);
|
|
1042
1119
|
}
|
|
1120
|
+
used();
|
|
1043
1121
|
const failure = outcomeFailed(outcome);
|
|
1044
1122
|
if (failure) throw new Error(`Transaction ${hash} failed on chain: ${failure}`);
|
|
1045
1123
|
return outcome.transaction?.hash ?? hash;
|
|
@@ -1048,20 +1126,35 @@ var WalletAccountNear = class _WalletAccountNear extends WalletAccountReadOnlyNe
|
|
|
1048
1126
|
* Sign and broadcast. Accepts a transaction, or base64 borsh of an unsigned /
|
|
1049
1127
|
* already-signed transaction (a signed one is checked, not re-signed).
|
|
1050
1128
|
*/
|
|
1051
|
-
|
|
1129
|
+
sendTransaction(tx, options = {}) {
|
|
1130
|
+
return this.#serial(() => this.#sendTransactionNow(tx, options));
|
|
1131
|
+
}
|
|
1132
|
+
async #sendTransactionNow(tx, options) {
|
|
1052
1133
|
this.key();
|
|
1053
1134
|
this.requireRpc("send transactions");
|
|
1054
1135
|
const presigned = typeof tx === "string" ? decodeSigned(tx) : void 0;
|
|
1055
1136
|
const { built, estimate } = await this.prepare(tx, feeLimit(this._config.transactionMaxFee, options), "transaction");
|
|
1056
|
-
const signed = presigned ?? await this
|
|
1137
|
+
const signed = presigned ?? await this.#signChecked(built);
|
|
1057
1138
|
return { hash: await this.broadcast(signed), fee: estimate.fee, estimate };
|
|
1058
1139
|
}
|
|
1059
1140
|
/** Native NEAR (no `token`) or NEP-141 `ft_transfer` (with `storage_deposit` when the recipient needs it). */
|
|
1060
|
-
|
|
1141
|
+
transfer(o, writeOptions = {}) {
|
|
1142
|
+
return this.#serial(() => this.#transferNow(o, writeOptions));
|
|
1143
|
+
}
|
|
1144
|
+
async #transferNow(o, writeOptions) {
|
|
1061
1145
|
this.key();
|
|
1062
1146
|
this.requireRpc("transfer tokens");
|
|
1063
1147
|
const { built, estimate } = await this.prepare(await this.transferActions(o), feeLimit(this._config.transferMaxFee, writeOptions), "transfer");
|
|
1064
|
-
return { hash: await this.broadcast(await this
|
|
1148
|
+
return { hash: await this.broadcast(await this.#signChecked(built)), fee: estimate.fee, estimate };
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* One send at a time per account: two sends started together would read the same access-key
|
|
1152
|
+
* nonce before either is broadcast. A failed send does not block the next.
|
|
1153
|
+
*/
|
|
1154
|
+
#serial(run) {
|
|
1155
|
+
const next = this._sendTail.then(run);
|
|
1156
|
+
this._sendTail = next.then(() => void 0, () => void 0);
|
|
1157
|
+
return next;
|
|
1065
1158
|
}
|
|
1066
1159
|
/** The same account as a {@link WalletAccountReadOnlyNear}. */
|
|
1067
1160
|
toReadOnlyAccount() {
|
|
@@ -1159,6 +1252,7 @@ export {
|
|
|
1159
1252
|
WalletAccountReadOnlyNear,
|
|
1160
1253
|
WalletManagerNear,
|
|
1161
1254
|
YOCTO,
|
|
1255
|
+
accessKeyPermissionTag,
|
|
1162
1256
|
actionKey,
|
|
1163
1257
|
argsBytes,
|
|
1164
1258
|
assertWellFormed,
|