@anywalletkit/wallet-near 0.3.1 → 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 +80 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -2
- package/dist/index.d.ts +21 -2
- package/dist/index.js +74 -14
- 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
|
@@ -626,7 +626,13 @@ declare class WalletAccountReadOnlyNear implements IWalletAccountReadOnly {
|
|
|
626
626
|
static hashOf(tx: NearBuiltTransaction): Uint8Array;
|
|
627
627
|
static txHash(tx: NearBuiltTransaction): string;
|
|
628
628
|
}
|
|
629
|
-
|
|
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;
|
|
630
636
|
declare function parseSignature(signature: string): Uint8Array;
|
|
631
637
|
/**
|
|
632
638
|
* An object transaction has exactly the shape the encoder writes, before it is built or signed (also
|
|
@@ -660,6 +666,15 @@ declare class WalletAccountNear extends WalletAccountReadOnlyNear implements IWa
|
|
|
660
666
|
readonly signerKind: Signer['kind'];
|
|
661
667
|
private _disposed;
|
|
662
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;
|
|
663
678
|
constructor(signer: Signer, publicKey: Uint8Array, path: string, config?: NearConfig, accountId?: string);
|
|
664
679
|
/** Wrap a raw derived key (takes ownership; zeroized on dispose). */
|
|
665
680
|
static fromPrivateKey(privateKey: Uint8Array, publicKey: Uint8Array, path: string, config?: NearConfig, accountId?: string): WalletAccountNear;
|
|
@@ -679,7 +694,11 @@ declare class WalletAccountNear extends WalletAccountReadOnlyNear implements IWa
|
|
|
679
694
|
sign(message: string | Uint8Array): Promise<string>;
|
|
680
695
|
/** NEP-413 off-chain message (what NEAR Intents and dApps ask wallets to sign). */
|
|
681
696
|
signNep413(payload: Nep413Payload): Promise<Nep413Signed>;
|
|
682
|
-
/**
|
|
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
|
+
*/
|
|
683
702
|
signBuilt(tx: NearBuiltTransaction): Promise<NearSignedTransaction>;
|
|
684
703
|
/** Build → hard checks → preflight → fee cap. Shared by sign / send / transfer. */
|
|
685
704
|
private prepare;
|
package/dist/index.d.ts
CHANGED
|
@@ -626,7 +626,13 @@ declare class WalletAccountReadOnlyNear implements IWalletAccountReadOnly {
|
|
|
626
626
|
static hashOf(tx: NearBuiltTransaction): Uint8Array;
|
|
627
627
|
static txHash(tx: NearBuiltTransaction): string;
|
|
628
628
|
}
|
|
629
|
-
|
|
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;
|
|
630
636
|
declare function parseSignature(signature: string): Uint8Array;
|
|
631
637
|
/**
|
|
632
638
|
* An object transaction has exactly the shape the encoder writes, before it is built or signed (also
|
|
@@ -660,6 +666,15 @@ declare class WalletAccountNear extends WalletAccountReadOnlyNear implements IWa
|
|
|
660
666
|
readonly signerKind: Signer['kind'];
|
|
661
667
|
private _disposed;
|
|
662
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;
|
|
663
678
|
constructor(signer: Signer, publicKey: Uint8Array, path: string, config?: NearConfig, accountId?: string);
|
|
664
679
|
/** Wrap a raw derived key (takes ownership; zeroized on dispose). */
|
|
665
680
|
static fromPrivateKey(privateKey: Uint8Array, publicKey: Uint8Array, path: string, config?: NearConfig, accountId?: string): WalletAccountNear;
|
|
@@ -679,7 +694,11 @@ declare class WalletAccountNear extends WalletAccountReadOnlyNear implements IWa
|
|
|
679
694
|
sign(message: string | Uint8Array): Promise<string>;
|
|
680
695
|
/** NEP-413 off-chain message (what NEAR Intents and dApps ask wallets to sign). */
|
|
681
696
|
signNep413(payload: Nep413Payload): Promise<Nep413Signed>;
|
|
682
|
-
/**
|
|
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
|
+
*/
|
|
683
702
|
signBuilt(tx: NearBuiltTransaction): Promise<NearSignedTransaction>;
|
|
684
703
|
/** Build → hard checks → preflight → fee cap. Shared by sign / send / transfer. */
|
|
685
704
|
private prepare;
|
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";
|
|
@@ -862,8 +862,7 @@ var WalletAccountReadOnlyNear = class _WalletAccountReadOnlyNear {
|
|
|
862
862
|
/** Status of one of this account's transactions (the `tx` RPC needs the sender). */
|
|
863
863
|
async getTransactionReceipt(hash) {
|
|
864
864
|
const o = await this.requireRpc("fetch transaction receipts").txStatus(hash, this.address);
|
|
865
|
-
|
|
866
|
-
return receiptOf(hash, o);
|
|
865
|
+
return o ? receiptOf(hash, o) : void 0;
|
|
867
866
|
}
|
|
868
867
|
/** Verify an `ed25519:<base58>` (or bare base58 / hex) signature produced by `sign`. */
|
|
869
868
|
async verify(message, signature) {
|
|
@@ -884,8 +883,10 @@ var WalletAccountReadOnlyNear = class _WalletAccountReadOnlyNear {
|
|
|
884
883
|
};
|
|
885
884
|
function receiptOf(hash, o) {
|
|
886
885
|
const failure = outcomeFailed(o);
|
|
887
|
-
|
|
888
|
-
|
|
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;
|
|
889
890
|
}
|
|
890
891
|
function parseSignature(signature) {
|
|
891
892
|
const s = signature.startsWith("ed25519:") ? signature.slice("ed25519:".length) : signature;
|
|
@@ -993,6 +994,15 @@ var WalletAccountNear = class _WalletAccountNear extends WalletAccountReadOnlyNe
|
|
|
993
994
|
signerKind;
|
|
994
995
|
_disposed = false;
|
|
995
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();
|
|
996
1006
|
constructor(signer, publicKey, path, config = {}, accountId) {
|
|
997
1007
|
super(accountId ?? implicitAccountId(publicKey), config, ed25519Key(publicKey));
|
|
998
1008
|
this.#signer = requireCurve(signer, "ed25519");
|
|
@@ -1037,15 +1047,44 @@ var WalletAccountNear = class _WalletAccountNear extends WalletAccountReadOnlyNe
|
|
|
1037
1047
|
const sig = await this.#signBytes(nep413Hash(payload), "near-nep413");
|
|
1038
1048
|
return { signature: toBase64(sig), publicKey: publicKeyToString(this.publicKey), accountId: this.address };
|
|
1039
1049
|
}
|
|
1040
|
-
/**
|
|
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
|
+
*/
|
|
1041
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) {
|
|
1042
1077
|
assertWellFormed(tx);
|
|
1043
1078
|
const sig = await this.#signBytes(WalletAccountReadOnlyNear.hashOf(tx), "near-tx");
|
|
1044
1079
|
return { transaction: tx, signature: { keyType: "ed25519", data: sig } };
|
|
1045
1080
|
}
|
|
1046
1081
|
/** Build → hard checks → preflight → fee cap. Shared by sign / send / transfer. */
|
|
1047
1082
|
async prepare(tx, maxFee, op) {
|
|
1048
|
-
|
|
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);
|
|
1049
1088
|
this.assertSafe(built);
|
|
1050
1089
|
const estimate = await this.estimate(built);
|
|
1051
1090
|
this.assertSafe(built, estimate.fee);
|
|
@@ -1061,18 +1100,24 @@ var WalletAccountNear = class _WalletAccountNear extends WalletAccountReadOnlyNe
|
|
|
1061
1100
|
this.key();
|
|
1062
1101
|
this.requireRpc("sign transactions");
|
|
1063
1102
|
const { built } = await this.prepare(tx, feeLimit(this._config.transactionMaxFee, options), "transaction");
|
|
1064
|
-
return toBase64(encodeSignedTransaction(await this
|
|
1103
|
+
return toBase64(encodeSignedTransaction(await this.#signChecked(built)));
|
|
1065
1104
|
}
|
|
1066
1105
|
async broadcast(signed) {
|
|
1067
1106
|
const hash = WalletAccountReadOnlyNear.txHash(signed.transaction);
|
|
1068
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
|
+
};
|
|
1069
1112
|
let outcome;
|
|
1070
1113
|
try {
|
|
1071
1114
|
outcome = await rpc.sendTx(toBase64(encodeSignedTransaction(signed)));
|
|
1072
1115
|
} catch (e) {
|
|
1073
|
-
if (
|
|
1116
|
+
if (isDefinitiveBroadcast(e)) throw e;
|
|
1117
|
+
used();
|
|
1074
1118
|
throw new BroadcastUnknownError(hash, e);
|
|
1075
1119
|
}
|
|
1120
|
+
used();
|
|
1076
1121
|
const failure = outcomeFailed(outcome);
|
|
1077
1122
|
if (failure) throw new Error(`Transaction ${hash} failed on chain: ${failure}`);
|
|
1078
1123
|
return outcome.transaction?.hash ?? hash;
|
|
@@ -1081,20 +1126,35 @@ var WalletAccountNear = class _WalletAccountNear extends WalletAccountReadOnlyNe
|
|
|
1081
1126
|
* Sign and broadcast. Accepts a transaction, or base64 borsh of an unsigned /
|
|
1082
1127
|
* already-signed transaction (a signed one is checked, not re-signed).
|
|
1083
1128
|
*/
|
|
1084
|
-
|
|
1129
|
+
sendTransaction(tx, options = {}) {
|
|
1130
|
+
return this.#serial(() => this.#sendTransactionNow(tx, options));
|
|
1131
|
+
}
|
|
1132
|
+
async #sendTransactionNow(tx, options) {
|
|
1085
1133
|
this.key();
|
|
1086
1134
|
this.requireRpc("send transactions");
|
|
1087
1135
|
const presigned = typeof tx === "string" ? decodeSigned(tx) : void 0;
|
|
1088
1136
|
const { built, estimate } = await this.prepare(tx, feeLimit(this._config.transactionMaxFee, options), "transaction");
|
|
1089
|
-
const signed = presigned ?? await this
|
|
1137
|
+
const signed = presigned ?? await this.#signChecked(built);
|
|
1090
1138
|
return { hash: await this.broadcast(signed), fee: estimate.fee, estimate };
|
|
1091
1139
|
}
|
|
1092
1140
|
/** Native NEAR (no `token`) or NEP-141 `ft_transfer` (with `storage_deposit` when the recipient needs it). */
|
|
1093
|
-
|
|
1141
|
+
transfer(o, writeOptions = {}) {
|
|
1142
|
+
return this.#serial(() => this.#transferNow(o, writeOptions));
|
|
1143
|
+
}
|
|
1144
|
+
async #transferNow(o, writeOptions) {
|
|
1094
1145
|
this.key();
|
|
1095
1146
|
this.requireRpc("transfer tokens");
|
|
1096
1147
|
const { built, estimate } = await this.prepare(await this.transferActions(o), feeLimit(this._config.transferMaxFee, writeOptions), "transfer");
|
|
1097
|
-
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;
|
|
1098
1158
|
}
|
|
1099
1159
|
/** The same account as a {@link WalletAccountReadOnlyNear}. */
|
|
1100
1160
|
toReadOnlyAccount() {
|