@anywalletkit/wallet-zcash 0.3.1 → 0.5.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/dist/index.cjs +23 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -5
- package/dist/index.d.ts +3 -5
- package/dist/index.js +23 -15
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -128,7 +128,8 @@ function encodeAddress(kind, hash, network) {
|
|
|
128
128
|
return b58.encode(Uint8Array.of(a, b, ...hash));
|
|
129
129
|
}
|
|
130
130
|
function decodeAddress(address, network) {
|
|
131
|
-
|
|
131
|
+
if (typeof address !== "string" || /\s/.test(address)) throw new Error(`Invalid Zcash address: it carries whitespace or an invisible character (${JSON.stringify(address)}).`);
|
|
132
|
+
const a = address;
|
|
132
133
|
if (/^u1|^utest/i.test(a)) throw new Error(`Unified address (${a.slice(0, 6)}\u2026) \u2014 shielded receivers are not supported; use a transparent t-address.`);
|
|
133
134
|
if (/^zs1|^ztestsapling/i.test(a)) throw new Error("Sapling shielded address (zs1\u2026) \u2014 this wallet sends to transparent t-addresses only.");
|
|
134
135
|
if (/^zc/i.test(a) && a.length > 90) throw new Error("Sprout address (zc\u2026) \u2014 the Sprout pool is deprecated; use a transparent t-address.");
|
|
@@ -1103,15 +1104,22 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1103
1104
|
path;
|
|
1104
1105
|
/** Compressed secp256k1 public key. */
|
|
1105
1106
|
publicKey;
|
|
1106
|
-
/**
|
|
1107
|
-
|
|
1107
|
+
/**
|
|
1108
|
+
* The signer that holds the key, in a private field: not a property of the account, so no code
|
|
1109
|
+
* the account is handed to (a protocol module, a logger) can reach it and sign around the
|
|
1110
|
+
* account's checks (audit 2026-10-29 A1).
|
|
1111
|
+
*/
|
|
1112
|
+
#signer;
|
|
1113
|
+
/** What holds the key: `seed`, `key` (one imported key) or `external`. */
|
|
1114
|
+
signerKind;
|
|
1108
1115
|
_disposed = false;
|
|
1109
1116
|
_readOnly;
|
|
1110
1117
|
/** `publicKey` is the signer's compressed secp256k1 key (33 bytes); it is needed synchronously for the address. */
|
|
1111
1118
|
constructor(signer, publicKey, path, config = {}) {
|
|
1112
1119
|
super(addressFromPublicKey(publicKey, config.network ?? "mainnet"), config);
|
|
1113
|
-
this
|
|
1114
|
-
|
|
1120
|
+
this.#signer = (0, import_core7.requireCurve)(signer, "secp256k1");
|
|
1121
|
+
this.signerKind = this.#signer.kind;
|
|
1122
|
+
if (!this.#signer.schemes.includes("ecdsa")) throw new import_core7.SignerError(`A Zcash account needs a signer with the 'ecdsa' scheme (has: ${this.#signer.schemes.join(", ")}).`);
|
|
1115
1123
|
this.publicKey = publicKey;
|
|
1116
1124
|
this.path = path;
|
|
1117
1125
|
}
|
|
@@ -1130,7 +1138,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1130
1138
|
/** Zcash message signature (zcashd `signmessage` encoding), base64. */
|
|
1131
1139
|
async sign(message) {
|
|
1132
1140
|
this.live();
|
|
1133
|
-
return signMessageWith(message, this
|
|
1141
|
+
return signMessageWith(message, this.#signer);
|
|
1134
1142
|
}
|
|
1135
1143
|
ctx(intended) {
|
|
1136
1144
|
return { network: this._network, ownAddress: this.address, intended, maxFee: this.maxFee };
|
|
@@ -1159,15 +1167,15 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1159
1167
|
return { lockTime, expiryHeight, consensusBranchId };
|
|
1160
1168
|
}
|
|
1161
1169
|
/** Sign every input through the signer; the scriptSig is `<DER ‖ 0x01> <pubkey>`. */
|
|
1162
|
-
async signInputs(tx, spent) {
|
|
1170
|
+
async #signInputs(tx, spent) {
|
|
1163
1171
|
for (let i = 0; i < tx.inputs.length; i++) {
|
|
1164
1172
|
const digest = sighashAll(tx, i, spent);
|
|
1165
|
-
const rs = await this
|
|
1173
|
+
const rs = await this.#signer.sign(digest, { scheme: "ecdsa", context: "zcash-sighash" });
|
|
1166
1174
|
const der = import_secp256k12.secp256k1.Signature.fromBytes(rs, "compact").toBytes("der");
|
|
1167
1175
|
tx.inputs[i].scriptSig = p2pkhScriptSig(der, this.publicKey);
|
|
1168
1176
|
}
|
|
1169
1177
|
}
|
|
1170
|
-
async signSpend(spend) {
|
|
1178
|
+
async #signSpend(spend) {
|
|
1171
1179
|
this.live();
|
|
1172
1180
|
const plan = await this.planSpend(spend);
|
|
1173
1181
|
const params = await this.chainParams();
|
|
@@ -1179,7 +1187,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1179
1187
|
const spent = plan.utxos.map((u) => ({ value: u.value, script: this.scriptPubKey }));
|
|
1180
1188
|
const have = plan.utxos.reduce((s, u) => s + u.value, 0n);
|
|
1181
1189
|
if (have < plan.amount + plan.fee) throw new import_core7.InsufficientFundsError(plan.amount + plan.fee, have, "ZEC");
|
|
1182
|
-
await this
|
|
1190
|
+
await this.#signInputs(tx, spent);
|
|
1183
1191
|
const ctx = this.ctx({ to: spend.to, value: plan.amount });
|
|
1184
1192
|
const desc = describeTransaction(tx, spent, ctx);
|
|
1185
1193
|
assertSafe(desc, ctx);
|
|
@@ -1211,7 +1219,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1211
1219
|
/** "What you sign": the fully resolved spend (signed, NOT broadcast) or a caller's raw hex. */
|
|
1212
1220
|
async describeTransaction(tx) {
|
|
1213
1221
|
if (typeof tx === "string") return (await this.describeRaw(tx)).desc;
|
|
1214
|
-
return (await this
|
|
1222
|
+
return (await this.#signSpend(tx)).desc;
|
|
1215
1223
|
}
|
|
1216
1224
|
/** Sign without broadcasting. Returns the raw transaction hex. Raw hex input gets the checks `sendTransaction` runs (prevouts through the client) and is returned unchanged, never re-signed. */
|
|
1217
1225
|
async signTransaction(tx, options = {}) {
|
|
@@ -1221,7 +1229,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1221
1229
|
this.checkMax(desc.fee, (0, import_core7.feeLimit)(this._config.transactionMaxFee, options), "transaction");
|
|
1222
1230
|
return tx;
|
|
1223
1231
|
}
|
|
1224
|
-
const built = await this
|
|
1232
|
+
const built = await this.#signSpend(tx);
|
|
1225
1233
|
this.checkMax(built.fee, (0, import_core7.feeLimit)(this._config.transactionMaxFee, options), "transaction");
|
|
1226
1234
|
return built.hex;
|
|
1227
1235
|
}
|
|
@@ -1239,7 +1247,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1239
1247
|
hash = txid(parsed);
|
|
1240
1248
|
fee = desc.fee;
|
|
1241
1249
|
} else {
|
|
1242
|
-
const built = await this
|
|
1250
|
+
const built = await this.#signSpend(tx);
|
|
1243
1251
|
rawHex = built.hex;
|
|
1244
1252
|
hash = built.txid;
|
|
1245
1253
|
fee = built.fee;
|
|
@@ -1252,7 +1260,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1252
1260
|
if (o.token) throw new Error("Tokens are not supported on the zcash blockchain.");
|
|
1253
1261
|
this.live();
|
|
1254
1262
|
const client = this.requireClient("transfer");
|
|
1255
|
-
const built = await this
|
|
1263
|
+
const built = await this.#signSpend({ to: o.recipient, value: o.amount });
|
|
1256
1264
|
this.checkMax(built.fee, (0, import_core7.feeLimit)(this._config.transferMaxFee, writeOptions), "transfer");
|
|
1257
1265
|
return { hash: await this.broadcast(client, built.hex, built.txid), fee: built.fee };
|
|
1258
1266
|
}
|
|
@@ -1277,7 +1285,7 @@ var WalletAccountZcash = class _WalletAccountZcash extends WalletAccountReadOnly
|
|
|
1277
1285
|
}
|
|
1278
1286
|
dispose() {
|
|
1279
1287
|
this._disposed = true;
|
|
1280
|
-
this
|
|
1288
|
+
this.#signer.dispose();
|
|
1281
1289
|
}
|
|
1282
1290
|
};
|
|
1283
1291
|
|