@hwlt/era-connect 0.2.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 +6 -6
- package/cardano/package.json +6 -0
- package/cosmos/package.json +6 -0
- package/dist/{btc-DfQ0q79G.d.ts → btc-B8LfSEkv.d.ts} +11 -2
- package/dist/{btc-VyJKXq7d.js → btc-B_Nq2H4T.js} +16 -7
- package/dist/btc-B_Nq2H4T.js.map +1 -0
- package/dist/{btc-Fr6Jz4Fi.cjs → btc-ByzjzUKs.cjs} +19 -10
- package/dist/btc-ByzjzUKs.cjs.map +1 -0
- package/dist/{btc-Dn6_Y12c.d.cts → btc-C4dVkxHb.d.cts} +11 -2
- package/dist/btc.cjs +2 -2
- package/dist/btc.d.cts +1 -1
- package/dist/btc.d.ts +1 -1
- package/dist/btc.js +2 -2
- package/dist/cardano-BCT55gwf.js +95 -0
- package/dist/cardano-BCT55gwf.js.map +1 -0
- package/dist/cardano-CzYswGzK.cjs +106 -0
- package/dist/cardano-CzYswGzK.cjs.map +1 -0
- package/dist/cardano-Do1ahUlK.d.cts +62 -0
- package/dist/cardano-OzjWZHh6.d.ts +62 -0
- package/dist/cardano.cjs +10 -0
- package/dist/cardano.d.cts +3 -0
- package/dist/cardano.d.ts +3 -0
- package/dist/cardano.js +3 -0
- package/dist/cosmos-BYrhIqRk.d.cts +77 -0
- package/dist/cosmos-DDsgtUki.cjs +113 -0
- package/dist/cosmos-DDsgtUki.cjs.map +1 -0
- package/dist/cosmos-DqyjA6lg.d.ts +77 -0
- package/dist/cosmos-jUHNxgWC.js +102 -0
- package/dist/cosmos-jUHNxgWC.js.map +1 -0
- package/dist/cosmos.cjs +10 -0
- package/dist/cosmos.d.cts +3 -0
- package/dist/cosmos.d.ts +3 -0
- package/dist/cosmos.js +3 -0
- package/dist/derive-BayrpfJk.cjs +188 -0
- package/dist/derive-BayrpfJk.cjs.map +1 -0
- package/dist/derive-CK9Nc9Jc.js +123 -0
- package/dist/derive-CK9Nc9Jc.js.map +1 -0
- package/dist/{evm-kJb3-oiR.js → evm-CI1cuZsp.js} +3 -2
- package/dist/{evm-kJb3-oiR.js.map → evm-CI1cuZsp.js.map} +1 -1
- package/dist/{evm-BHj_2OTG.cjs → evm-yfKOc2dy.cjs} +6 -5
- package/dist/{evm-BHj_2OTG.cjs.map → evm-yfKOc2dy.cjs.map} +1 -1
- package/dist/evm.cjs +2 -2
- package/dist/evm.js +2 -2
- package/dist/index.cjs +156 -116
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -9
- package/dist/index.d.ts +68 -9
- package/dist/index.js +125 -94
- package/dist/index.js.map +1 -1
- package/dist/keypath-Bvv_cfHt.js +75 -0
- package/dist/keypath-Bvv_cfHt.js.map +1 -0
- package/dist/keypath-pzm_YIfN.cjs +116 -0
- package/dist/keypath-pzm_YIfN.cjs.map +1 -0
- package/dist/{messages-BzcdWlg1.cjs → messages-BZXDY29v.cjs} +2 -2
- package/dist/{messages-BzcdWlg1.cjs.map → messages-BZXDY29v.cjs.map} +1 -1
- package/dist/{messages-17Oup0-Z.js → messages-DbnXy3dC.js} +2 -2
- package/dist/{messages-17Oup0-Z.js.map → messages-DbnXy3dC.js.map} +1 -1
- package/dist/{shared-B8Wc7ViU.js → shared-Bbgejrus.js} +2 -73
- package/dist/shared-Bbgejrus.js.map +1 -0
- package/dist/{shared-nISrEktU.cjs → shared-Cu2yynP9.cjs} +13 -114
- package/dist/shared-Cu2yynP9.cjs.map +1 -0
- package/dist/{solana-DdEn24X4.cjs → solana-BoQBy0hu.cjs} +6 -5
- package/dist/{solana-DdEn24X4.cjs.map → solana-BoQBy0hu.cjs.map} +1 -1
- package/dist/{solana-C7JQEAec.js → solana-BukH3AI3.js} +3 -2
- package/dist/{solana-C7JQEAec.js.map → solana-BukH3AI3.js.map} +1 -1
- package/dist/solana.cjs +2 -2
- package/dist/solana.js +2 -2
- package/dist/sui-6WX6VPlW.d.cts +49 -0
- package/dist/sui-BtbPG6Xt.js +71 -0
- package/dist/sui-BtbPG6Xt.js.map +1 -0
- package/dist/sui-CYRn331O.cjs +82 -0
- package/dist/sui-CYRn331O.cjs.map +1 -0
- package/dist/sui-DI0ruW7E.d.ts +49 -0
- package/dist/sui.cjs +10 -0
- package/dist/sui.d.cts +3 -0
- package/dist/sui.d.ts +3 -0
- package/dist/sui.js +3 -0
- package/dist/{ton-5Uvi5ifg.js → ton-BSPKU5B9.js} +3 -2
- package/dist/{ton-5Uvi5ifg.js.map → ton-BSPKU5B9.js.map} +1 -1
- package/dist/{ton-DUJGXdGa.cjs → ton-CI2s9puH.cjs} +6 -5
- package/dist/{ton-DUJGXdGa.cjs.map → ton-CI2s9puH.cjs.map} +1 -1
- package/dist/ton.cjs +2 -2
- package/dist/ton.js +2 -2
- package/dist/{tron-CQIEqjCA.cjs → tron-B9wXdzlA.cjs} +7 -6
- package/dist/{tron-CQIEqjCA.cjs.map → tron-B9wXdzlA.cjs.map} +1 -1
- package/dist/{tron-Bo9HnvVE.js → tron-fufBDNuQ.js} +4 -3
- package/dist/{tron-Bo9HnvVE.js.map → tron-fufBDNuQ.js.map} +1 -1
- package/dist/tron.cjs +3 -3
- package/dist/tron.js +3 -3
- package/dist/verify.cjs +335 -4
- package/dist/verify.cjs.map +1 -1
- package/dist/verify.d.cts +86 -1
- package/dist/verify.d.ts +86 -1
- package/dist/verify.js +333 -6
- package/dist/verify.js.map +1 -1
- package/dist/xrp-BXAeK4iH.d.cts +32 -0
- package/dist/xrp-BrHXUnX5.cjs +52 -0
- package/dist/xrp-BrHXUnX5.cjs.map +1 -0
- package/dist/xrp-C8LJO5b-.js +47 -0
- package/dist/xrp-C8LJO5b-.js.map +1 -0
- package/dist/xrp-DqCXGYEk.d.ts +32 -0
- package/dist/xrp.cjs +9 -0
- package/dist/xrp.d.cts +3 -0
- package/dist/xrp.d.ts +3 -0
- package/dist/xrp.js +3 -0
- package/package.json +49 -1
- package/sui/package.json +6 -0
- package/xrp/package.json +6 -0
- package/dist/btc-Fr6Jz4Fi.cjs.map +0 -1
- package/dist/btc-VyJKXq7d.js.map +0 -1
- package/dist/shared-B8Wc7ViU.js.map +0 -1
- package/dist/shared-nISrEktU.cjs.map +0 -1
package/dist/verify.cjs
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_shared = require("./shared-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
2
|
+
const require_shared = require("./shared-Cu2yynP9.cjs");
|
|
3
|
+
const require_keypath = require("./keypath-pzm_YIfN.cjs");
|
|
4
|
+
const require_derive = require("./derive-BayrpfJk.cjs");
|
|
5
|
+
const require_cardano = require("./cardano-CzYswGzK.cjs");
|
|
6
|
+
const require_evm = require("./evm-yfKOc2dy.cjs");
|
|
7
|
+
const require_sui = require("./sui-CYRn331O.cjs");
|
|
8
|
+
const require_ton = require("./ton-CI2s9puH.cjs");
|
|
9
|
+
const require_messages = require("./messages-BZXDY29v.cjs");
|
|
6
10
|
let _noble_curves_secp256k1 = require("@noble/curves/secp256k1");
|
|
11
|
+
let _noble_hashes_blake2b = require("@noble/hashes/blake2b");
|
|
7
12
|
let _noble_hashes_sha2 = require("@noble/hashes/sha2");
|
|
8
13
|
let _noble_hashes_sha3 = require("@noble/hashes/sha3");
|
|
9
14
|
let _scure_base = require("@scure/base");
|
|
@@ -247,6 +252,165 @@ function message(e) {
|
|
|
247
252
|
return e instanceof require_shared.EraSdkError || e instanceof Error ? e.message : String(e);
|
|
248
253
|
}
|
|
249
254
|
//#endregion
|
|
255
|
+
//#region src/verify/cardano.ts
|
|
256
|
+
/**
|
|
257
|
+
* Recompute the digest the device signs — BLAKE2b-256 of the ENCODED FIRST
|
|
258
|
+
* ELEMENT of the transaction CBOR array (the tx body) — and verify every
|
|
259
|
+
* `[vkey, signature]` pair against it. With `account` + `signerPaths`, the
|
|
260
|
+
* vkeys are additionally required to be exactly the soft-derived children of
|
|
261
|
+
* YOUR linked account at the request's own paths.
|
|
262
|
+
*/
|
|
263
|
+
function verifyCardanoSignature(args) {
|
|
264
|
+
let witnesses;
|
|
265
|
+
try {
|
|
266
|
+
witnesses = args.witnesses ?? (args.witnessSet ? require_cardano.parseWitnessSet(args.witnessSet) : []);
|
|
267
|
+
} catch (e) {
|
|
268
|
+
return failed(`witness set is not readable: ${e.message}`);
|
|
269
|
+
}
|
|
270
|
+
if (witnesses.length === 0) return failed("no witnesses to verify");
|
|
271
|
+
let digest;
|
|
272
|
+
try {
|
|
273
|
+
digest = (0, _noble_hashes_blake2b.blake2b)(firstArrayItemBytes(args.signData), { dkLen: 32 });
|
|
274
|
+
} catch (e) {
|
|
275
|
+
return failed(`signData is not a readable transaction array: ${e.message}`);
|
|
276
|
+
}
|
|
277
|
+
for (const witness of witnesses) {
|
|
278
|
+
let ok;
|
|
279
|
+
try {
|
|
280
|
+
ok = _noble_curves_ed25519.ed25519.verify(witness.signature, digest, witness.vkey);
|
|
281
|
+
} catch (e) {
|
|
282
|
+
return failed(`Cardano signature could not be checked: ${e.message}`);
|
|
283
|
+
}
|
|
284
|
+
if (!ok) return failed("a witness signature does not verify against its own vkey");
|
|
285
|
+
}
|
|
286
|
+
if (args.account && args.signerPaths && args.signerPaths.length > 0) {
|
|
287
|
+
const accountLevels = require_keypath.parsePath(args.account.accountPath);
|
|
288
|
+
const expected = /* @__PURE__ */ new Map();
|
|
289
|
+
for (const path of new Set(args.signerPaths)) {
|
|
290
|
+
const levels = require_keypath.parsePath(path);
|
|
291
|
+
if (levels.length !== accountLevels.length + 2 || !accountLevels.every((l, i) => levels[i].index === l.index && levels[i].hardened === l.hardened) || levels.slice(accountLevels.length).some((l) => l.hardened)) return failed(`signer path ${path} does not extend the account path with two soft components`);
|
|
292
|
+
const tail = levels.slice(accountLevels.length).map((l) => l.index);
|
|
293
|
+
const vkey = require_derive.cardanoSoftDerivePath(args.account.publicKey, args.account.chainCode, tail);
|
|
294
|
+
expected.set(require_shared.bytesToHex(vkey), path);
|
|
295
|
+
}
|
|
296
|
+
for (const [vkeyHex, path] of expected) if (!witnesses.some((w) => require_shared.bytesToHex(w.vkey) === vkeyHex)) return failed(`no witness for the requested signer path ${path}`);
|
|
297
|
+
for (const witness of witnesses) if (!expected.has(require_shared.bytesToHex(witness.vkey))) return failed("the witness set carries a key your request did not ask for");
|
|
298
|
+
}
|
|
299
|
+
return verified;
|
|
300
|
+
}
|
|
301
|
+
function firstArrayItemBytes(bytes) {
|
|
302
|
+
const top = bytes[0];
|
|
303
|
+
if (top === void 0) throw new Error("empty input");
|
|
304
|
+
if (top >> 5 !== 4) throw new Error("not a CBOR array");
|
|
305
|
+
let start;
|
|
306
|
+
if ((top & 31) === 31) start = 1;
|
|
307
|
+
else {
|
|
308
|
+
const head = readHead(bytes, 0);
|
|
309
|
+
if (head.value === 0n) throw new Error("transaction array is empty");
|
|
310
|
+
start = head.next;
|
|
311
|
+
}
|
|
312
|
+
const end = skipItem(bytes, start, 0);
|
|
313
|
+
return bytes.slice(start, end);
|
|
314
|
+
}
|
|
315
|
+
function readHead(bytes, offset) {
|
|
316
|
+
const initial = bytes[offset];
|
|
317
|
+
if (initial === void 0) throw new Error("truncated");
|
|
318
|
+
const info = initial & 31;
|
|
319
|
+
if (info < 24) return {
|
|
320
|
+
value: BigInt(info),
|
|
321
|
+
next: offset + 1
|
|
322
|
+
};
|
|
323
|
+
if (info === 31) return {
|
|
324
|
+
value: -1n,
|
|
325
|
+
next: offset + 1
|
|
326
|
+
};
|
|
327
|
+
let width;
|
|
328
|
+
if (info === 24) width = 1;
|
|
329
|
+
else if (info === 25) width = 2;
|
|
330
|
+
else if (info === 26) width = 4;
|
|
331
|
+
else if (info === 27) width = 8;
|
|
332
|
+
else throw new Error("reserved length encoding");
|
|
333
|
+
let value = 0n;
|
|
334
|
+
for (let i = 0; i < width; i++) {
|
|
335
|
+
const b = bytes[offset + 1 + i];
|
|
336
|
+
if (b === void 0) throw new Error("truncated");
|
|
337
|
+
value = value << 8n | BigInt(b);
|
|
338
|
+
}
|
|
339
|
+
return {
|
|
340
|
+
value,
|
|
341
|
+
next: offset + 1 + width
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
/** Returns the offset just past the item starting at `offset`. */
|
|
345
|
+
function skipItem(bytes, offset, depth) {
|
|
346
|
+
if (depth > 32) throw new Error("nesting too deep");
|
|
347
|
+
const initial = bytes[offset];
|
|
348
|
+
if (initial === void 0) throw new Error("truncated");
|
|
349
|
+
const major = initial >> 5;
|
|
350
|
+
const head = readHead(bytes, offset);
|
|
351
|
+
switch (major) {
|
|
352
|
+
case 0:
|
|
353
|
+
case 1:
|
|
354
|
+
if (head.value === -1n) throw new Error("malformed integer");
|
|
355
|
+
return head.next;
|
|
356
|
+
case 2:
|
|
357
|
+
case 3: {
|
|
358
|
+
if (head.value === -1n) {
|
|
359
|
+
let pos = head.next;
|
|
360
|
+
while (bytes[pos] !== 255) {
|
|
361
|
+
const chunk = readHead(bytes, pos);
|
|
362
|
+
if (chunk.value < 0n) throw new Error("malformed chunk");
|
|
363
|
+
pos = chunk.next + Number(chunk.value);
|
|
364
|
+
if (pos > bytes.length) throw new Error("truncated string");
|
|
365
|
+
}
|
|
366
|
+
return pos + 1;
|
|
367
|
+
}
|
|
368
|
+
const end = head.next + Number(head.value);
|
|
369
|
+
if (end > bytes.length) throw new Error("truncated string");
|
|
370
|
+
return end;
|
|
371
|
+
}
|
|
372
|
+
case 4:
|
|
373
|
+
case 5: {
|
|
374
|
+
const perEntry = major === 5 ? 2 : 1;
|
|
375
|
+
if (head.value === -1n) {
|
|
376
|
+
let pos = head.next;
|
|
377
|
+
while (bytes[pos] !== 255) for (let i = 0; i < perEntry; i++) pos = skipItem(bytes, pos, depth + 1);
|
|
378
|
+
return pos + 1;
|
|
379
|
+
}
|
|
380
|
+
let pos = head.next;
|
|
381
|
+
const count = Number(head.value) * perEntry;
|
|
382
|
+
if (count > 1e6) throw new Error("container too large");
|
|
383
|
+
for (let i = 0; i < count; i++) pos = skipItem(bytes, pos, depth + 1);
|
|
384
|
+
return pos;
|
|
385
|
+
}
|
|
386
|
+
case 6:
|
|
387
|
+
if (head.value === -1n) throw new Error("malformed tag");
|
|
388
|
+
return skipItem(bytes, head.next, depth + 1);
|
|
389
|
+
case 7:
|
|
390
|
+
if ((initial & 31) === 31) throw new Error("unexpected break");
|
|
391
|
+
if ((initial & 31) === 25) return offset + 3;
|
|
392
|
+
if ((initial & 31) === 26) return offset + 5;
|
|
393
|
+
if ((initial & 31) === 27) return offset + 9;
|
|
394
|
+
return head.next;
|
|
395
|
+
default: throw new Error("unreachable");
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
//#endregion
|
|
399
|
+
//#region src/verify/cosmos.ts
|
|
400
|
+
function verifyCosmosSignature(args) {
|
|
401
|
+
if (args.signature.length !== 64) return failed("signature must be 64 bytes (compact r||s)");
|
|
402
|
+
if (args.publicKey.length !== 33) return failed("publicKey must be 33 bytes (compressed)");
|
|
403
|
+
if (args.expectedPublicKey !== void 0 && !require_shared.equalBytes(args.publicKey, args.expectedPublicKey)) return failed("the reply public key is not the linked account key");
|
|
404
|
+
const digest = args.digest === "keccak256" ? (0, _noble_hashes_sha3.keccak_256)(args.signData) : (0, _noble_hashes_sha2.sha256)(args.signData);
|
|
405
|
+
let ok;
|
|
406
|
+
try {
|
|
407
|
+
ok = _noble_curves_secp256k1.secp256k1.verify(args.signature, digest, args.publicKey);
|
|
408
|
+
} catch (e) {
|
|
409
|
+
return failed(`Cosmos signature could not be checked: ${e.message}`);
|
|
410
|
+
}
|
|
411
|
+
return ok ? verified : failed("the signature does not belong to this account");
|
|
412
|
+
}
|
|
413
|
+
//#endregion
|
|
250
414
|
//#region src/verify/evm.ts
|
|
251
415
|
/** EIP-191: 0x19 || "Ethereum Signed Message:\n" || len(message). */
|
|
252
416
|
function personalSignDigest(message) {
|
|
@@ -302,6 +466,25 @@ function verifySolanaSignature(args) {
|
|
|
302
466
|
return ok ? verified : failed("the signature does not belong to this account");
|
|
303
467
|
}
|
|
304
468
|
//#endregion
|
|
469
|
+
//#region src/verify/sui.ts
|
|
470
|
+
/** BLAKE2b-256 of the intent message (or the given hash) + Ed25519 verification. */
|
|
471
|
+
function verifySuiSignature(args) {
|
|
472
|
+
let digest;
|
|
473
|
+
if (args.messageHash !== void 0) {
|
|
474
|
+
if (args.messageHash.length !== 32) return failed("messageHash must be 32 bytes");
|
|
475
|
+
digest = args.messageHash;
|
|
476
|
+
} else if (args.intentMessage !== void 0) digest = require_sui.suiIntentDigest(args.intentMessage);
|
|
477
|
+
else return failed("provide intentMessage or messageHash");
|
|
478
|
+
if (args.expectedPublicKey !== void 0 && !require_shared.equalBytes(args.publicKey, args.expectedPublicKey)) return failed("the reply public key is not the linked account key");
|
|
479
|
+
let ok;
|
|
480
|
+
try {
|
|
481
|
+
ok = _noble_curves_ed25519.ed25519.verify(args.signature, digest, args.publicKey);
|
|
482
|
+
} catch (e) {
|
|
483
|
+
return failed(`Sui signature could not be checked: ${e.message}`);
|
|
484
|
+
}
|
|
485
|
+
return ok ? verified : failed("the signature does not belong to this account");
|
|
486
|
+
}
|
|
487
|
+
//#endregion
|
|
305
488
|
//#region src/verify/ton-boc.ts
|
|
306
489
|
/**
|
|
307
490
|
* Minimal TON Bag-of-Cells reader + cell representation hash — exactly the
|
|
@@ -573,14 +756,162 @@ function compareWindow(repliedBytes, latestBlock) {
|
|
|
573
756
|
return verified;
|
|
574
757
|
}
|
|
575
758
|
//#endregion
|
|
759
|
+
//#region src/verify/xrp.ts
|
|
760
|
+
/**
|
|
761
|
+
* XRP has no request id — this check IS the binding. The signed binary is
|
|
762
|
+
* split into its canonical fields; `TxnSignature` is removed; the remainder
|
|
763
|
+
* (prefixed with the XRPL signing tag `STX\0`) is hashed with SHA-512-half
|
|
764
|
+
* and the DER signature is verified against `SigningPubKey`, which must also
|
|
765
|
+
* equal the key your request carried.
|
|
766
|
+
*
|
|
767
|
+
* The field walker covers the types Payment-class transactions use; a
|
|
768
|
+
* transaction carrying an exotic field type comes back `checked: false`
|
|
769
|
+
* rather than a false verdict.
|
|
770
|
+
*/
|
|
771
|
+
function verifyXrpSignature(args) {
|
|
772
|
+
let fields;
|
|
773
|
+
try {
|
|
774
|
+
fields = splitFields(args.signedTx);
|
|
775
|
+
} catch (e) {
|
|
776
|
+
const message = e.message;
|
|
777
|
+
if (message === "unsupported-field") return unverifiable("the transaction carries a field type this checker does not walk");
|
|
778
|
+
return failed(`the signed transaction is not readable: ${message}`);
|
|
779
|
+
}
|
|
780
|
+
const signingPubKey = fields.find((f) => f.header === 115);
|
|
781
|
+
const txnSignature = fields.find((f) => f.header === 116);
|
|
782
|
+
if (!signingPubKey || !txnSignature) return failed("the signed transaction is missing SigningPubKey or TxnSignature");
|
|
783
|
+
const expected = require_shared.hexToBytes(args.expectedSigningPubKey);
|
|
784
|
+
if (!require_shared.equalBytes(signingPubKey.value, expected)) return failed(`the transaction was signed with a different key (${require_shared.bytesToHex(signingPubKey.value)})`);
|
|
785
|
+
const payload = require_shared.concatBytes(new Uint8Array([
|
|
786
|
+
83,
|
|
787
|
+
84,
|
|
788
|
+
88,
|
|
789
|
+
0
|
|
790
|
+
]), ...fields.filter((f) => f.header !== 116).map((f) => f.raw));
|
|
791
|
+
const digest = (0, _noble_hashes_sha2.sha512)(payload).slice(0, 32);
|
|
792
|
+
let ok;
|
|
793
|
+
try {
|
|
794
|
+
ok = _noble_curves_secp256k1.secp256k1.verify(_noble_curves_secp256k1.secp256k1.Signature.fromDER(txnSignature.value).toCompactRawBytes(), digest, expected);
|
|
795
|
+
} catch (e) {
|
|
796
|
+
return failed(`XRP signature could not be checked: ${e.message}`);
|
|
797
|
+
}
|
|
798
|
+
return ok ? verified : failed("the signature does not verify against SigningPubKey");
|
|
799
|
+
}
|
|
800
|
+
/** Split a canonical STObject into its top-level fields. */
|
|
801
|
+
function splitFields(bytes) {
|
|
802
|
+
const fields = [];
|
|
803
|
+
let pos = 0;
|
|
804
|
+
while (pos < bytes.length) {
|
|
805
|
+
const field = parseField(bytes, pos);
|
|
806
|
+
fields.push(field.field);
|
|
807
|
+
pos = field.end;
|
|
808
|
+
}
|
|
809
|
+
return fields;
|
|
810
|
+
}
|
|
811
|
+
/** Parse ONE field at `pos`; returns the field and the offset past it. */
|
|
812
|
+
function parseField(bytes, pos) {
|
|
813
|
+
const start = pos;
|
|
814
|
+
const first = bytes[pos++];
|
|
815
|
+
if (first === void 0) throw new Error("truncated");
|
|
816
|
+
let type = first >> 4;
|
|
817
|
+
let fieldCode = first & 15;
|
|
818
|
+
if (type === 0) {
|
|
819
|
+
const t = bytes[pos++];
|
|
820
|
+
if (t === void 0) throw new Error("truncated type");
|
|
821
|
+
type = t;
|
|
822
|
+
}
|
|
823
|
+
if (fieldCode === 0) {
|
|
824
|
+
const f = bytes[pos++];
|
|
825
|
+
if (f === void 0) throw new Error("truncated field code");
|
|
826
|
+
fieldCode = f;
|
|
827
|
+
}
|
|
828
|
+
let valueStart = pos;
|
|
829
|
+
switch (type) {
|
|
830
|
+
case 1:
|
|
831
|
+
pos += 2;
|
|
832
|
+
break;
|
|
833
|
+
case 2:
|
|
834
|
+
pos += 4;
|
|
835
|
+
break;
|
|
836
|
+
case 5:
|
|
837
|
+
pos += 32;
|
|
838
|
+
break;
|
|
839
|
+
case 6: {
|
|
840
|
+
const head = bytes[pos];
|
|
841
|
+
if (head === void 0) throw new Error("truncated amount");
|
|
842
|
+
pos += (head & 128) !== 0 ? 48 : 8;
|
|
843
|
+
break;
|
|
844
|
+
}
|
|
845
|
+
case 7:
|
|
846
|
+
case 8: {
|
|
847
|
+
const vl = readVl(bytes, pos);
|
|
848
|
+
valueStart = vl.next;
|
|
849
|
+
pos = vl.next + vl.length;
|
|
850
|
+
break;
|
|
851
|
+
}
|
|
852
|
+
case 14:
|
|
853
|
+
while (bytes[pos] !== 225) {
|
|
854
|
+
if (pos >= bytes.length) throw new Error("unterminated inner object");
|
|
855
|
+
pos = parseField(bytes, pos).end;
|
|
856
|
+
}
|
|
857
|
+
pos += 1;
|
|
858
|
+
break;
|
|
859
|
+
case 15:
|
|
860
|
+
while (bytes[pos] !== 241) {
|
|
861
|
+
if (pos >= bytes.length) throw new Error("unterminated array");
|
|
862
|
+
pos = parseField(bytes, pos).end;
|
|
863
|
+
}
|
|
864
|
+
pos += 1;
|
|
865
|
+
break;
|
|
866
|
+
default: throw new Error("unsupported-field");
|
|
867
|
+
}
|
|
868
|
+
if (pos > bytes.length) throw new Error("truncated field");
|
|
869
|
+
return {
|
|
870
|
+
field: {
|
|
871
|
+
header: type << 4 | (fieldCode <= 15 ? fieldCode : 0),
|
|
872
|
+
value: bytes.slice(valueStart, pos),
|
|
873
|
+
raw: bytes.slice(start, pos)
|
|
874
|
+
},
|
|
875
|
+
end: pos
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
/** XRPL variable-length prefix. */
|
|
879
|
+
function readVl(bytes, pos) {
|
|
880
|
+
const b1 = bytes[pos];
|
|
881
|
+
if (b1 === void 0) throw new Error("truncated length");
|
|
882
|
+
if (b1 <= 192) return {
|
|
883
|
+
length: b1,
|
|
884
|
+
next: pos + 1
|
|
885
|
+
};
|
|
886
|
+
if (b1 <= 240) {
|
|
887
|
+
const b2 = bytes[pos + 1];
|
|
888
|
+
if (b2 === void 0) throw new Error("truncated length");
|
|
889
|
+
return {
|
|
890
|
+
length: 193 + (b1 - 193) * 256 + b2,
|
|
891
|
+
next: pos + 2
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
const b2 = bytes[pos + 1];
|
|
895
|
+
const b3 = bytes[pos + 2];
|
|
896
|
+
if (b2 === void 0 || b3 === void 0) throw new Error("truncated length");
|
|
897
|
+
return {
|
|
898
|
+
length: 12481 + (b1 - 241) * 65536 + b2 * 256 + b3,
|
|
899
|
+
next: pos + 3
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
//#endregion
|
|
576
903
|
exports.PsbtInputType = PsbtInputType;
|
|
577
904
|
exports.bocRootHash = bocRootHash;
|
|
578
905
|
exports.parsePsbt = parsePsbt;
|
|
579
906
|
exports.verifyBtcMessageHeader = verifyBtcMessageHeader;
|
|
907
|
+
exports.verifyCardanoSignature = verifyCardanoSignature;
|
|
908
|
+
exports.verifyCosmosSignature = verifyCosmosSignature;
|
|
580
909
|
exports.verifyEvmSignature = verifyEvmSignature;
|
|
581
910
|
exports.verifySignedPsbt = verifySignedPsbt;
|
|
582
911
|
exports.verifySolanaSignature = verifySolanaSignature;
|
|
912
|
+
exports.verifySuiSignature = verifySuiSignature;
|
|
583
913
|
exports.verifyTonSignature = verifyTonSignature;
|
|
584
914
|
exports.verifyTronSignature = verifyTronSignature;
|
|
915
|
+
exports.verifyXrpSignature = verifyXrpSignature;
|
|
585
916
|
|
|
586
917
|
//# sourceMappingURL=verify.cjs.map
|