@hwlt/era-connect 0.4.0 → 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.
Files changed (64) hide show
  1. package/README.md +3 -9
  2. package/bch/package.json +6 -0
  3. package/dist/bch-CK6dKGQA.d.ts +74 -0
  4. package/dist/bch-CpLACx0j.cjs +139 -0
  5. package/dist/bch-CpLACx0j.cjs.map +1 -0
  6. package/dist/bch-DHsIVJqK.d.cts +74 -0
  7. package/dist/bch-dMESlQfv.js +134 -0
  8. package/dist/bch-dMESlQfv.js.map +1 -0
  9. package/dist/bch.cjs +13 -0
  10. package/dist/bch.d.cts +26 -0
  11. package/dist/bch.d.ts +26 -0
  12. package/dist/bch.js +4 -0
  13. package/dist/{btc-B_Nq2H4T.js → btc-BmVgvvBd.js} +2 -2
  14. package/dist/btc-BmVgvvBd.js.map +1 -0
  15. package/dist/{btc-ByzjzUKs.cjs → btc-BxNww6kW.cjs} +2 -2
  16. package/dist/btc-BxNww6kW.cjs.map +1 -0
  17. package/dist/{btc-B8LfSEkv.d.ts → btc-uzt0uC-Q.d.ts} +6 -4
  18. package/dist/{btc-C4dVkxHb.d.cts → btc-wogJ4INA.d.cts} +6 -4
  19. package/dist/btc.cjs +1 -1
  20. package/dist/btc.d.cts +1 -1
  21. package/dist/btc.d.ts +1 -1
  22. package/dist/btc.js +1 -1
  23. package/dist/cashaddr-BIzawizX.js +134 -0
  24. package/dist/cashaddr-BIzawizX.js.map +1 -0
  25. package/dist/cashaddr-Ci0_8ITN.cjs +151 -0
  26. package/dist/cashaddr-Ci0_8ITN.cjs.map +1 -0
  27. package/dist/{derive-CK9Nc9Jc.js → derive-00JUOkmn.js} +7 -2
  28. package/dist/derive-00JUOkmn.js.map +1 -0
  29. package/dist/{derive-BayrpfJk.cjs → derive-BuNsfWlg.cjs} +12 -1
  30. package/dist/derive-BuNsfWlg.cjs.map +1 -0
  31. package/dist/gzip-CLzDX7AZ.cjs +79 -0
  32. package/dist/gzip-CLzDX7AZ.cjs.map +1 -0
  33. package/dist/gzip-DyZLtgJJ.js +68 -0
  34. package/dist/gzip-DyZLtgJJ.js.map +1 -0
  35. package/dist/index.cjs +44 -3
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +28 -3
  38. package/dist/index.d.ts +28 -3
  39. package/dist/index.js +43 -4
  40. package/dist/index.js.map +1 -1
  41. package/dist/{messages-DbnXy3dC.js → messages--XbVef_k.js} +38 -2
  42. package/dist/messages--XbVef_k.js.map +1 -0
  43. package/dist/{messages-BZXDY29v.cjs → messages-orAQ52CI.cjs} +43 -1
  44. package/dist/messages-orAQ52CI.cjs.map +1 -0
  45. package/dist/{tron-fufBDNuQ.js → tron-BpUEYTPT.js} +4 -67
  46. package/dist/tron-BpUEYTPT.js.map +1 -0
  47. package/dist/{tron-B9wXdzlA.cjs → tron-DYPOg5cm.cjs} +5 -68
  48. package/dist/{tron-fufBDNuQ.js.map → tron-DYPOg5cm.cjs.map} +1 -1
  49. package/dist/tron.cjs +2 -2
  50. package/dist/tron.js +2 -2
  51. package/dist/verify.cjs +224 -17
  52. package/dist/verify.cjs.map +1 -1
  53. package/dist/verify.d.cts +67 -1
  54. package/dist/verify.d.ts +67 -1
  55. package/dist/verify.js +222 -18
  56. package/dist/verify.js.map +1 -1
  57. package/package.json +13 -1
  58. package/dist/btc-B_Nq2H4T.js.map +0 -1
  59. package/dist/btc-ByzjzUKs.cjs.map +0 -1
  60. package/dist/derive-BayrpfJk.cjs.map +0 -1
  61. package/dist/derive-CK9Nc9Jc.js.map +0 -1
  62. package/dist/messages-BZXDY29v.cjs.map +0 -1
  63. package/dist/messages-DbnXy3dC.js.map +0 -1
  64. package/dist/tron-B9wXdzlA.cjs.map +0 -1
package/dist/verify.js CHANGED
@@ -1,17 +1,236 @@
1
1
  import { A as utf8Encode, D as hexToBytes, E as equalBytes, K as EraSdkError, T as concatBytes, k as utf8Decode, w as bytesToHex } from "./shared-Bbgejrus.js";
2
2
  import { i as parsePath } from "./keypath-Bvv_cfHt.js";
3
- import { a as cardanoSoftDerivePath } from "./derive-CK9Nc9Jc.js";
3
+ import { n as decodeCashAddr } from "./cashaddr-BIzawizX.js";
4
+ import { o as cardanoSoftDerivePath } from "./derive-00JUOkmn.js";
4
5
  import { n as parseWitnessSet } from "./cardano-BCT55gwf.js";
6
+ import { a as firstBytes, i as splitSignedTronTx, o as firstVarint, s as readFields } from "./messages--XbVef_k.js";
5
7
  import { n as EvmDataType, r as foldRecoveryId } from "./evm-CI1cuZsp.js";
6
8
  import { n as suiIntentDigest } from "./sui-BtbPG6Xt.js";
7
9
  import { n as TonDataType } from "./ton-BSPKU5B9.js";
8
- import { a as firstVarint, i as firstBytes, o as readFields, r as splitSignedTronTx } from "./messages-DbnXy3dC.js";
9
10
  import { secp256k1 } from "@noble/curves/secp256k1";
10
11
  import { blake2b } from "@noble/hashes/blake2b";
12
+ import { ripemd160 } from "@noble/hashes/ripemd160";
11
13
  import { sha256, sha512 } from "@noble/hashes/sha2";
12
14
  import { keccak_256 } from "@noble/hashes/sha3";
13
15
  import { createBase58check } from "@scure/base";
14
16
  import { ed25519 } from "@noble/curves/ed25519";
17
+ //#region src/verify/result.ts
18
+ const verified = {
19
+ ok: true,
20
+ checked: true
21
+ };
22
+ const failed = (reason) => ({
23
+ ok: false,
24
+ reason
25
+ });
26
+ const unverifiable = (reason) => ({
27
+ ok: true,
28
+ checked: false,
29
+ reason
30
+ });
31
+ //#endregion
32
+ //#region src/verify/bch.ts
33
+ const SIGHASH_FORKID_ALL = 65;
34
+ const BCH_TX_VERSION = 1;
35
+ const BCH_TX_LOCKTIME = 0;
36
+ const BCH_TX_SEQUENCE = 4294967293;
37
+ /** Hardened reader for the legacy (non-witness) transaction serialization. */
38
+ function decodeBchRawTx(rawTxHex) {
39
+ let bytes;
40
+ try {
41
+ bytes = hexToBytes(rawTxHex);
42
+ } catch {
43
+ throw new EraSdkError("malformed-reply", "signed transaction is not hex");
44
+ }
45
+ let offset = 0;
46
+ const need = (n) => {
47
+ if (offset + n > bytes.length) throw new EraSdkError("malformed-reply", "signed transaction is truncated");
48
+ };
49
+ const readU32 = () => {
50
+ need(4);
51
+ const v = bytes[offset] | bytes[offset + 1] << 8 | bytes[offset + 2] << 16 | bytes[offset + 3] << 24;
52
+ offset += 4;
53
+ return v >>> 0;
54
+ };
55
+ const readU64 = () => {
56
+ need(8);
57
+ let v = 0n;
58
+ for (let i = 7; i >= 0; i--) v = v << 8n | BigInt(bytes[offset + i]);
59
+ offset += 8;
60
+ return v;
61
+ };
62
+ const readVarint = () => {
63
+ need(1);
64
+ const first = bytes[offset++];
65
+ if (first < 253) return first;
66
+ if (first === 253) {
67
+ need(2);
68
+ const v = bytes[offset] | bytes[offset + 1] << 8;
69
+ offset += 2;
70
+ return v;
71
+ }
72
+ throw new EraSdkError("malformed-reply", "unreasonable varint in signed transaction");
73
+ };
74
+ const readSlice = (n) => {
75
+ need(n);
76
+ const s = bytes.subarray(offset, offset + n);
77
+ offset += n;
78
+ return s;
79
+ };
80
+ const version = readU32();
81
+ const inputCount = readVarint();
82
+ if (inputCount === 0 || inputCount > 1e3) throw new EraSdkError("malformed-reply", "unreasonable input count in signed transaction");
83
+ const inputs = [];
84
+ for (let i = 0; i < inputCount; i++) {
85
+ const txidLE = readSlice(32);
86
+ const index = readU32();
87
+ const scriptSig = readSlice(readVarint());
88
+ const sequence = readU32();
89
+ inputs.push({
90
+ txidLE,
91
+ index,
92
+ scriptSig,
93
+ sequence
94
+ });
95
+ }
96
+ const outputCount = readVarint();
97
+ if (outputCount === 0 || outputCount > 1e3) throw new EraSdkError("malformed-reply", "unreasonable output count in signed transaction");
98
+ const outputs = [];
99
+ for (let i = 0; i < outputCount; i++) {
100
+ const value = readU64();
101
+ const script = readSlice(readVarint());
102
+ outputs.push({
103
+ value,
104
+ script
105
+ });
106
+ }
107
+ const locktime = readU32();
108
+ if (offset !== bytes.length) throw new EraSdkError("malformed-reply", "trailing bytes after signed transaction");
109
+ return {
110
+ version,
111
+ inputs,
112
+ outputs,
113
+ locktime
114
+ };
115
+ }
116
+ function sha256d(data) {
117
+ return sha256(sha256(data));
118
+ }
119
+ function hash160(data) {
120
+ return ripemd160(sha256(data));
121
+ }
122
+ function p2pkhScript(pubkeyHash) {
123
+ return concatBytes(new Uint8Array([
124
+ 118,
125
+ 169,
126
+ 20
127
+ ]), pubkeyHash, new Uint8Array([136, 172]));
128
+ }
129
+ function p2shScript(scriptHash) {
130
+ return concatBytes(new Uint8Array([169, 20]), scriptHash, new Uint8Array([135]));
131
+ }
132
+ function scriptForAddress(address) {
133
+ const decoded = decodeCashAddr(address);
134
+ return decoded.type === "p2pkh" ? p2pkhScript(decoded.hash) : p2shScript(decoded.hash);
135
+ }
136
+ function le32(value) {
137
+ return new Uint8Array([
138
+ value & 255,
139
+ value >>> 8 & 255,
140
+ value >>> 16 & 255,
141
+ value >>> 24 & 255
142
+ ]);
143
+ }
144
+ function le64(value) {
145
+ const out = /* @__PURE__ */ new Uint8Array(8);
146
+ let v = value;
147
+ for (let i = 0; i < 8; i++) {
148
+ out[i] = Number(v & 255n);
149
+ v >>= 8n;
150
+ }
151
+ return out;
152
+ }
153
+ function varintBytes(value) {
154
+ if (value < 253) return new Uint8Array([value]);
155
+ return new Uint8Array([
156
+ 253,
157
+ value & 255,
158
+ value >>> 8 & 255
159
+ ]);
160
+ }
161
+ /**
162
+ * BIP-143 sighash preimage with FORKID, exactly as consensus defines it:
163
+ * `version ‖ hashPrevouts ‖ hashSequence ‖ outpoint ‖ scriptCode ‖ value ‖
164
+ * sequence ‖ hashOutputs ‖ locktime ‖ hashType(LE)`, double-SHA256d.
165
+ */
166
+ function computeBchSighash(args) {
167
+ const { tx, inputIndex, scriptCode, value } = args;
168
+ const hashType = args.hashType ?? SIGHASH_FORKID_ALL;
169
+ const input = tx.inputs[inputIndex];
170
+ if (!input) throw new EraSdkError("invalid-props", "sighash input index out of range");
171
+ const hashPrevouts = sha256d(concatBytes(...tx.inputs.map((i) => concatBytes(i.txidLE, le32(i.index)))));
172
+ const hashSequence = sha256d(concatBytes(...tx.inputs.map((i) => le32(i.sequence))));
173
+ const hashOutputs = sha256d(concatBytes(...tx.outputs.map((o) => concatBytes(le64(o.value), varintBytes(o.script.length), o.script))));
174
+ return sha256d(concatBytes(le32(tx.version), hashPrevouts, hashSequence, input.txidLE, le32(input.index), varintBytes(scriptCode.length), scriptCode, le64(value), le32(input.sequence), hashOutputs, le32(tx.locktime), le32(hashType)));
175
+ }
176
+ function toBigintValue(value, label) {
177
+ const v = typeof value === "number" ? BigInt(value) : value;
178
+ if (v <= 0n) throw new EraSdkError("invalid-props", `${label} must be positive`);
179
+ return v;
180
+ }
181
+ function toPublicKeyBytes(publicKey) {
182
+ return typeof publicKey === "string" ? hexToBytes(publicKey) : publicKey;
183
+ }
184
+ function verifyBchSignedTx(args) {
185
+ try {
186
+ const tx = decodeBchRawTx(args.rawTx);
187
+ if (tx.version !== BCH_TX_VERSION || tx.locktime !== BCH_TX_LOCKTIME) return failed(`transaction parameters (version ${tx.version}, locktime ${tx.locktime}) are not the device signer's (1, 0)`);
188
+ for (let i = 0; i < tx.inputs.length; i++) if (tx.inputs[i].sequence !== BCH_TX_SEQUENCE) return failed(`input ${i} sequence is not the device signer's 0xfffffffd`);
189
+ if (tx.inputs.length !== args.inputs.length) return failed(`signed transaction has ${tx.inputs.length} inputs, the request had ${args.inputs.length}`);
190
+ if (tx.outputs.length !== args.outputs.length) return failed(`signed transaction has ${tx.outputs.length} outputs, the request had ${args.outputs.length}`);
191
+ for (let i = 0; i < args.outputs.length; i++) {
192
+ const requested = args.outputs[i];
193
+ const actual = tx.outputs[i];
194
+ if (actual.value !== toBigintValue(requested.value, `output ${i} value`)) return failed(`output ${i} value differs from the request`);
195
+ if (!equalBytes(actual.script, scriptForAddress(requested.address))) return failed(`output ${i} does not pay the requested address`);
196
+ }
197
+ for (let i = 0; i < args.inputs.length; i++) {
198
+ const requested = args.inputs[i];
199
+ const actual = tx.inputs[i];
200
+ const txidLE = hexToBytes(requested.txid).reverse();
201
+ if (!equalBytes(actual.txidLE, txidLE) || actual.index !== requested.index) return failed(`input ${i} spends a different outpoint than the request named`);
202
+ const script = actual.scriptSig;
203
+ if (script.length < 2) return failed(`input ${i} has no signature`);
204
+ const sigLen = script[0];
205
+ if (sigLen < 9 || 1 + sigLen + 1 > script.length) return failed(`input ${i} scriptSig is not a signature push`);
206
+ const sigWithType = script.subarray(1, 1 + sigLen);
207
+ const pubLen = script[1 + sigLen];
208
+ if (pubLen !== 33 || 1 + sigLen + 1 + pubLen !== script.length) return failed(`input ${i} scriptSig does not end with a compressed public key push`);
209
+ const pubkey = script.subarray(1 + sigLen + 1);
210
+ if (!equalBytes(pubkey, toPublicKeyBytes(requested.publicKey))) return failed(`input ${i} was signed with a different public key than the request named — the transaction cannot spend the requested UTXO`);
211
+ const hashType = sigWithType[sigWithType.length - 1];
212
+ if (hashType !== SIGHASH_FORKID_ALL) return failed(`input ${i} uses sighash 0x${hashType.toString(16)}, expected SIGHASH_ALL|FORKID (0x41)`);
213
+ const sighash = computeBchSighash({
214
+ tx,
215
+ inputIndex: i,
216
+ scriptCode: p2pkhScript(hash160(pubkey)),
217
+ value: toBigintValue(requested.value, `input ${i} value`)
218
+ });
219
+ const signature = secp256k1.Signature.fromDER(sigWithType.subarray(0, sigWithType.length - 1)).toCompactRawBytes();
220
+ if (!secp256k1.verify(signature, sighash, pubkey)) return failed(`input ${i} signature does not verify against the BIP-143 FORKID sighash`);
221
+ }
222
+ if (args.txId !== void 0) {
223
+ if (bytesToHex(sha256d(hexToBytes(args.rawTx)).reverse()) !== args.txId.toLowerCase()) return failed("reply txId does not match the hash of the signed transaction");
224
+ }
225
+ return verified;
226
+ } catch (e) {
227
+ return failed(message$1(e));
228
+ }
229
+ }
230
+ function message$1(e) {
231
+ return e instanceof EraSdkError || e instanceof Error ? e.message : String(e);
232
+ }
233
+ //#endregion
15
234
  //#region src/verify/psbt-reader.ts
16
235
  const MAGIC = [
17
236
  112,
@@ -150,21 +369,6 @@ function inputHas(psbt, index, keyType) {
150
369
  return inputEntries(psbt, index, keyType).length > 0;
151
370
  }
152
371
  //#endregion
153
- //#region src/verify/result.ts
154
- const verified = {
155
- ok: true,
156
- checked: true
157
- };
158
- const failed = (reason) => ({
159
- ok: false,
160
- reason
161
- });
162
- const unverifiable = (reason) => ({
163
- ok: true,
164
- checked: false,
165
- reason
166
- });
167
- //#endregion
168
372
  //#region src/verify/btc.ts
169
373
  /**
170
374
  * The `crypto-psbt` reply carries NO request id — this comparison IS the
@@ -899,6 +1103,6 @@ function readVl(bytes, pos) {
899
1103
  };
900
1104
  }
901
1105
  //#endregion
902
- export { PsbtInputType, bocRootHash, parsePsbt, verifyBtcMessageHeader, verifyCardanoSignature, verifyCosmosSignature, verifyEvmSignature, verifySignedPsbt, verifySolanaSignature, verifySuiSignature, verifyTonSignature, verifyTronSignature, verifyXrpSignature };
1106
+ export { PsbtInputType, bocRootHash, computeBchSighash, decodeBchRawTx, parsePsbt, verifyBchSignedTx, verifyBtcMessageHeader, verifyCardanoSignature, verifyCosmosSignature, verifyEvmSignature, verifySignedPsbt, verifySolanaSignature, verifySuiSignature, verifyTonSignature, verifyTronSignature, verifyXrpSignature };
903
1107
 
904
1108
  //# sourceMappingURL=verify.js.map