@hwlt/era-connect 0.3.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 (131) hide show
  1. package/README.md +8 -14
  2. package/bch/package.json +6 -0
  3. package/cosmos/package.json +6 -0
  4. package/dist/bch-CK6dKGQA.d.ts +74 -0
  5. package/dist/bch-CpLACx0j.cjs +139 -0
  6. package/dist/bch-CpLACx0j.cjs.map +1 -0
  7. package/dist/bch-DHsIVJqK.d.cts +74 -0
  8. package/dist/bch-dMESlQfv.js +134 -0
  9. package/dist/bch-dMESlQfv.js.map +1 -0
  10. package/dist/bch.cjs +13 -0
  11. package/dist/bch.d.cts +26 -0
  12. package/dist/bch.d.ts +26 -0
  13. package/dist/bch.js +4 -0
  14. package/dist/{btc-VyJKXq7d.js → btc-BmVgvvBd.js} +17 -8
  15. package/dist/btc-BmVgvvBd.js.map +1 -0
  16. package/dist/{btc-Fr6Jz4Fi.cjs → btc-BxNww6kW.cjs} +20 -11
  17. package/dist/btc-BxNww6kW.cjs.map +1 -0
  18. package/dist/{btc-DfQ0q79G.d.ts → btc-uzt0uC-Q.d.ts} +15 -4
  19. package/dist/{btc-Dn6_Y12c.d.cts → btc-wogJ4INA.d.cts} +15 -4
  20. package/dist/btc.cjs +2 -2
  21. package/dist/btc.d.cts +1 -1
  22. package/dist/btc.d.ts +1 -1
  23. package/dist/btc.js +2 -2
  24. package/dist/{cardano-yuOygqwp.js → cardano-BCT55gwf.js} +3 -2
  25. package/dist/{cardano-yuOygqwp.js.map → cardano-BCT55gwf.js.map} +1 -1
  26. package/dist/{cardano-DP6U_K1J.cjs → cardano-CzYswGzK.cjs} +5 -4
  27. package/dist/{cardano-DP6U_K1J.cjs.map → cardano-CzYswGzK.cjs.map} +1 -1
  28. package/dist/cardano.cjs +2 -2
  29. package/dist/cardano.js +2 -2
  30. package/dist/cashaddr-BIzawizX.js +134 -0
  31. package/dist/cashaddr-BIzawizX.js.map +1 -0
  32. package/dist/cashaddr-Ci0_8ITN.cjs +151 -0
  33. package/dist/cashaddr-Ci0_8ITN.cjs.map +1 -0
  34. package/dist/cosmos-BYrhIqRk.d.cts +77 -0
  35. package/dist/cosmos-DDsgtUki.cjs +113 -0
  36. package/dist/cosmos-DDsgtUki.cjs.map +1 -0
  37. package/dist/cosmos-DqyjA6lg.d.ts +77 -0
  38. package/dist/cosmos-jUHNxgWC.js +102 -0
  39. package/dist/cosmos-jUHNxgWC.js.map +1 -0
  40. package/dist/cosmos.cjs +10 -0
  41. package/dist/cosmos.d.cts +3 -0
  42. package/dist/cosmos.d.ts +3 -0
  43. package/dist/cosmos.js +3 -0
  44. package/dist/{derive-C4JdycUh.js → derive-00JUOkmn.js} +14 -3
  45. package/dist/derive-00JUOkmn.js.map +1 -0
  46. package/dist/{derive-CuILJRPT.cjs → derive-BuNsfWlg.cjs} +25 -2
  47. package/dist/derive-BuNsfWlg.cjs.map +1 -0
  48. package/dist/{evm-kJb3-oiR.js → evm-CI1cuZsp.js} +3 -2
  49. package/dist/{evm-kJb3-oiR.js.map → evm-CI1cuZsp.js.map} +1 -1
  50. package/dist/{evm-BHj_2OTG.cjs → evm-yfKOc2dy.cjs} +6 -5
  51. package/dist/{evm-BHj_2OTG.cjs.map → evm-yfKOc2dy.cjs.map} +1 -1
  52. package/dist/evm.cjs +2 -2
  53. package/dist/evm.js +2 -2
  54. package/dist/gzip-CLzDX7AZ.cjs +79 -0
  55. package/dist/gzip-CLzDX7AZ.cjs.map +1 -0
  56. package/dist/gzip-DyZLtgJJ.js +68 -0
  57. package/dist/gzip-DyZLtgJJ.js.map +1 -0
  58. package/dist/index.cjs +120 -31
  59. package/dist/index.cjs.map +1 -1
  60. package/dist/index.d.cts +50 -3
  61. package/dist/index.d.ts +50 -3
  62. package/dist/index.js +90 -9
  63. package/dist/index.js.map +1 -1
  64. package/dist/keypath-Bvv_cfHt.js +75 -0
  65. package/dist/keypath-Bvv_cfHt.js.map +1 -0
  66. package/dist/keypath-pzm_YIfN.cjs +116 -0
  67. package/dist/keypath-pzm_YIfN.cjs.map +1 -0
  68. package/dist/{messages-17Oup0-Z.js → messages--XbVef_k.js} +39 -3
  69. package/dist/messages--XbVef_k.js.map +1 -0
  70. package/dist/{messages-BzcdWlg1.cjs → messages-orAQ52CI.cjs} +44 -2
  71. package/dist/messages-orAQ52CI.cjs.map +1 -0
  72. package/dist/{shared-B8Wc7ViU.js → shared-Bbgejrus.js} +2 -73
  73. package/dist/shared-Bbgejrus.js.map +1 -0
  74. package/dist/{shared-nISrEktU.cjs → shared-Cu2yynP9.cjs} +13 -114
  75. package/dist/shared-Cu2yynP9.cjs.map +1 -0
  76. package/dist/{solana-DdEn24X4.cjs → solana-BoQBy0hu.cjs} +6 -5
  77. package/dist/{solana-DdEn24X4.cjs.map → solana-BoQBy0hu.cjs.map} +1 -1
  78. package/dist/{solana-C7JQEAec.js → solana-BukH3AI3.js} +3 -2
  79. package/dist/{solana-C7JQEAec.js.map → solana-BukH3AI3.js.map} +1 -1
  80. package/dist/solana.cjs +2 -2
  81. package/dist/solana.js +2 -2
  82. package/dist/sui-6WX6VPlW.d.cts +49 -0
  83. package/dist/sui-BtbPG6Xt.js +71 -0
  84. package/dist/sui-BtbPG6Xt.js.map +1 -0
  85. package/dist/sui-CYRn331O.cjs +82 -0
  86. package/dist/sui-CYRn331O.cjs.map +1 -0
  87. package/dist/sui-DI0ruW7E.d.ts +49 -0
  88. package/dist/sui.cjs +10 -0
  89. package/dist/sui.d.cts +3 -0
  90. package/dist/sui.d.ts +3 -0
  91. package/dist/sui.js +3 -0
  92. package/dist/{ton-5Uvi5ifg.js → ton-BSPKU5B9.js} +3 -2
  93. package/dist/{ton-5Uvi5ifg.js.map → ton-BSPKU5B9.js.map} +1 -1
  94. package/dist/{ton-DUJGXdGa.cjs → ton-CI2s9puH.cjs} +6 -5
  95. package/dist/{ton-DUJGXdGa.cjs.map → ton-CI2s9puH.cjs.map} +1 -1
  96. package/dist/ton.cjs +2 -2
  97. package/dist/ton.js +2 -2
  98. package/dist/{tron-Bo9HnvVE.js → tron-BpUEYTPT.js} +5 -67
  99. package/dist/tron-BpUEYTPT.js.map +1 -0
  100. package/dist/{tron-CQIEqjCA.cjs → tron-DYPOg5cm.cjs} +10 -72
  101. package/dist/{tron-Bo9HnvVE.js.map → tron-DYPOg5cm.cjs.map} +1 -1
  102. package/dist/tron.cjs +3 -3
  103. package/dist/tron.js +3 -3
  104. package/dist/verify.cjs +414 -24
  105. package/dist/verify.cjs.map +1 -1
  106. package/dist/verify.d.cts +120 -1
  107. package/dist/verify.d.ts +120 -1
  108. package/dist/verify.js +408 -24
  109. package/dist/verify.js.map +1 -1
  110. package/dist/xrp-BXAeK4iH.d.cts +32 -0
  111. package/dist/xrp-BrHXUnX5.cjs +52 -0
  112. package/dist/xrp-BrHXUnX5.cjs.map +1 -0
  113. package/dist/xrp-C8LJO5b-.js +47 -0
  114. package/dist/xrp-C8LJO5b-.js.map +1 -0
  115. package/dist/xrp-DqCXGYEk.d.ts +32 -0
  116. package/dist/xrp.cjs +9 -0
  117. package/dist/xrp.d.cts +3 -0
  118. package/dist/xrp.d.ts +3 -0
  119. package/dist/xrp.js +3 -0
  120. package/package.json +49 -1
  121. package/sui/package.json +6 -0
  122. package/xrp/package.json +6 -0
  123. package/dist/btc-Fr6Jz4Fi.cjs.map +0 -1
  124. package/dist/btc-VyJKXq7d.js.map +0 -1
  125. package/dist/derive-C4JdycUh.js.map +0 -1
  126. package/dist/derive-CuILJRPT.cjs.map +0 -1
  127. package/dist/messages-17Oup0-Z.js.map +0 -1
  128. package/dist/messages-BzcdWlg1.cjs.map +0 -1
  129. package/dist/shared-B8Wc7ViU.js.map +0 -1
  130. package/dist/shared-nISrEktU.cjs.map +0 -1
  131. package/dist/tron-CQIEqjCA.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"verify.js","names":["err"],"sources":["../src/verify/psbt-reader.ts","../src/verify/result.ts","../src/verify/btc.ts","../src/verify/cardano.ts","../src/verify/evm.ts","../src/verify/solana.ts","../src/verify/ton-boc.ts","../src/verify/ton.ts","../src/verify/tron.ts"],"sourcesContent":["import { EraSdkError } from '../core/errors';\n\n/**\n * Minimal PSBT v0 (BIP-174) reader — just enough structure for the\n * verification guard: the global unsigned transaction (verbatim slice, never\n * re-serialized), the PSBT version, and per-input key/value maps.\n *\n * Hardened: compact-size lengths bounds-checked before slicing, duplicate\n * keys within one map refused (a hostile PSBT carrying two final scriptSigs\n * for one input must not survive parsing).\n */\n\nexport interface PsbtKeyValue {\n readonly keyType: number;\n readonly keyData: Uint8Array;\n readonly value: Uint8Array;\n}\n\nexport interface ParsedPsbt {\n /** The global UNSIGNED_TX value, verbatim. */\n readonly unsignedTx: Uint8Array;\n /** Global PSBT_GLOBAL_VERSION (0xFB) if present; v0 files normally omit it. */\n readonly version: number;\n readonly inputs: readonly (readonly PsbtKeyValue[])[];\n readonly outputs: readonly (readonly PsbtKeyValue[])[];\n}\n\nconst MAGIC = [0x70, 0x73, 0x62, 0x74, 0xff]; // \"psbt\\xff\"\n\nexport const PsbtInputType = {\n partialSig: 0x02,\n finalScriptSig: 0x07,\n finalScriptWitness: 0x08,\n taprootKeySpendSignature: 0x13,\n taprootScriptSpendSignature: 0x14,\n} as const;\n\nfunction err(message: string): EraSdkError {\n return new EraSdkError('malformed-reply', `psbt: ${message}`);\n}\n\nclass Reader {\n offset = 0;\n constructor(readonly bytes: Uint8Array) {}\n\n get remaining(): number {\n return this.bytes.length - this.offset;\n }\n\n u8(): number {\n const b = this.bytes[this.offset];\n if (b === undefined) throw err('truncated');\n this.offset += 1;\n return b;\n }\n\n /** Bitcoin compact-size integer, MINIMAL encoding required (as consensus does). */\n compactSize(): number {\n const first = this.u8();\n if (first < 0xfd) return first;\n let width: number;\n let minimum: bigint;\n if (first === 0xfd) {\n width = 2;\n minimum = 0xfdn;\n } else if (first === 0xfe) {\n width = 4;\n minimum = 0x10000n;\n } else {\n width = 8;\n minimum = 0x100000000n;\n }\n let value = 0n;\n for (let i = 0; i < width; i++) value |= BigInt(this.u8()) << BigInt(8 * i);\n if (value < minimum) throw err('non-minimal compact-size encoding');\n if (value > BigInt(Number.MAX_SAFE_INTEGER)) throw err('length exceeds safe range');\n return Number(value);\n }\n\n take(length: number): Uint8Array {\n if (length > this.remaining) throw err('length exceeds input');\n const out = this.bytes.slice(this.offset, this.offset + length);\n this.offset += length;\n return out;\n }\n}\n\n/** Read one key/value map (ends at the 0x00 separator). */\nfunction readMap(reader: Reader): PsbtKeyValue[] {\n const entries: PsbtKeyValue[] = [];\n const seen = new Set<string>();\n for (;;) {\n const keyLength = reader.compactSize();\n if (keyLength === 0) return entries;\n const key = reader.take(keyLength);\n const value = reader.take(reader.compactSize());\n const keyId = Array.from(key)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n if (seen.has(keyId)) throw err('duplicate key within one map');\n seen.add(keyId);\n entries.push({ keyType: key[0]!, keyData: key.slice(1), value });\n }\n}\n\n/** Count of inputs/outputs in a (non-witness) unsigned transaction. */\nfunction countTxInputsOutputs(tx: Uint8Array): { inputs: number; outputs: number } {\n const reader = new Reader(tx);\n reader.take(4); // version\n const inputs = reader.compactSize();\n if (inputs === 0) {\n // A zero here would be a segwit marker — the PSBT unsigned tx must not\n // carry witness data, so this is not a transaction we can count.\n throw err('unsigned transaction has zero inputs (or carries witness data)');\n }\n for (let i = 0; i < inputs; i++) {\n reader.take(32 + 4); // prevout\n reader.take(reader.compactSize()); // scriptSig (empty in a PSBT)\n reader.take(4); // sequence\n }\n const outputs = reader.compactSize();\n for (let i = 0; i < outputs; i++) {\n reader.take(8); // amount\n reader.take(reader.compactSize()); // scriptPubKey\n }\n reader.take(4); // locktime\n if (reader.remaining !== 0) throw err('trailing bytes after the unsigned transaction');\n return { inputs, outputs };\n}\n\nexport function parsePsbt(bytes: Uint8Array): ParsedPsbt {\n const reader = new Reader(bytes);\n for (const expected of MAGIC) {\n if (reader.u8() !== expected) throw err('bad magic');\n }\n const globalMap = readMap(reader);\n\n let unsignedTx: Uint8Array | null = null;\n let version = 0;\n for (const entry of globalMap) {\n if (entry.keyType === 0x00 && entry.keyData.length === 0) unsignedTx = entry.value;\n if (entry.keyType === 0xfb && entry.keyData.length === 0) {\n if (entry.value.length !== 4) throw err('bad version field');\n version =\n (entry.value[0]! |\n (entry.value[1]! << 8) |\n (entry.value[2]! << 16) |\n (entry.value[3]! << 24)) >>>\n 0;\n }\n }\n if (unsignedTx === null) {\n // The device's signer relies on the global UNSIGNED_TX that only PSBT v0\n // carries; its absence means v2 (or not a PSBT at all).\n throw err('no global unsigned transaction — not a PSBT v0');\n }\n if (version !== 0) throw err(`unsupported PSBT version ${version}`);\n\n const counts = countTxInputsOutputs(unsignedTx);\n const inputs: PsbtKeyValue[][] = [];\n for (let i = 0; i < counts.inputs; i++) inputs.push(readMap(reader));\n const outputs: PsbtKeyValue[][] = [];\n for (let i = 0; i < counts.outputs; i++) outputs.push(readMap(reader));\n if (reader.remaining !== 0) throw err('trailing bytes after the output maps');\n\n return { unsignedTx, version, inputs, outputs };\n}\n\nexport function inputEntries(\n psbt: ParsedPsbt,\n index: number,\n keyType: number,\n): readonly PsbtKeyValue[] {\n return (psbt.inputs[index] ?? []).filter((e) => e.keyType === keyType);\n}\n\nexport function inputHas(psbt: ParsedPsbt, index: number, keyType: number): boolean {\n return inputEntries(psbt, index, keyType).length > 0;\n}\n","/** Outcome of a verification helper. Helpers return, never throw, on mismatches. */\nexport type VerifyResult =\n /** Verified cryptographically / byte-for-byte. */\n | { readonly ok: true; readonly checked: true }\n /**\n * Nothing client-side is verifiable for this input (EIP-712 typed data:\n * the digest is the hash of the structure, which only the device computes).\n * The UR-type pin and the request-id echo are the whole binding.\n */\n | { readonly ok: true; readonly checked: false; readonly reason: string }\n | { readonly ok: false; readonly reason: string };\n\nexport const verified: VerifyResult = { ok: true, checked: true };\nexport const failed = (reason: string): VerifyResult => ({ ok: false, reason });\nexport const unverifiable = (reason: string): VerifyResult => ({\n ok: true,\n checked: false,\n reason,\n});\n","import { equalBytes } from '../core/bytes';\nimport { EraSdkError } from '../core/errors';\nimport type { ParsedPsbt } from './psbt-reader';\nimport { inputEntries, inputHas, PsbtInputType, parsePsbt } from './psbt-reader';\nimport type { VerifyResult } from './result';\nimport { failed, verified } from './result';\n\nexport interface VerifySignedPsbtArgs {\n /** The PSBT you sent to the device. */\n readonly sentPsbt: Uint8Array;\n /** The PSBT the device returned. */\n readonly signedPsbt: Uint8Array;\n /**\n * true (default) on flows where every input is yours (a plain send): a\n * reply that signed only part of the transaction is refused here with a\n * reason instead of failing later inside a finalizer. Set false for dApp\n * `signPsbt` hand-backs, where a PSBT legitimately carries inputs you\n * cannot sign.\n */\n readonly requireEveryInputSigned?: boolean;\n}\n\n/**\n * The `crypto-psbt` reply carries NO request id — this comparison IS the\n * anti-replay binding for Bitcoin. It is not optional.\n *\n * The unsigned transaction is compared byte for byte, which pins the input\n * set and order, the outputs, their amounts, the version and the locktime in\n * one shot — and therefore the txid. The device only ADDS per-input\n * signature fields, so a legitimate reply always matches.\n */\nexport function verifySignedPsbt(args: VerifySignedPsbtArgs): VerifyResult {\n let sent: ParsedPsbt;\n let signed: ParsedPsbt;\n try {\n sent = parsePsbt(args.sentPsbt);\n } catch (e) {\n return failed(`the PSBT we sent is not readable: ${message(e)}`);\n }\n try {\n signed = parsePsbt(args.signedPsbt);\n } catch (e) {\n return failed(`the PSBT the device returned is not readable: ${message(e)}`);\n }\n\n if (!equalBytes(sent.unsignedTx, signed.unsignedTx)) {\n return failed('the returned PSBT is a different transaction from the one approved');\n }\n\n // A finalized field carries the COMPLETE scriptSig/witness that will be\n // broadcast, and the unsigned-tx comparison above does not cover it (it\n // lives per input, the unsigned tx in the global map). An input that comes\n // back finalized must have been SENT that way, with byte-identical\n // values — the device echoes these fields, it never authors them.\n const finalizedTypes = [PsbtInputType.finalScriptSig, PsbtInputType.finalScriptWitness];\n for (let i = 0; i < signed.inputs.length; i++) {\n for (const type of finalizedTypes) {\n if (!inputHas(signed, i, type)) continue;\n if (!inputHas(sent, i, type)) {\n return failed(\n `input ${i} came back finalized (type 0x${type.toString(16)}) and was not sent that way — the script it would broadcast is not ours`,\n );\n }\n const a = inputEntries(sent, i, type);\n const b = inputEntries(signed, i, type);\n if (a.length !== b.length || !a.every((entry, k) => equalBytes(entry.value, b[k]!.value))) {\n return failed(\n `input ${i} came back with a different finalized script than the one we sent`,\n );\n }\n }\n }\n\n const isSigned = (i: number): boolean =>\n inputHas(signed, i, PsbtInputType.partialSig) ||\n inputHas(signed, i, PsbtInputType.taprootKeySpendSignature) ||\n inputHas(signed, i, PsbtInputType.taprootScriptSpendSignature);\n\n const indexes = signed.inputs.map((_, i) => i);\n if (args.requireEveryInputSigned ?? true) {\n if (!indexes.every(isSigned)) {\n return failed('the device signed only part of the transaction');\n }\n } else if (!indexes.some(isSigned)) {\n return failed('the returned PSBT carries no signature');\n }\n return verified;\n}\n\nexport interface VerifyBtcMessageHeaderArgs {\n /** The address the request asked the device to sign with. */\n readonly address: string;\n /** The raw 65-byte BIP-137 signature. */\n readonly signature: Uint8Array;\n}\n\n/**\n * BIP-137: the recovery header names the address type a verifier derives\n * before comparing. A header of the wrong range produces a signature that\n * LOOKS fine (65 bytes, valid base64) but fails every verifier downstream —\n * this check is the only place that difference is visible.\n */\nexport function verifyBtcMessageHeader(args: VerifyBtcMessageHeaderArgs): VerifyResult {\n if (args.signature.length === 0) {\n return failed('empty signature');\n }\n const header = args.signature[0]!;\n const range = headerRangeFor(args.address);\n if (range === null) {\n return {\n ok: true,\n checked: false,\n reason: 'address kind has no BIP-137 header range to check against',\n };\n }\n if (header >= range.low && header <= range.high) return verified;\n return failed(\n `recovery header ${header} does not match a ${range.label} address ` +\n `(BIP-137 expects ${range.low}..${range.high}); this signature would not verify against the address it was asked to sign for`,\n );\n}\n\ninterface HeaderRange {\n readonly low: number;\n readonly high: number;\n readonly label: string;\n}\n\nfunction headerRangeFor(address: string): HeaderRange | null {\n const a = address.toLowerCase();\n if (a.startsWith('bc1q') || a.startsWith('tb1q') || a.startsWith('bcrt1q')) {\n return { low: 39, high: 42, label: 'native segwit (P2WPKH)' };\n }\n if (a.startsWith('bc1p') || a.startsWith('tb1p') || a.startsWith('bcrt1p')) {\n return null; // Taproot: BIP-137 does not cover it (BIP-322 is the scheme).\n }\n // Base58 kinds matched on SHAPE, not first character alone — a guard that\n // invents a range for a string it does not understand is worse than one\n // that declines to judge.\n if (looksBase58(address)) {\n if (address.startsWith('3') || address.startsWith('2')) {\n return { low: 35, high: 38, label: 'P2SH (nested segwit)' };\n }\n if (address.startsWith('1') || address.startsWith('m') || address.startsWith('n')) {\n // Both the uncompressed and compressed P2PKH ranges — which one is\n // right depends on the key the device used, which we do not know.\n return { low: 27, high: 34, label: 'legacy P2PKH' };\n }\n }\n return null;\n}\n\nfunction looksBase58(address: string): boolean {\n return address.length >= 26 && address.length <= 35 && /^[1-9A-HJ-NP-Za-km-z]+$/.test(address);\n}\n\nfunction message(e: unknown): string {\n return e instanceof EraSdkError || e instanceof Error ? e.message : String(e);\n}\n","import { ed25519 } from '@noble/curves/ed25519';\nimport { blake2b } from '@noble/hashes/blake2b';\nimport { cardanoSoftDerivePath } from '../accounts/derive';\nimport type { CardanoWitness } from '../chains/cardano';\nimport { parseWitnessSet } from '../chains/cardano';\nimport { bytesToHex, equalBytes } from '../core/bytes';\nimport { parsePath } from '../registry/keypath';\nimport type { VerifyResult } from './result';\nimport { failed, verified } from './result';\n\nexport interface VerifyCardanoSignatureArgs {\n /** The exact bytes the request carried in `signData` (the full tx CBOR array). */\n readonly signData: Uint8Array;\n /** The reply's witness set (or already-parsed witnesses). */\n readonly witnessSet?: Uint8Array;\n readonly witnesses?: readonly CardanoWitness[];\n /**\n * Optional but STRONGLY recommended — binds the witnesses to YOUR wallet:\n * the linked account's key material plus the signing paths your request\n * carried. Without it the check only proves internal consistency of the\n * reply (any key could have produced a matching pair).\n */\n readonly account?: {\n /** From `accounts.cardano()`: the account xpub halves and its path. */\n readonly publicKey: Uint8Array;\n readonly chainCode: Uint8Array;\n readonly accountPath: string;\n };\n /** The unique signing paths of the request (utxos + certKeys), e.g. `m/1852'/1815'/0'/0/0`. */\n readonly signerPaths?: readonly string[];\n}\n\n/**\n * Recompute the digest the device signs — BLAKE2b-256 of the ENCODED FIRST\n * ELEMENT of the transaction CBOR array (the tx body) — and verify every\n * `[vkey, signature]` pair against it. With `account` + `signerPaths`, the\n * vkeys are additionally required to be exactly the soft-derived children of\n * YOUR linked account at the request's own paths.\n */\nexport function verifyCardanoSignature(args: VerifyCardanoSignatureArgs): VerifyResult {\n let witnesses: readonly CardanoWitness[];\n try {\n witnesses = args.witnesses ?? (args.witnessSet ? parseWitnessSet(args.witnessSet) : []);\n } catch (e) {\n return failed(`witness set is not readable: ${(e as Error).message}`);\n }\n if (witnesses.length === 0) return failed('no witnesses to verify');\n\n let digest: Uint8Array;\n try {\n digest = blake2b(firstArrayItemBytes(args.signData), { dkLen: 32 });\n } catch (e) {\n return failed(`signData is not a readable transaction array: ${(e as Error).message}`);\n }\n\n for (const witness of witnesses) {\n let ok: boolean;\n try {\n ok = ed25519.verify(witness.signature, digest, witness.vkey);\n } catch (e) {\n return failed(`Cardano signature could not be checked: ${(e as Error).message}`);\n }\n if (!ok) return failed('a witness signature does not verify against its own vkey');\n }\n\n if (args.account && args.signerPaths && args.signerPaths.length > 0) {\n const accountLevels = parsePath(args.account.accountPath);\n const expected = new Map<string, string>(); // vkey hex -> path\n for (const path of new Set(args.signerPaths)) {\n const levels = parsePath(path);\n if (\n levels.length !== accountLevels.length + 2 ||\n !accountLevels.every(\n (l, i) => levels[i]!.index === l.index && levels[i]!.hardened === l.hardened,\n ) ||\n levels.slice(accountLevels.length).some((l) => l.hardened)\n ) {\n return failed(\n `signer path ${path} does not extend the account path with two soft components`,\n );\n }\n const tail = levels.slice(accountLevels.length).map((l) => l.index);\n const vkey = cardanoSoftDerivePath(args.account.publicKey, args.account.chainCode, tail);\n expected.set(bytesToHex(vkey), path);\n }\n // Every requested path must have produced a witness…\n for (const [vkeyHex, path] of expected) {\n if (!witnesses.some((w) => bytesToHex(w.vkey) === vkeyHex)) {\n return failed(`no witness for the requested signer path ${path}`);\n }\n }\n // …and every witness must belong to a requested path (no foreign keys).\n for (const witness of witnesses) {\n if (!expected.has(bytesToHex(witness.vkey))) {\n return failed('the witness set carries a key your request did not ask for');\n }\n }\n }\n return verified;\n}\n\n// ---------------------------------------------------------------------------\n// CBOR item walker: the encoded extent of the first element of a CBOR array.\n// Supports definite AND indefinite lengths (wallet-produced tx CBOR may use\n// either), with depth/size hardening.\n// ---------------------------------------------------------------------------\n\nexport function firstArrayItemBytes(bytes: Uint8Array): Uint8Array {\n const top = bytes[0];\n if (top === undefined) throw new Error('empty input');\n const major = top >> 5;\n if (major !== 4) throw new Error('not a CBOR array');\n let start: number;\n if ((top & 0x1f) === 31) {\n start = 1; // indefinite array\n } else {\n const head = readHead(bytes, 0);\n if (head.value === 0n) throw new Error('transaction array is empty');\n start = head.next;\n }\n const end = skipItem(bytes, start, 0);\n return bytes.slice(start, end);\n}\n\nfunction readHead(bytes: Uint8Array, offset: number): { value: bigint; next: number } {\n const initial = bytes[offset];\n if (initial === undefined) throw new Error('truncated');\n const info = initial & 0x1f;\n if (info < 24) return { value: BigInt(info), next: offset + 1 };\n if (info === 31) return { value: -1n, next: offset + 1 }; // indefinite marker\n let width: number;\n if (info === 24) width = 1;\n else if (info === 25) width = 2;\n else if (info === 26) width = 4;\n else if (info === 27) width = 8;\n else throw new Error('reserved length encoding');\n let value = 0n;\n for (let i = 0; i < width; i++) {\n const b = bytes[offset + 1 + i];\n if (b === undefined) throw new Error('truncated');\n value = (value << 8n) | BigInt(b);\n }\n return { value, next: offset + 1 + width };\n}\n\n/** Returns the offset just past the item starting at `offset`. */\nfunction skipItem(bytes: Uint8Array, offset: number, depth: number): number {\n if (depth > 32) throw new Error('nesting too deep');\n const initial = bytes[offset];\n if (initial === undefined) throw new Error('truncated');\n const major = initial >> 5;\n const head = readHead(bytes, offset);\n\n switch (major) {\n case 0:\n case 1:\n if (head.value === -1n) throw new Error('malformed integer');\n return head.next;\n case 2:\n case 3: {\n if (head.value === -1n) {\n // Indefinite string: chunks until 0xFF.\n let pos = head.next;\n while (bytes[pos] !== 0xff) {\n const chunk = readHead(bytes, pos);\n if (chunk.value < 0n) throw new Error('malformed chunk');\n pos = chunk.next + Number(chunk.value);\n if (pos > bytes.length) throw new Error('truncated string');\n }\n return pos + 1;\n }\n const end = head.next + Number(head.value);\n if (end > bytes.length) throw new Error('truncated string');\n return end;\n }\n case 4:\n case 5: {\n const perEntry = major === 5 ? 2 : 1;\n if (head.value === -1n) {\n let pos = head.next;\n while (bytes[pos] !== 0xff) {\n for (let i = 0; i < perEntry; i++) pos = skipItem(bytes, pos, depth + 1);\n }\n return pos + 1;\n }\n let pos = head.next;\n const count = Number(head.value) * perEntry;\n if (count > 1_000_000) throw new Error('container too large');\n for (let i = 0; i < count; i++) pos = skipItem(bytes, pos, depth + 1);\n return pos;\n }\n case 6:\n if (head.value === -1n) throw new Error('malformed tag');\n return skipItem(bytes, head.next, depth + 1);\n case 7:\n if ((initial & 0x1f) === 31) throw new Error('unexpected break');\n if ((initial & 0x1f) === 25) return offset + 3;\n if ((initial & 0x1f) === 26) return offset + 5;\n if ((initial & 0x1f) === 27) return offset + 9;\n return head.next;\n default:\n throw new Error('unreachable');\n }\n}\n","import { secp256k1 } from '@noble/curves/secp256k1';\nimport { keccak_256 } from '@noble/hashes/sha3';\nimport { EvmDataType, foldRecoveryId } from '../chains/evm';\nimport { bytesToHex, concatBytes, equalBytes, hexToBytes, utf8Encode } from '../core/bytes';\nimport type { VerifyResult } from './result';\nimport { failed, unverifiable, verified } from './result';\n\nexport interface VerifyEvmSignatureArgs {\n /** The exact bytes the request carried in `signData`. */\n readonly signData: Uint8Array;\n readonly dataType: EvmDataType;\n /** Raw `r || s || v` from the reply (65+ bytes; multi-byte legacy `v` handled). */\n readonly signature: Uint8Array;\n /** The signer address the request was built for. */\n readonly address: Uint8Array | `0x${string}`;\n /**\n * Optional: the signing payload re-derived from the transaction you are\n * ABOUT TO BROADCAST. Recovering against `signData` alone proves the device\n * signed something you asked for — this closes the second half: that it is\n * the transaction still in your hands (payloads can legitimately change\n * between build and send, e.g. a blockhash refresh in your own state).\n */\n readonly reEncodedSignData?: Uint8Array;\n}\n\n/** EIP-191: 0x19 || \"Ethereum Signed Message:\\n\" || len(message). */\nfunction personalSignDigest(message: Uint8Array): Uint8Array {\n const prefix = utf8Encode(`Ethereum Signed Message:\\n${message.length}`);\n return keccak_256(concatBytes(new Uint8Array([0x19]), prefix, message));\n}\n\n/**\n * \"Did the device sign exactly what I sent, with the key I expected?\"\n * keccak digest + public-key recovery; the recovered address must equal the\n * request's. Run it before broadcasting.\n */\nexport function verifyEvmSignature(args: VerifyEvmSignatureArgs): VerifyResult {\n if (args.signature.length < 65) {\n return failed('signature is shorter than 65 bytes');\n }\n if (args.reEncodedSignData !== undefined && !equalBytes(args.reEncodedSignData, args.signData)) {\n return failed('the transaction to broadcast is not the one the device signed');\n }\n\n let digest: Uint8Array;\n switch (args.dataType) {\n case EvmDataType.transaction:\n case EvmDataType.typedTransaction:\n digest = keccak_256(args.signData);\n break;\n case EvmDataType.personalMessage:\n digest = personalSignDigest(args.signData);\n break;\n case EvmDataType.typedData:\n return unverifiable(\n 'EIP-712: the digest is the hash of the structure, computed only on the device',\n );\n default:\n return failed(`unknown dataType ${args.dataType satisfies never}`);\n }\n\n let vBig = 0n;\n for (const b of args.signature.slice(64)) vBig = (vBig << 8n) | BigInt(b);\n const recoveryId = foldRecoveryId(vBig);\n if (recoveryId !== 0 && recoveryId !== 1) {\n return failed('implausible recovery value');\n }\n\n let recovered: Uint8Array;\n try {\n const point = secp256k1.Signature.fromCompact(args.signature.slice(0, 64))\n .addRecoveryBit(recoveryId)\n .recoverPublicKey(digest);\n recovered = keccak_256(point.toRawBytes(false).slice(1)).slice(12);\n } catch (e) {\n return failed(`signature could not be checked: ${(e as Error).message}`);\n }\n\n const expected = args.address instanceof Uint8Array ? args.address : hexToBytes(args.address);\n if (expected.length !== 20) {\n return failed(`expected address must be 20 bytes, got ${expected.length}`);\n }\n if (!equalBytes(recovered, expected)) {\n return failed(\n `the signature does not belong to this account (recovered 0x${bytesToHex(recovered)})`,\n );\n }\n return verified;\n}\n","import { ed25519 } from '@noble/curves/ed25519';\nimport { equalBytes } from '../core/bytes';\nimport type { VerifyResult } from './result';\nimport { failed, verified } from './result';\n\nexport interface VerifySolanaSignatureArgs {\n /** The exact bytes the request carried in `signData` (the compiled message). */\n readonly signData: Uint8Array;\n /** 64-byte Ed25519 signature from the reply. */\n readonly signature: Uint8Array;\n /** The 32-byte signer public key the request was built for. */\n readonly publicKey: Uint8Array;\n /**\n * Optional: the message bytes you are ABOUT TO BROADCAST. Matters most on\n * Solana — a blockhash refresh between build and send makes \"what was\n * signed\" and \"what will be sent\" two different objects that must agree.\n */\n readonly broadcastMessageBytes?: Uint8Array;\n}\n\nexport function verifySolanaSignature(args: VerifySolanaSignatureArgs): VerifyResult {\n if (\n args.broadcastMessageBytes !== undefined &&\n !equalBytes(args.broadcastMessageBytes, args.signData)\n ) {\n return failed('the message to broadcast is not the one the device signed');\n }\n let ok: boolean;\n try {\n ok = ed25519.verify(args.signature, args.signData, args.publicKey);\n } catch (e) {\n return failed(`Solana signature could not be checked: ${(e as Error).message}`);\n }\n return ok ? verified : failed('the signature does not belong to this account');\n}\n","import { sha256 } from '@noble/hashes/sha2';\nimport { concatBytes } from '../core/bytes';\nimport { EraSdkError } from '../core/errors';\n\n/**\n * Minimal TON Bag-of-Cells reader + cell representation hash — exactly the\n * subset the device's signer implements: generic BoC, ordinary level-0 cells,\n * first root. The transaction digest the device signs IS the root cell's\n * representation hash, so this must agree with the firmware bit for bit.\n *\n * Hardened for scanned/untrusted input: size caps, bounds checks, and\n * forward-only references (the standard BoC topological order; a backward\n * reference would make the single-pass hash read an uncomputed child).\n */\n\nconst BOC_MAGIC = 0xb5ee9c72;\nconst MAX_CELLS = 256;\nconst MAX_CELL_DATA_BYTES = 128;\nconst MAX_REFS = 4;\n\ninterface Cell {\n dataBits: number;\n data: Uint8Array;\n refs: number[];\n depth: number;\n hash: Uint8Array;\n}\n\nfunction err(message: string): EraSdkError {\n return new EraSdkError('malformed-reply', `ton boc: ${message}`);\n}\n\n/** Representation hash of the ROOT cell of a BoC — the bytes TON signs. */\nexport function bocRootHash(boc: Uint8Array): Uint8Array {\n if (boc.length < 10) throw err('too short');\n const magic = ((boc[0]! << 24) | (boc[1]! << 16) | (boc[2]! << 8) | boc[3]!) >>> 0;\n if (magic !== BOC_MAGIC) throw err('not a generic BoC');\n\n const flags = boc[4]!;\n const hasIdx = (flags >> 7) & 1;\n const refSize = flags & 0x07;\n const offSize = boc[5]!;\n if (refSize === 0 || refSize > 4) throw err('bad ref size');\n if (offSize === 0 || offSize > 8) throw err('bad offset size');\n\n let pos = 6;\n const readInt = (byteLen: number): number => {\n let value = 0;\n for (let i = 0; i < byteLen; i++) {\n if (pos >= boc.length) throw err('truncated header');\n value = value * 256 + boc[pos++]!;\n }\n if (!Number.isSafeInteger(value)) throw err('header value out of range');\n return value;\n };\n\n const cellCount = readInt(refSize);\n const rootCount = readInt(refSize);\n readInt(refSize); // absent count\n readInt(offSize); // total cell data size\n if (rootCount === 0) throw err('no roots');\n if (cellCount === 0 || cellCount > MAX_CELLS) throw err('cell count out of range');\n\n const rootIndex = readInt(refSize);\n for (let i = 1; i < rootCount; i++) readInt(refSize); // remaining root indices\n if (rootIndex >= cellCount) throw err('root index out of range');\n if (hasIdx) pos += cellCount * offSize; // skip the offsets index\n\n const cells: Cell[] = [];\n for (let i = 0; i < cellCount; i++) {\n if (pos + 2 > boc.length) throw err('truncated cell');\n const d1 = boc[pos++]!;\n const d2 = boc[pos++]!;\n const refCount = d1 & 0x07;\n if (refCount > MAX_REFS) throw err('too many references');\n\n const dataByteLen = (d2 + 1) >> 1;\n const incomplete = (d2 & 1) === 1;\n if (dataByteLen > MAX_CELL_DATA_BYTES) throw err('cell data too large');\n if (pos + dataByteLen > boc.length) throw err('truncated cell data');\n const data = boc.slice(pos, pos + dataByteLen);\n pos += dataByteLen;\n\n // Bit length from the completion tag (last set bit marks the end).\n let dataBits: number;\n if (incomplete && dataByteLen > 0) {\n const last = data[dataByteLen - 1]!;\n if (last === 0) {\n dataBits = (dataByteLen - 1) * 8;\n } else {\n let trailingZeros = 0;\n for (let b = 0; b < 8; b++) {\n if (last & (1 << b)) break;\n trailingZeros++;\n }\n dataBits = dataByteLen * 8 - 1 - trailingZeros;\n }\n } else {\n dataBits = dataByteLen * 8;\n }\n\n const refs: number[] = [];\n for (let r = 0; r < refCount; r++) {\n const ref = readInt(refSize);\n if (ref >= cellCount) throw err('reference out of range');\n if (ref <= i) throw err('non-topological cell reference');\n refs.push(ref);\n }\n cells.push({ dataBits, data, refs, depth: 0, hash: new Uint8Array(0) });\n }\n\n // Bottom-up (children first — guaranteed by the forward-only reference check).\n for (let i = cellCount - 1; i >= 0; i--) {\n const cell = cells[i]!;\n let maxChildDepth = -1;\n for (const r of cell.refs) {\n maxChildDepth = Math.max(maxChildDepth, cells[r]!.depth);\n }\n cell.depth = cell.refs.length === 0 ? 0 : maxChildDepth + 1;\n\n const dataBytes = (cell.dataBits + 7) >> 3;\n const incomplete = cell.dataBits % 8 !== 0;\n const repr: number[] = [cell.refs.length, dataBytes * 2 - (incomplete ? 1 : 0)];\n for (let b = 0; b < dataBytes; b++) repr.push(cell.data[b] ?? 0);\n if (incomplete && dataBytes > 0) {\n const shift = 7 - (cell.dataBits % 8);\n const last = repr.length - 1;\n repr[last] = (repr[last]! | (1 << shift)) & (0xff << shift) & 0xff;\n }\n for (const r of cell.refs) {\n repr.push((cells[r]!.depth >> 8) & 0xff, cells[r]!.depth & 0xff);\n }\n let bytes: Uint8Array = new Uint8Array(repr);\n for (const r of cell.refs) bytes = concatBytes(bytes, cells[r]!.hash);\n cell.hash = sha256(bytes);\n }\n\n return cells[rootIndex]!.hash;\n}\n","import { ed25519 } from '@noble/curves/ed25519';\nimport { sha256 } from '@noble/hashes/sha2';\nimport { TonDataType } from '../chains/ton';\nimport { concatBytes, utf8Encode } from '../core/bytes';\nimport type { VerifyResult } from './result';\nimport { failed, verified } from './result';\nimport { bocRootHash } from './ton-boc';\n\nexport interface VerifyTonSignatureArgs {\n /** The exact bytes the request carried in `signData`. */\n readonly signData: Uint8Array;\n readonly dataType: TonDataType;\n /** 64-byte Ed25519 signature from the reply. */\n readonly signature: Uint8Array;\n /** The 32-byte signer public key from linking (`accounts.ton()`). */\n readonly publicKey: Uint8Array;\n}\n\n/**\n * Recompute the exact digest the device signs — the BoC ROOT CELL's\n * representation hash for a transaction, or the TON Connect proof digest\n * `sha256(0xFFFF || \"ton-connect\" || sha256(payload))` — and verify the\n * Ed25519 signature against the linked key.\n */\nexport function verifyTonSignature(args: VerifyTonSignatureArgs): VerifyResult {\n if (args.signature.length !== 64) return failed('signature must be 64 bytes');\n if (args.publicKey.length !== 32) return failed('public key must be 32 bytes');\n\n let digest: Uint8Array;\n if (args.dataType === TonDataType.tonProof) {\n digest = sha256(\n concatBytes(new Uint8Array([0xff, 0xff]), utf8Encode('ton-connect'), sha256(args.signData)),\n );\n } else if (args.dataType === TonDataType.transaction) {\n try {\n digest = bocRootHash(args.signData);\n } catch (e) {\n return failed(`signData is not a readable BoC: ${(e as Error).message}`);\n }\n } else {\n return failed(`unknown dataType ${args.dataType satisfies never}`);\n }\n\n let ok: boolean;\n try {\n ok = ed25519.verify(args.signature, digest, args.publicKey);\n } catch (e) {\n return failed(`TON signature could not be checked: ${(e as Error).message}`);\n }\n return ok ? verified : failed('the signature does not belong to this account');\n}\n","import { secp256k1 } from '@noble/curves/secp256k1';\nimport { sha256 } from '@noble/hashes/sha2';\nimport { keccak_256 } from '@noble/hashes/sha3';\nimport { createBase58check } from '@scure/base';\nimport { concatBytes, equalBytes, utf8Decode } from '../core/bytes';\nimport type { SignedTronTx, TronLatestBlock } from '../tron-proto/messages';\nimport { splitSignedTronTx } from '../tron-proto/messages';\nimport { firstBytes, firstVarint, readFields } from '../tron-proto/wire';\nimport type { VerifyResult } from './result';\nimport { failed, verified } from './result';\n\nconst base58check = createBase58check(sha256);\n\nexport interface VerifyTronSignatureArgs {\n /** The `raw_data` bytes the request carried. */\n readonly rawData: Uint8Array;\n /** The base58 owner address the transaction spends from. */\n readonly from: string;\n /** The reference block the request carried (enables the rebuild-path window check). */\n readonly latestBlock?: TronLatestBlock;\n /** The reply: either the split frame from `TronSignatureResult.signedTx`, or the raw hex. */\n readonly signedTx: SignedTronTx | string;\n}\n\n/**\n * The Tron reply is a fully signed transaction broadcast VERBATIM, so it is\n * checked on both counts: every signature must recover to the owner address,\n * and the transaction must move what the user approved.\n *\n * Byte equality with the request's `rawData` is the strong form. When the\n * bytes differ (a firmware that rebuilds `raw_data` from the semantic\n * fields), the fallback compares the fields that decide where the money goes,\n * plus the validity window against the reference block.\n */\nexport function verifyTronSignature(args: VerifyTronSignatureArgs): VerifyResult {\n let signedTx: SignedTronTx;\n try {\n signedTx = typeof args.signedTx === 'string' ? splitSignedTronTx(args.signedTx) : args.signedTx;\n } catch (e) {\n return failed(`the returned Tron transaction is not readable: ${(e as Error).message}`);\n }\n if (signedTx.signatures.length === 0) {\n return failed('the returned Tron transaction carries no signature');\n }\n if (!args.from) {\n return failed('no owner address to check the signature against');\n }\n\n const digest = sha256(signedTx.rawData);\n for (const signature of signedTx.signatures) {\n const recovered = recoverTronAddress(digest, signature);\n if (recovered === null) return failed('signature could not be checked');\n if (recovered !== args.from) {\n return failed('the signature does not belong to this account');\n }\n }\n\n if (equalBytes(signedTx.rawData, args.rawData)) return verified;\n\n // Rebuild path: the firmware built its own raw_data from the semantic\n // fields. Compare the operation, then the validity window.\n const contractResult = compareContracts(args.rawData, signedTx.rawData);\n if (contractResult !== null) return contractResult;\n if (args.latestBlock === undefined) {\n return failed(\n 'the returned raw_data differs from the request and no latestBlock was provided to check the validity window',\n );\n }\n return compareWindow(signedTx.rawData, args.latestBlock);\n}\n\nfunction recoverTronAddress(digest: Uint8Array, signature: Uint8Array): string | null {\n if (signature.length < 65) return null;\n const recovery = signature[64]!;\n const recoveryId = recovery >= 27 ? (recovery - 27) & 1 : recovery & 1;\n try {\n const point = secp256k1.Signature.fromCompact(signature.slice(0, 64))\n .addRecoveryBit(recoveryId)\n .recoverPublicKey(digest);\n const hash = keccak_256(point.toRawBytes(false).slice(1));\n return base58check.encode(concatBytes(new Uint8Array([0x41]), hash.slice(12)));\n } catch {\n return null;\n }\n}\n\n// --- raw_data structural comparison ---------------------------------------\n\ninterface TronContract {\n readonly typeUrl: string;\n readonly type: bigint;\n readonly parameter: Uint8Array;\n}\n\ninterface TronRawData {\n readonly contracts: readonly TronContract[];\n readonly expiration: bigint;\n readonly timestamp: bigint;\n}\n\nfunction parseRawData(bytes: Uint8Array): TronRawData | null {\n try {\n const fields = readFields(bytes);\n const contracts: TronContract[] = [];\n for (const f of fields) {\n if (f.field === 11 && f.wireType === 2) {\n const c = readFields(f.bytes);\n const anyBytes = firstBytes(c, 2);\n const any = anyBytes ? readFields(anyBytes) : [];\n const typeUrlBytes = anyBytes ? firstBytes(any, 1) : null;\n contracts.push({\n typeUrl: typeUrlBytes ? utf8Decode(typeUrlBytes) : '',\n type: firstVarint(c, 1) ?? 0n,\n parameter: (anyBytes && firstBytes(any, 2)) || new Uint8Array(0),\n });\n }\n }\n return {\n contracts,\n expiration: firstVarint(fields, 8) ?? 0n,\n timestamp: firstVarint(fields, 14) ?? 0n,\n };\n } catch {\n return null;\n }\n}\n\n/** null = contracts match (continue to the window check); a result = verdict. */\nfunction compareContracts(askedBytes: Uint8Array, repliedBytes: Uint8Array): VerifyResult | null {\n const asked = parseRawData(askedBytes);\n const replied = parseRawData(repliedBytes);\n if (!asked) return failed('the Tron transaction built by the app could not be read');\n if (!replied) return failed('the Tron transaction built by the device could not be read');\n if (asked.contracts.length !== 1 || replied.contracts.length !== 1) {\n return failed('the Tron transaction does not carry exactly one contract');\n }\n const a = asked.contracts[0]!;\n const b = replied.contracts[0]!;\n const kindA = contractKind(a);\n const kindB = contractKind(b);\n if (kindA !== kindB) {\n return failed('the returned Tron transaction is a different kind of operation');\n }\n\n const pa = readFieldsSafe(a.parameter);\n const pb = readFieldsSafe(b.parameter);\n if (!pa || !pb) return failed('the Tron contract parameters could not be read');\n\n switch (kindA) {\n case 'transfer':\n // TransferContract {1: owner, 2: to, 3: amount}\n if (\n sameBytesField(pa, pb, 1) &&\n sameBytesField(pa, pb, 2) &&\n (firstVarint(pa, 3) ?? 0n) === (firstVarint(pb, 3) ?? 0n)\n ) {\n return null;\n }\n break;\n case 'transferAsset':\n // TransferAssetContract {1: asset, 2: owner, 3: to, 4: amount}\n if (\n sameBytesField(pa, pb, 1) &&\n sameBytesField(pa, pb, 2) &&\n sameBytesField(pa, pb, 3) &&\n (firstVarint(pa, 4) ?? 0n) === (firstVarint(pb, 4) ?? 0n)\n ) {\n return null;\n }\n break;\n case 'triggerSmartContract':\n // TriggerSmartContract {1: owner, 2: contract, 3: call_value, 4: data}.\n // call_value: zero and absent are the same thing — the two sides are\n // serialized by different protobuf writers that disagree on whether a\n // zero scalar is written, and every TRC-20 transfer carries call_value 0.\n if (\n sameBytesField(pa, pb, 1) &&\n sameBytesField(pa, pb, 2) &&\n (firstVarint(pa, 3) ?? 0n) === (firstVarint(pb, 3) ?? 0n) &&\n sameBytesField(pa, pb, 4)\n ) {\n return null;\n }\n break;\n default:\n // An operation this gate cannot compare field by field is not waved\n // through: without byte equality there is nothing left to bind it to\n // what the user approved.\n return failed('the returned Tron transaction carries an operation this check cannot compare');\n }\n return failed('the returned Tron transaction does not match the one approved');\n}\n\ntype ContractKind = 'transfer' | 'transferAsset' | 'triggerSmartContract' | 'other';\n\nfunction contractKind(contract: TronContract): ContractKind {\n if (contract.typeUrl.endsWith('.TransferContract') || contract.type === 1n) return 'transfer';\n if (contract.typeUrl.endsWith('.TransferAssetContract') || contract.type === 2n) {\n return 'transferAsset';\n }\n if (contract.typeUrl.endsWith('.TriggerSmartContract') || contract.type === 31n) {\n return 'triggerSmartContract';\n }\n return 'other';\n}\n\nfunction readFieldsSafe(bytes: Uint8Array): ReturnType<typeof readFields> | null {\n try {\n return readFields(bytes);\n } catch {\n return null;\n }\n}\n\nfunction sameBytesField(\n a: ReturnType<typeof readFields>,\n b: ReturnType<typeof readFields>,\n field: number,\n): boolean {\n const x = firstBytes(a, field) ?? new Uint8Array(0);\n const y = firstBytes(b, field) ?? new Uint8Array(0);\n return equalBytes(x, y);\n}\n\n/**\n * Firmware formulas, not policy: the two device-side transaction builders\n * stamp `timestamp` with the request's reference-block timestamp verbatim and\n * set `expiration` to +10 minutes (one builder) or +10 hours (the other). A\n * range spanning both cannot refuse a reply the live fleet produces.\n */\nconst MIN_EXPIRY_MS = 10n * 60n * 1000n;\nconst MAX_EXPIRY_MS = 10n * 60n * 60n * 1000n;\n\nfunction compareWindow(repliedBytes: Uint8Array, latestBlock: TronLatestBlock): VerifyResult {\n const replied = parseRawData(repliedBytes);\n if (!replied) return failed('the Tron transaction built by the device could not be read');\n const block = BigInt(latestBlock.timestamp);\n if (replied.timestamp !== block) {\n return failed(\n 'the returned Tron transaction is stamped against a different reference block than the one we sent',\n );\n }\n const validFor = replied.expiration - block;\n if (validFor < MIN_EXPIRY_MS || validFor > MAX_EXPIRY_MS) {\n return failed(\n `the returned Tron transaction is valid for ${validFor} ms after the reference block, outside the firmware's ${MIN_EXPIRY_MS}-${MAX_EXPIRY_MS} ms window`,\n );\n }\n return verified;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"verify.js","names":["message","err"],"sources":["../src/verify/result.ts","../src/verify/bch.ts","../src/verify/psbt-reader.ts","../src/verify/btc.ts","../src/verify/cardano.ts","../src/verify/cosmos.ts","../src/verify/evm.ts","../src/verify/solana.ts","../src/verify/sui.ts","../src/verify/ton-boc.ts","../src/verify/ton.ts","../src/verify/tron.ts","../src/verify/xrp.ts"],"sourcesContent":["/** Outcome of a verification helper. Helpers return, never throw, on mismatches. */\nexport type VerifyResult =\n /** Verified cryptographically / byte-for-byte. */\n | { readonly ok: true; readonly checked: true }\n /**\n * Nothing client-side is verifiable for this input (EIP-712 typed data:\n * the digest is the hash of the structure, which only the device computes).\n * The UR-type pin and the request-id echo are the whole binding.\n */\n | { readonly ok: true; readonly checked: false; readonly reason: string }\n | { readonly ok: false; readonly reason: string };\n\nexport const verified: VerifyResult = { ok: true, checked: true };\nexport const failed = (reason: string): VerifyResult => ({ ok: false, reason });\nexport const unverifiable = (reason: string): VerifyResult => ({\n ok: true,\n checked: false,\n reason,\n});\n","import { secp256k1 } from '@noble/curves/secp256k1';\nimport { ripemd160 } from '@noble/hashes/ripemd160';\nimport { sha256 } from '@noble/hashes/sha2';\nimport { decodeCashAddr } from '../chains/cashaddr';\nimport { bytesToHex, concatBytes, equalBytes, hexToBytes } from '../core/bytes';\nimport { EraSdkError } from '../core/errors';\nimport type { VerifyResult } from './result';\nimport { failed, verified } from './result';\n\n/**\n * \"The device signed exactly what I sent\" for Bitcoin Cash.\n *\n * The reply on this chain is a COMPLETE broadcastable transaction, so the\n * binding has to be rebuilt from it: every outpoint, every output script and\n * value, and every input signature are checked against the request. The\n * sighash is BIP-143 with `SIGHASH_FORKID` (0x41) — recomputed here from the\n * request's own input values, which is also what makes a value lie visible:\n * a wrong `value` in the request would fail right here, because the network\n * would reject the same preimage.\n */\n\nexport interface VerifyBchInput {\n /** Display-order txid, 64 hex chars — as sent in the request. */\n readonly txid: string;\n readonly index: number;\n /** UTXO value in satoshis — as sent in the request. */\n readonly value: number | bigint;\n /** The compressed public key the request named as the UTXO owner. */\n readonly publicKey: Uint8Array | string;\n}\n\nexport interface VerifyBchOutput {\n /** CashAddr as sent in the request (prefixed or bare). */\n readonly address: string;\n readonly value: number | bigint;\n}\n\nexport interface VerifyBchSignedTxArgs {\n /** The reply's `rawTx` hex. */\n readonly rawTx: string;\n readonly inputs: readonly VerifyBchInput[];\n readonly outputs: readonly VerifyBchOutput[];\n /** The reply's `txId`, when you want it checked against the raw bytes too. */\n readonly txId?: string;\n}\n\nconst SIGHASH_FORKID_ALL = 0x41;\n// The device's signer hardcodes these; a reply that deviates was not built\n// by it (or a firmware change landed — then update BOTH constants and docs).\nconst BCH_TX_VERSION = 1;\nconst BCH_TX_LOCKTIME = 0;\nconst BCH_TX_SEQUENCE = 0xfffffffd;\n\ninterface DecodedInput {\n readonly txidLE: Uint8Array;\n readonly index: number;\n readonly scriptSig: Uint8Array;\n readonly sequence: number;\n}\n\ninterface DecodedOutput {\n readonly value: bigint;\n readonly script: Uint8Array;\n}\n\nexport interface DecodedBchTx {\n readonly version: number;\n readonly inputs: readonly DecodedInput[];\n readonly outputs: readonly DecodedOutput[];\n readonly locktime: number;\n}\n\n/** Hardened reader for the legacy (non-witness) transaction serialization. */\nexport function decodeBchRawTx(rawTxHex: string): DecodedBchTx {\n let bytes: Uint8Array;\n try {\n bytes = hexToBytes(rawTxHex);\n } catch {\n throw new EraSdkError('malformed-reply', 'signed transaction is not hex');\n }\n let offset = 0;\n const need = (n: number): void => {\n if (offset + n > bytes.length) {\n throw new EraSdkError('malformed-reply', 'signed transaction is truncated');\n }\n };\n const readU32 = (): number => {\n need(4);\n const v =\n bytes[offset]! |\n (bytes[offset + 1]! << 8) |\n (bytes[offset + 2]! << 16) |\n (bytes[offset + 3]! << 24);\n offset += 4;\n return v >>> 0;\n };\n const readU64 = (): bigint => {\n need(8);\n let v = 0n;\n for (let i = 7; i >= 0; i--) v = (v << 8n) | BigInt(bytes[offset + i]!);\n offset += 8;\n return v;\n };\n const readVarint = (): number => {\n need(1);\n const first = bytes[offset++]!;\n if (first < 0xfd) return first;\n if (first === 0xfd) {\n need(2);\n const v = bytes[offset]! | (bytes[offset + 1]! << 8);\n offset += 2;\n return v;\n }\n // 4- and 8-byte counts cannot occur in a transaction the device can build.\n throw new EraSdkError('malformed-reply', 'unreasonable varint in signed transaction');\n };\n const readSlice = (n: number): Uint8Array => {\n need(n);\n const s = bytes.subarray(offset, offset + n);\n offset += n;\n return s;\n };\n\n const version = readU32();\n const inputCount = readVarint();\n if (inputCount === 0 || inputCount > 1000) {\n throw new EraSdkError('malformed-reply', 'unreasonable input count in signed transaction');\n }\n const inputs: DecodedInput[] = [];\n for (let i = 0; i < inputCount; i++) {\n const txidLE = readSlice(32);\n const index = readU32();\n const scriptSig = readSlice(readVarint());\n const sequence = readU32();\n inputs.push({ txidLE, index, scriptSig, sequence });\n }\n const outputCount = readVarint();\n if (outputCount === 0 || outputCount > 1000) {\n throw new EraSdkError('malformed-reply', 'unreasonable output count in signed transaction');\n }\n const outputs: DecodedOutput[] = [];\n for (let i = 0; i < outputCount; i++) {\n const value = readU64();\n const script = readSlice(readVarint());\n outputs.push({ value, script });\n }\n const locktime = readU32();\n if (offset !== bytes.length) {\n throw new EraSdkError('malformed-reply', 'trailing bytes after signed transaction');\n }\n return { version, inputs, outputs, locktime };\n}\n\nfunction sha256d(data: Uint8Array): Uint8Array {\n return sha256(sha256(data));\n}\n\nfunction hash160(data: Uint8Array): Uint8Array {\n return ripemd160(sha256(data));\n}\n\nfunction p2pkhScript(pubkeyHash: Uint8Array): Uint8Array {\n return concatBytes(new Uint8Array([0x76, 0xa9, 0x14]), pubkeyHash, new Uint8Array([0x88, 0xac]));\n}\n\nfunction p2shScript(scriptHash: Uint8Array): Uint8Array {\n return concatBytes(new Uint8Array([0xa9, 0x14]), scriptHash, new Uint8Array([0x87]));\n}\n\nfunction scriptForAddress(address: string): Uint8Array {\n const decoded = decodeCashAddr(address);\n return decoded.type === 'p2pkh' ? p2pkhScript(decoded.hash) : p2shScript(decoded.hash);\n}\n\nfunction le32(value: number): Uint8Array {\n return new Uint8Array([\n value & 0xff,\n (value >>> 8) & 0xff,\n (value >>> 16) & 0xff,\n (value >>> 24) & 0xff,\n ]);\n}\n\nfunction le64(value: bigint): Uint8Array {\n const out = new Uint8Array(8);\n let v = value;\n for (let i = 0; i < 8; i++) {\n out[i] = Number(v & 0xffn);\n v >>= 8n;\n }\n return out;\n}\n\nfunction varintBytes(value: number): Uint8Array {\n if (value < 0xfd) return new Uint8Array([value]);\n return new Uint8Array([0xfd, value & 0xff, (value >>> 8) & 0xff]);\n}\n\n/**\n * BIP-143 sighash preimage with FORKID, exactly as consensus defines it:\n * `version ‖ hashPrevouts ‖ hashSequence ‖ outpoint ‖ scriptCode ‖ value ‖\n * sequence ‖ hashOutputs ‖ locktime ‖ hashType(LE)`, double-SHA256d.\n */\nexport function computeBchSighash(args: {\n readonly tx: DecodedBchTx;\n readonly inputIndex: number;\n readonly scriptCode: Uint8Array;\n readonly value: bigint;\n readonly hashType?: number;\n}): Uint8Array {\n const { tx, inputIndex, scriptCode, value } = args;\n const hashType = args.hashType ?? SIGHASH_FORKID_ALL;\n const input = tx.inputs[inputIndex];\n if (!input) {\n throw new EraSdkError('invalid-props', 'sighash input index out of range');\n }\n const hashPrevouts = sha256d(\n concatBytes(...tx.inputs.map((i) => concatBytes(i.txidLE, le32(i.index)))),\n );\n const hashSequence = sha256d(concatBytes(...tx.inputs.map((i) => le32(i.sequence))));\n const hashOutputs = sha256d(\n concatBytes(\n ...tx.outputs.map((o) => concatBytes(le64(o.value), varintBytes(o.script.length), o.script)),\n ),\n );\n const preimage = concatBytes(\n le32(tx.version),\n hashPrevouts,\n hashSequence,\n input.txidLE,\n le32(input.index),\n varintBytes(scriptCode.length),\n scriptCode,\n le64(value),\n le32(input.sequence),\n hashOutputs,\n le32(tx.locktime),\n le32(hashType),\n );\n return sha256d(preimage);\n}\n\nfunction toBigintValue(value: number | bigint, label: string): bigint {\n const v = typeof value === 'number' ? BigInt(value) : value;\n if (v <= 0n) throw new EraSdkError('invalid-props', `${label} must be positive`);\n return v;\n}\n\nfunction toPublicKeyBytes(publicKey: Uint8Array | string): Uint8Array {\n return typeof publicKey === 'string' ? hexToBytes(publicKey) : publicKey;\n}\n\nexport function verifyBchSignedTx(args: VerifyBchSignedTxArgs): VerifyResult {\n try {\n const tx = decodeBchRawTx(args.rawTx);\n\n // Everything the verifier does not read is unchecked (the sighash is\n // recomputed FROM the decoded tx, so it is self-consistent with any\n // version/locktime/sequence). Pin the parameters the signer fixes.\n if (tx.version !== BCH_TX_VERSION || tx.locktime !== BCH_TX_LOCKTIME) {\n return failed(\n `transaction parameters (version ${tx.version}, locktime ${tx.locktime}) are not the device signer's (1, 0)`,\n );\n }\n for (let i = 0; i < tx.inputs.length; i++) {\n if (tx.inputs[i]!.sequence !== BCH_TX_SEQUENCE) {\n return failed(`input ${i} sequence is not the device signer's 0xfffffffd`);\n }\n }\n\n if (tx.inputs.length !== args.inputs.length) {\n return failed(\n `signed transaction has ${tx.inputs.length} inputs, the request had ${args.inputs.length}`,\n );\n }\n if (tx.outputs.length !== args.outputs.length) {\n return failed(\n `signed transaction has ${tx.outputs.length} outputs, the request had ${args.outputs.length}`,\n );\n }\n\n for (let i = 0; i < args.outputs.length; i++) {\n const requested = args.outputs[i]!;\n const actual = tx.outputs[i]!;\n if (actual.value !== toBigintValue(requested.value, `output ${i} value`)) {\n return failed(`output ${i} value differs from the request`);\n }\n if (!equalBytes(actual.script, scriptForAddress(requested.address))) {\n return failed(`output ${i} does not pay the requested address`);\n }\n }\n\n for (let i = 0; i < args.inputs.length; i++) {\n const requested = args.inputs[i]!;\n const actual = tx.inputs[i]!;\n const txidLE = hexToBytes(requested.txid).reverse();\n if (!equalBytes(actual.txidLE, txidLE) || actual.index !== requested.index) {\n return failed(`input ${i} spends a different outpoint than the request named`);\n }\n\n // scriptSig must be exactly push(sig‖0x41) push(pubkey33).\n const script = actual.scriptSig;\n if (script.length < 2) return failed(`input ${i} has no signature`);\n const sigLen = script[0]!;\n if (sigLen < 9 || 1 + sigLen + 1 > script.length) {\n return failed(`input ${i} scriptSig is not a signature push`);\n }\n const sigWithType = script.subarray(1, 1 + sigLen);\n const pubLen = script[1 + sigLen]!;\n if (pubLen !== 33 || 1 + sigLen + 1 + pubLen !== script.length) {\n return failed(`input ${i} scriptSig does not end with a compressed public key push`);\n }\n const pubkey = script.subarray(1 + sigLen + 1);\n if (!equalBytes(pubkey, toPublicKeyBytes(requested.publicKey))) {\n return failed(\n `input ${i} was signed with a different public key than the request named — ` +\n 'the transaction cannot spend the requested UTXO',\n );\n }\n const hashType = sigWithType[sigWithType.length - 1]!;\n if (hashType !== SIGHASH_FORKID_ALL) {\n return failed(\n `input ${i} uses sighash 0x${hashType.toString(16)}, expected SIGHASH_ALL|FORKID (0x41)`,\n );\n }\n const sighash = computeBchSighash({\n tx,\n inputIndex: i,\n scriptCode: p2pkhScript(hash160(pubkey)),\n value: toBigintValue(requested.value, `input ${i} value`),\n });\n const signature = secp256k1.Signature.fromDER(\n sigWithType.subarray(0, sigWithType.length - 1),\n ).toCompactRawBytes();\n if (!secp256k1.verify(signature, sighash, pubkey)) {\n return failed(`input ${i} signature does not verify against the BIP-143 FORKID sighash`);\n }\n }\n\n if (args.txId !== undefined) {\n const computed = bytesToHex(sha256d(hexToBytes(args.rawTx)).reverse());\n if (computed !== args.txId.toLowerCase()) {\n return failed('reply txId does not match the hash of the signed transaction');\n }\n }\n return verified;\n } catch (e) {\n return failed(message(e));\n }\n}\n\nfunction message(e: unknown): string {\n return e instanceof EraSdkError || e instanceof Error ? e.message : String(e);\n}\n","import { EraSdkError } from '../core/errors';\n\n/**\n * Minimal PSBT v0 (BIP-174) reader — just enough structure for the\n * verification guard: the global unsigned transaction (verbatim slice, never\n * re-serialized), the PSBT version, and per-input key/value maps.\n *\n * Hardened: compact-size lengths bounds-checked before slicing, duplicate\n * keys within one map refused (a hostile PSBT carrying two final scriptSigs\n * for one input must not survive parsing).\n */\n\nexport interface PsbtKeyValue {\n readonly keyType: number;\n readonly keyData: Uint8Array;\n readonly value: Uint8Array;\n}\n\nexport interface ParsedPsbt {\n /** The global UNSIGNED_TX value, verbatim. */\n readonly unsignedTx: Uint8Array;\n /** Global PSBT_GLOBAL_VERSION (0xFB) if present; v0 files normally omit it. */\n readonly version: number;\n readonly inputs: readonly (readonly PsbtKeyValue[])[];\n readonly outputs: readonly (readonly PsbtKeyValue[])[];\n}\n\nconst MAGIC = [0x70, 0x73, 0x62, 0x74, 0xff]; // \"psbt\\xff\"\n\nexport const PsbtInputType = {\n partialSig: 0x02,\n finalScriptSig: 0x07,\n finalScriptWitness: 0x08,\n taprootKeySpendSignature: 0x13,\n taprootScriptSpendSignature: 0x14,\n} as const;\n\nfunction err(message: string): EraSdkError {\n return new EraSdkError('malformed-reply', `psbt: ${message}`);\n}\n\nclass Reader {\n offset = 0;\n constructor(readonly bytes: Uint8Array) {}\n\n get remaining(): number {\n return this.bytes.length - this.offset;\n }\n\n u8(): number {\n const b = this.bytes[this.offset];\n if (b === undefined) throw err('truncated');\n this.offset += 1;\n return b;\n }\n\n /** Bitcoin compact-size integer, MINIMAL encoding required (as consensus does). */\n compactSize(): number {\n const first = this.u8();\n if (first < 0xfd) return first;\n let width: number;\n let minimum: bigint;\n if (first === 0xfd) {\n width = 2;\n minimum = 0xfdn;\n } else if (first === 0xfe) {\n width = 4;\n minimum = 0x10000n;\n } else {\n width = 8;\n minimum = 0x100000000n;\n }\n let value = 0n;\n for (let i = 0; i < width; i++) value |= BigInt(this.u8()) << BigInt(8 * i);\n if (value < minimum) throw err('non-minimal compact-size encoding');\n if (value > BigInt(Number.MAX_SAFE_INTEGER)) throw err('length exceeds safe range');\n return Number(value);\n }\n\n take(length: number): Uint8Array {\n if (length > this.remaining) throw err('length exceeds input');\n const out = this.bytes.slice(this.offset, this.offset + length);\n this.offset += length;\n return out;\n }\n}\n\n/** Read one key/value map (ends at the 0x00 separator). */\nfunction readMap(reader: Reader): PsbtKeyValue[] {\n const entries: PsbtKeyValue[] = [];\n const seen = new Set<string>();\n for (;;) {\n const keyLength = reader.compactSize();\n if (keyLength === 0) return entries;\n const key = reader.take(keyLength);\n const value = reader.take(reader.compactSize());\n const keyId = Array.from(key)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n if (seen.has(keyId)) throw err('duplicate key within one map');\n seen.add(keyId);\n entries.push({ keyType: key[0]!, keyData: key.slice(1), value });\n }\n}\n\n/** Count of inputs/outputs in a (non-witness) unsigned transaction. */\nfunction countTxInputsOutputs(tx: Uint8Array): { inputs: number; outputs: number } {\n const reader = new Reader(tx);\n reader.take(4); // version\n const inputs = reader.compactSize();\n if (inputs === 0) {\n // A zero here would be a segwit marker — the PSBT unsigned tx must not\n // carry witness data, so this is not a transaction we can count.\n throw err('unsigned transaction has zero inputs (or carries witness data)');\n }\n for (let i = 0; i < inputs; i++) {\n reader.take(32 + 4); // prevout\n reader.take(reader.compactSize()); // scriptSig (empty in a PSBT)\n reader.take(4); // sequence\n }\n const outputs = reader.compactSize();\n for (let i = 0; i < outputs; i++) {\n reader.take(8); // amount\n reader.take(reader.compactSize()); // scriptPubKey\n }\n reader.take(4); // locktime\n if (reader.remaining !== 0) throw err('trailing bytes after the unsigned transaction');\n return { inputs, outputs };\n}\n\nexport function parsePsbt(bytes: Uint8Array): ParsedPsbt {\n const reader = new Reader(bytes);\n for (const expected of MAGIC) {\n if (reader.u8() !== expected) throw err('bad magic');\n }\n const globalMap = readMap(reader);\n\n let unsignedTx: Uint8Array | null = null;\n let version = 0;\n for (const entry of globalMap) {\n if (entry.keyType === 0x00 && entry.keyData.length === 0) unsignedTx = entry.value;\n if (entry.keyType === 0xfb && entry.keyData.length === 0) {\n if (entry.value.length !== 4) throw err('bad version field');\n version =\n (entry.value[0]! |\n (entry.value[1]! << 8) |\n (entry.value[2]! << 16) |\n (entry.value[3]! << 24)) >>>\n 0;\n }\n }\n if (unsignedTx === null) {\n // The device's signer relies on the global UNSIGNED_TX that only PSBT v0\n // carries; its absence means v2 (or not a PSBT at all).\n throw err('no global unsigned transaction — not a PSBT v0');\n }\n if (version !== 0) throw err(`unsupported PSBT version ${version}`);\n\n const counts = countTxInputsOutputs(unsignedTx);\n const inputs: PsbtKeyValue[][] = [];\n for (let i = 0; i < counts.inputs; i++) inputs.push(readMap(reader));\n const outputs: PsbtKeyValue[][] = [];\n for (let i = 0; i < counts.outputs; i++) outputs.push(readMap(reader));\n if (reader.remaining !== 0) throw err('trailing bytes after the output maps');\n\n return { unsignedTx, version, inputs, outputs };\n}\n\nexport function inputEntries(\n psbt: ParsedPsbt,\n index: number,\n keyType: number,\n): readonly PsbtKeyValue[] {\n return (psbt.inputs[index] ?? []).filter((e) => e.keyType === keyType);\n}\n\nexport function inputHas(psbt: ParsedPsbt, index: number, keyType: number): boolean {\n return inputEntries(psbt, index, keyType).length > 0;\n}\n","import { equalBytes } from '../core/bytes';\nimport { EraSdkError } from '../core/errors';\nimport type { ParsedPsbt } from './psbt-reader';\nimport { inputEntries, inputHas, PsbtInputType, parsePsbt } from './psbt-reader';\nimport type { VerifyResult } from './result';\nimport { failed, verified } from './result';\n\nexport interface VerifySignedPsbtArgs {\n /** The PSBT you sent to the device. */\n readonly sentPsbt: Uint8Array;\n /** The PSBT the device returned. */\n readonly signedPsbt: Uint8Array;\n /**\n * true (default) on flows where every input is yours (a plain send): a\n * reply that signed only part of the transaction is refused here with a\n * reason instead of failing later inside a finalizer. Set false for dApp\n * `signPsbt` hand-backs, where a PSBT legitimately carries inputs you\n * cannot sign.\n */\n readonly requireEveryInputSigned?: boolean;\n}\n\n/**\n * The `crypto-psbt` reply carries NO request id — this comparison IS the\n * anti-replay binding for Bitcoin. It is not optional.\n *\n * The unsigned transaction is compared byte for byte, which pins the input\n * set and order, the outputs, their amounts, the version and the locktime in\n * one shot — and therefore the txid. The device only ADDS per-input\n * signature fields, so a legitimate reply always matches.\n */\nexport function verifySignedPsbt(args: VerifySignedPsbtArgs): VerifyResult {\n let sent: ParsedPsbt;\n let signed: ParsedPsbt;\n try {\n sent = parsePsbt(args.sentPsbt);\n } catch (e) {\n return failed(`the PSBT we sent is not readable: ${message(e)}`);\n }\n try {\n signed = parsePsbt(args.signedPsbt);\n } catch (e) {\n return failed(`the PSBT the device returned is not readable: ${message(e)}`);\n }\n\n if (!equalBytes(sent.unsignedTx, signed.unsignedTx)) {\n return failed('the returned PSBT is a different transaction from the one approved');\n }\n\n // A finalized field carries the COMPLETE scriptSig/witness that will be\n // broadcast, and the unsigned-tx comparison above does not cover it (it\n // lives per input, the unsigned tx in the global map). An input that comes\n // back finalized must have been SENT that way, with byte-identical\n // values — the device echoes these fields, it never authors them.\n const finalizedTypes = [PsbtInputType.finalScriptSig, PsbtInputType.finalScriptWitness];\n for (let i = 0; i < signed.inputs.length; i++) {\n for (const type of finalizedTypes) {\n if (!inputHas(signed, i, type)) continue;\n if (!inputHas(sent, i, type)) {\n return failed(\n `input ${i} came back finalized (type 0x${type.toString(16)}) and was not sent that way — the script it would broadcast is not ours`,\n );\n }\n const a = inputEntries(sent, i, type);\n const b = inputEntries(signed, i, type);\n if (a.length !== b.length || !a.every((entry, k) => equalBytes(entry.value, b[k]!.value))) {\n return failed(\n `input ${i} came back with a different finalized script than the one we sent`,\n );\n }\n }\n }\n\n const isSigned = (i: number): boolean =>\n inputHas(signed, i, PsbtInputType.partialSig) ||\n inputHas(signed, i, PsbtInputType.taprootKeySpendSignature) ||\n inputHas(signed, i, PsbtInputType.taprootScriptSpendSignature);\n\n const indexes = signed.inputs.map((_, i) => i);\n if (args.requireEveryInputSigned ?? true) {\n if (!indexes.every(isSigned)) {\n return failed('the device signed only part of the transaction');\n }\n } else if (!indexes.some(isSigned)) {\n return failed('the returned PSBT carries no signature');\n }\n return verified;\n}\n\nexport interface VerifyBtcMessageHeaderArgs {\n /** The address the request asked the device to sign with. */\n readonly address: string;\n /** The raw 65-byte BIP-137 signature. */\n readonly signature: Uint8Array;\n}\n\n/**\n * BIP-137: the recovery header names the address type a verifier derives\n * before comparing. A header of the wrong range produces a signature that\n * LOOKS fine (65 bytes, valid base64) but fails every verifier downstream —\n * this check is the only place that difference is visible.\n */\nexport function verifyBtcMessageHeader(args: VerifyBtcMessageHeaderArgs): VerifyResult {\n if (args.signature.length === 0) {\n return failed('empty signature');\n }\n const header = args.signature[0]!;\n const range = headerRangeFor(args.address);\n if (range === null) {\n return {\n ok: true,\n checked: false,\n reason: 'address kind has no BIP-137 header range to check against',\n };\n }\n if (header >= range.low && header <= range.high) return verified;\n return failed(\n `recovery header ${header} does not match a ${range.label} address ` +\n `(BIP-137 expects ${range.low}..${range.high}); this signature would not verify against the address it was asked to sign for`,\n );\n}\n\ninterface HeaderRange {\n readonly low: number;\n readonly high: number;\n readonly label: string;\n}\n\nfunction headerRangeFor(address: string): HeaderRange | null {\n const a = address.toLowerCase();\n if (a.startsWith('bc1q') || a.startsWith('tb1q') || a.startsWith('bcrt1q')) {\n return { low: 39, high: 42, label: 'native segwit (P2WPKH)' };\n }\n if (a.startsWith('bc1p') || a.startsWith('tb1p') || a.startsWith('bcrt1p')) {\n return null; // Taproot: BIP-137 does not cover it (BIP-322 is the scheme).\n }\n // Base58 kinds matched on SHAPE, not first character alone — a guard that\n // invents a range for a string it does not understand is worse than one\n // that declines to judge.\n if (looksBase58(address)) {\n if (address.startsWith('3') || address.startsWith('2')) {\n return { low: 35, high: 38, label: 'P2SH (nested segwit)' };\n }\n if (address.startsWith('1') || address.startsWith('m') || address.startsWith('n')) {\n // Both the uncompressed and compressed P2PKH ranges — which one is\n // right depends on the key the device used, which we do not know.\n return { low: 27, high: 34, label: 'legacy P2PKH' };\n }\n }\n return null;\n}\n\nfunction looksBase58(address: string): boolean {\n return address.length >= 26 && address.length <= 35 && /^[1-9A-HJ-NP-Za-km-z]+$/.test(address);\n}\n\nfunction message(e: unknown): string {\n return e instanceof EraSdkError || e instanceof Error ? e.message : String(e);\n}\n","import { ed25519 } from '@noble/curves/ed25519';\nimport { blake2b } from '@noble/hashes/blake2b';\nimport { cardanoSoftDerivePath } from '../accounts/derive';\nimport type { CardanoWitness } from '../chains/cardano';\nimport { parseWitnessSet } from '../chains/cardano';\nimport { bytesToHex, equalBytes } from '../core/bytes';\nimport { parsePath } from '../registry/keypath';\nimport type { VerifyResult } from './result';\nimport { failed, verified } from './result';\n\nexport interface VerifyCardanoSignatureArgs {\n /** The exact bytes the request carried in `signData` (the full tx CBOR array). */\n readonly signData: Uint8Array;\n /** The reply's witness set (or already-parsed witnesses). */\n readonly witnessSet?: Uint8Array;\n readonly witnesses?: readonly CardanoWitness[];\n /**\n * Optional but STRONGLY recommended — binds the witnesses to YOUR wallet:\n * the linked account's key material plus the signing paths your request\n * carried. Without it the check only proves internal consistency of the\n * reply (any key could have produced a matching pair).\n */\n readonly account?: {\n /** From `accounts.cardano()`: the account xpub halves and its path. */\n readonly publicKey: Uint8Array;\n readonly chainCode: Uint8Array;\n readonly accountPath: string;\n };\n /** The unique signing paths of the request (utxos + certKeys), e.g. `m/1852'/1815'/0'/0/0`. */\n readonly signerPaths?: readonly string[];\n}\n\n/**\n * Recompute the digest the device signs — BLAKE2b-256 of the ENCODED FIRST\n * ELEMENT of the transaction CBOR array (the tx body) — and verify every\n * `[vkey, signature]` pair against it. With `account` + `signerPaths`, the\n * vkeys are additionally required to be exactly the soft-derived children of\n * YOUR linked account at the request's own paths.\n */\nexport function verifyCardanoSignature(args: VerifyCardanoSignatureArgs): VerifyResult {\n let witnesses: readonly CardanoWitness[];\n try {\n witnesses = args.witnesses ?? (args.witnessSet ? parseWitnessSet(args.witnessSet) : []);\n } catch (e) {\n return failed(`witness set is not readable: ${(e as Error).message}`);\n }\n if (witnesses.length === 0) return failed('no witnesses to verify');\n\n let digest: Uint8Array;\n try {\n digest = blake2b(firstArrayItemBytes(args.signData), { dkLen: 32 });\n } catch (e) {\n return failed(`signData is not a readable transaction array: ${(e as Error).message}`);\n }\n\n for (const witness of witnesses) {\n let ok: boolean;\n try {\n ok = ed25519.verify(witness.signature, digest, witness.vkey);\n } catch (e) {\n return failed(`Cardano signature could not be checked: ${(e as Error).message}`);\n }\n if (!ok) return failed('a witness signature does not verify against its own vkey');\n }\n\n if (args.account && args.signerPaths && args.signerPaths.length > 0) {\n const accountLevels = parsePath(args.account.accountPath);\n const expected = new Map<string, string>(); // vkey hex -> path\n for (const path of new Set(args.signerPaths)) {\n const levels = parsePath(path);\n if (\n levels.length !== accountLevels.length + 2 ||\n !accountLevels.every(\n (l, i) => levels[i]!.index === l.index && levels[i]!.hardened === l.hardened,\n ) ||\n levels.slice(accountLevels.length).some((l) => l.hardened)\n ) {\n return failed(\n `signer path ${path} does not extend the account path with two soft components`,\n );\n }\n const tail = levels.slice(accountLevels.length).map((l) => l.index);\n const vkey = cardanoSoftDerivePath(args.account.publicKey, args.account.chainCode, tail);\n expected.set(bytesToHex(vkey), path);\n }\n // Every requested path must have produced a witness…\n for (const [vkeyHex, path] of expected) {\n if (!witnesses.some((w) => bytesToHex(w.vkey) === vkeyHex)) {\n return failed(`no witness for the requested signer path ${path}`);\n }\n }\n // …and every witness must belong to a requested path (no foreign keys).\n for (const witness of witnesses) {\n if (!expected.has(bytesToHex(witness.vkey))) {\n return failed('the witness set carries a key your request did not ask for');\n }\n }\n }\n return verified;\n}\n\n// ---------------------------------------------------------------------------\n// CBOR item walker: the encoded extent of the first element of a CBOR array.\n// Supports definite AND indefinite lengths (wallet-produced tx CBOR may use\n// either), with depth/size hardening.\n// ---------------------------------------------------------------------------\n\nexport function firstArrayItemBytes(bytes: Uint8Array): Uint8Array {\n const top = bytes[0];\n if (top === undefined) throw new Error('empty input');\n const major = top >> 5;\n if (major !== 4) throw new Error('not a CBOR array');\n let start: number;\n if ((top & 0x1f) === 31) {\n start = 1; // indefinite array\n } else {\n const head = readHead(bytes, 0);\n if (head.value === 0n) throw new Error('transaction array is empty');\n start = head.next;\n }\n const end = skipItem(bytes, start, 0);\n return bytes.slice(start, end);\n}\n\nfunction readHead(bytes: Uint8Array, offset: number): { value: bigint; next: number } {\n const initial = bytes[offset];\n if (initial === undefined) throw new Error('truncated');\n const info = initial & 0x1f;\n if (info < 24) return { value: BigInt(info), next: offset + 1 };\n if (info === 31) return { value: -1n, next: offset + 1 }; // indefinite marker\n let width: number;\n if (info === 24) width = 1;\n else if (info === 25) width = 2;\n else if (info === 26) width = 4;\n else if (info === 27) width = 8;\n else throw new Error('reserved length encoding');\n let value = 0n;\n for (let i = 0; i < width; i++) {\n const b = bytes[offset + 1 + i];\n if (b === undefined) throw new Error('truncated');\n value = (value << 8n) | BigInt(b);\n }\n return { value, next: offset + 1 + width };\n}\n\n/** Returns the offset just past the item starting at `offset`. */\nfunction skipItem(bytes: Uint8Array, offset: number, depth: number): number {\n if (depth > 32) throw new Error('nesting too deep');\n const initial = bytes[offset];\n if (initial === undefined) throw new Error('truncated');\n const major = initial >> 5;\n const head = readHead(bytes, offset);\n\n switch (major) {\n case 0:\n case 1:\n if (head.value === -1n) throw new Error('malformed integer');\n return head.next;\n case 2:\n case 3: {\n if (head.value === -1n) {\n // Indefinite string: chunks until 0xFF.\n let pos = head.next;\n while (bytes[pos] !== 0xff) {\n const chunk = readHead(bytes, pos);\n if (chunk.value < 0n) throw new Error('malformed chunk');\n pos = chunk.next + Number(chunk.value);\n if (pos > bytes.length) throw new Error('truncated string');\n }\n return pos + 1;\n }\n const end = head.next + Number(head.value);\n if (end > bytes.length) throw new Error('truncated string');\n return end;\n }\n case 4:\n case 5: {\n const perEntry = major === 5 ? 2 : 1;\n if (head.value === -1n) {\n let pos = head.next;\n while (bytes[pos] !== 0xff) {\n for (let i = 0; i < perEntry; i++) pos = skipItem(bytes, pos, depth + 1);\n }\n return pos + 1;\n }\n let pos = head.next;\n const count = Number(head.value) * perEntry;\n if (count > 1_000_000) throw new Error('container too large');\n for (let i = 0; i < count; i++) pos = skipItem(bytes, pos, depth + 1);\n return pos;\n }\n case 6:\n if (head.value === -1n) throw new Error('malformed tag');\n return skipItem(bytes, head.next, depth + 1);\n case 7:\n if ((initial & 0x1f) === 31) throw new Error('unexpected break');\n if ((initial & 0x1f) === 25) return offset + 3;\n if ((initial & 0x1f) === 26) return offset + 5;\n if ((initial & 0x1f) === 27) return offset + 9;\n return head.next;\n default:\n throw new Error('unreachable');\n }\n}\n","import { secp256k1 } from '@noble/curves/secp256k1';\nimport { sha256 } from '@noble/hashes/sha2';\nimport { keccak_256 } from '@noble/hashes/sha3';\nimport { equalBytes } from '../core/bytes';\nimport type { VerifyResult } from './result';\nimport { failed, verified } from './result';\n\nexport interface VerifyCosmosSignatureArgs {\n /** The exact SignDoc bytes the request carried. */\n readonly signData: Uint8Array;\n /**\n * Digest family: vanilla Cosmos zones hash with sha256; Ethermint chains\n * (Injective, Evmos, Dymension) with keccak256.\n */\n readonly digest: 'sha256' | 'keccak256';\n /** 64-byte compact signature from the reply. */\n readonly signature: Uint8Array;\n /** 33-byte compressed public key (from the reply, or derived from your linked xpub). */\n readonly publicKey: Uint8Array;\n /** Optional binding: the key you EXPECT (derived from the linked account). */\n readonly expectedPublicKey?: Uint8Array;\n}\n\nexport function verifyCosmosSignature(args: VerifyCosmosSignatureArgs): VerifyResult {\n if (args.signature.length !== 64) return failed('signature must be 64 bytes (compact r||s)');\n if (args.publicKey.length !== 33) return failed('publicKey must be 33 bytes (compressed)');\n if (args.expectedPublicKey !== undefined && !equalBytes(args.publicKey, args.expectedPublicKey)) {\n return failed('the reply public key is not the linked account key');\n }\n const digest = args.digest === 'keccak256' ? keccak_256(args.signData) : sha256(args.signData);\n let ok: boolean;\n try {\n ok = secp256k1.verify(args.signature, digest, args.publicKey);\n } catch (e) {\n return failed(`Cosmos signature could not be checked: ${(e as Error).message}`);\n }\n return ok ? verified : failed('the signature does not belong to this account');\n}\n","import { secp256k1 } from '@noble/curves/secp256k1';\nimport { keccak_256 } from '@noble/hashes/sha3';\nimport { EvmDataType, foldRecoveryId } from '../chains/evm';\nimport { bytesToHex, concatBytes, equalBytes, hexToBytes, utf8Encode } from '../core/bytes';\nimport type { VerifyResult } from './result';\nimport { failed, unverifiable, verified } from './result';\n\nexport interface VerifyEvmSignatureArgs {\n /** The exact bytes the request carried in `signData`. */\n readonly signData: Uint8Array;\n readonly dataType: EvmDataType;\n /** Raw `r || s || v` from the reply (65+ bytes; multi-byte legacy `v` handled). */\n readonly signature: Uint8Array;\n /** The signer address the request was built for. */\n readonly address: Uint8Array | `0x${string}`;\n /**\n * Optional: the signing payload re-derived from the transaction you are\n * ABOUT TO BROADCAST. Recovering against `signData` alone proves the device\n * signed something you asked for — this closes the second half: that it is\n * the transaction still in your hands (payloads can legitimately change\n * between build and send, e.g. a blockhash refresh in your own state).\n */\n readonly reEncodedSignData?: Uint8Array;\n}\n\n/** EIP-191: 0x19 || \"Ethereum Signed Message:\\n\" || len(message). */\nfunction personalSignDigest(message: Uint8Array): Uint8Array {\n const prefix = utf8Encode(`Ethereum Signed Message:\\n${message.length}`);\n return keccak_256(concatBytes(new Uint8Array([0x19]), prefix, message));\n}\n\n/**\n * \"Did the device sign exactly what I sent, with the key I expected?\"\n * keccak digest + public-key recovery; the recovered address must equal the\n * request's. Run it before broadcasting.\n */\nexport function verifyEvmSignature(args: VerifyEvmSignatureArgs): VerifyResult {\n if (args.signature.length < 65) {\n return failed('signature is shorter than 65 bytes');\n }\n if (args.reEncodedSignData !== undefined && !equalBytes(args.reEncodedSignData, args.signData)) {\n return failed('the transaction to broadcast is not the one the device signed');\n }\n\n let digest: Uint8Array;\n switch (args.dataType) {\n case EvmDataType.transaction:\n case EvmDataType.typedTransaction:\n digest = keccak_256(args.signData);\n break;\n case EvmDataType.personalMessage:\n digest = personalSignDigest(args.signData);\n break;\n case EvmDataType.typedData:\n return unverifiable(\n 'EIP-712: the digest is the hash of the structure, computed only on the device',\n );\n default:\n return failed(`unknown dataType ${args.dataType satisfies never}`);\n }\n\n let vBig = 0n;\n for (const b of args.signature.slice(64)) vBig = (vBig << 8n) | BigInt(b);\n const recoveryId = foldRecoveryId(vBig);\n if (recoveryId !== 0 && recoveryId !== 1) {\n return failed('implausible recovery value');\n }\n\n let recovered: Uint8Array;\n try {\n const point = secp256k1.Signature.fromCompact(args.signature.slice(0, 64))\n .addRecoveryBit(recoveryId)\n .recoverPublicKey(digest);\n recovered = keccak_256(point.toRawBytes(false).slice(1)).slice(12);\n } catch (e) {\n return failed(`signature could not be checked: ${(e as Error).message}`);\n }\n\n const expected = args.address instanceof Uint8Array ? args.address : hexToBytes(args.address);\n if (expected.length !== 20) {\n return failed(`expected address must be 20 bytes, got ${expected.length}`);\n }\n if (!equalBytes(recovered, expected)) {\n return failed(\n `the signature does not belong to this account (recovered 0x${bytesToHex(recovered)})`,\n );\n }\n return verified;\n}\n","import { ed25519 } from '@noble/curves/ed25519';\nimport { equalBytes } from '../core/bytes';\nimport type { VerifyResult } from './result';\nimport { failed, verified } from './result';\n\nexport interface VerifySolanaSignatureArgs {\n /** The exact bytes the request carried in `signData` (the compiled message). */\n readonly signData: Uint8Array;\n /** 64-byte Ed25519 signature from the reply. */\n readonly signature: Uint8Array;\n /** The 32-byte signer public key the request was built for. */\n readonly publicKey: Uint8Array;\n /**\n * Optional: the message bytes you are ABOUT TO BROADCAST. Matters most on\n * Solana — a blockhash refresh between build and send makes \"what was\n * signed\" and \"what will be sent\" two different objects that must agree.\n */\n readonly broadcastMessageBytes?: Uint8Array;\n}\n\nexport function verifySolanaSignature(args: VerifySolanaSignatureArgs): VerifyResult {\n if (\n args.broadcastMessageBytes !== undefined &&\n !equalBytes(args.broadcastMessageBytes, args.signData)\n ) {\n return failed('the message to broadcast is not the one the device signed');\n }\n let ok: boolean;\n try {\n ok = ed25519.verify(args.signature, args.signData, args.publicKey);\n } catch (e) {\n return failed(`Solana signature could not be checked: ${(e as Error).message}`);\n }\n return ok ? verified : failed('the signature does not belong to this account');\n}\n","import { ed25519 } from '@noble/curves/ed25519';\nimport { suiIntentDigest } from '../chains/sui';\nimport { equalBytes } from '../core/bytes';\nimport type { VerifyResult } from './result';\nimport { failed, verified } from './result';\n\nexport interface VerifySuiSignatureArgs {\n /** The intent message the request carried (or pass `messageHash` for the hash variant). */\n readonly intentMessage?: Uint8Array;\n readonly messageHash?: Uint8Array;\n /** 64-byte Ed25519 signature from the reply. */\n readonly signature: Uint8Array;\n /** The signer key the reply carried. */\n readonly publicKey: Uint8Array;\n /** The linked account's key (`accounts.sui()[i].publicKey`) — binds the reply to YOUR wallet. */\n readonly expectedPublicKey?: Uint8Array;\n}\n\n/** BLAKE2b-256 of the intent message (or the given hash) + Ed25519 verification. */\nexport function verifySuiSignature(args: VerifySuiSignatureArgs): VerifyResult {\n let digest: Uint8Array;\n if (args.messageHash !== undefined) {\n if (args.messageHash.length !== 32) return failed('messageHash must be 32 bytes');\n digest = args.messageHash;\n } else if (args.intentMessage !== undefined) {\n digest = suiIntentDigest(args.intentMessage);\n } else {\n return failed('provide intentMessage or messageHash');\n }\n if (args.expectedPublicKey !== undefined && !equalBytes(args.publicKey, args.expectedPublicKey)) {\n return failed('the reply public key is not the linked account key');\n }\n let ok: boolean;\n try {\n ok = ed25519.verify(args.signature, digest, args.publicKey);\n } catch (e) {\n return failed(`Sui signature could not be checked: ${(e as Error).message}`);\n }\n return ok ? verified : failed('the signature does not belong to this account');\n}\n","import { sha256 } from '@noble/hashes/sha2';\nimport { concatBytes } from '../core/bytes';\nimport { EraSdkError } from '../core/errors';\n\n/**\n * Minimal TON Bag-of-Cells reader + cell representation hash — exactly the\n * subset the device's signer implements: generic BoC, ordinary level-0 cells,\n * first root. The transaction digest the device signs IS the root cell's\n * representation hash, so this must agree with the firmware bit for bit.\n *\n * Hardened for scanned/untrusted input: size caps, bounds checks, and\n * forward-only references (the standard BoC topological order; a backward\n * reference would make the single-pass hash read an uncomputed child).\n */\n\nconst BOC_MAGIC = 0xb5ee9c72;\nconst MAX_CELLS = 256;\nconst MAX_CELL_DATA_BYTES = 128;\nconst MAX_REFS = 4;\n\ninterface Cell {\n dataBits: number;\n data: Uint8Array;\n refs: number[];\n depth: number;\n hash: Uint8Array;\n}\n\nfunction err(message: string): EraSdkError {\n return new EraSdkError('malformed-reply', `ton boc: ${message}`);\n}\n\n/** Representation hash of the ROOT cell of a BoC — the bytes TON signs. */\nexport function bocRootHash(boc: Uint8Array): Uint8Array {\n if (boc.length < 10) throw err('too short');\n const magic = ((boc[0]! << 24) | (boc[1]! << 16) | (boc[2]! << 8) | boc[3]!) >>> 0;\n if (magic !== BOC_MAGIC) throw err('not a generic BoC');\n\n const flags = boc[4]!;\n const hasIdx = (flags >> 7) & 1;\n const refSize = flags & 0x07;\n const offSize = boc[5]!;\n if (refSize === 0 || refSize > 4) throw err('bad ref size');\n if (offSize === 0 || offSize > 8) throw err('bad offset size');\n\n let pos = 6;\n const readInt = (byteLen: number): number => {\n let value = 0;\n for (let i = 0; i < byteLen; i++) {\n if (pos >= boc.length) throw err('truncated header');\n value = value * 256 + boc[pos++]!;\n }\n if (!Number.isSafeInteger(value)) throw err('header value out of range');\n return value;\n };\n\n const cellCount = readInt(refSize);\n const rootCount = readInt(refSize);\n readInt(refSize); // absent count\n readInt(offSize); // total cell data size\n if (rootCount === 0) throw err('no roots');\n if (cellCount === 0 || cellCount > MAX_CELLS) throw err('cell count out of range');\n\n const rootIndex = readInt(refSize);\n for (let i = 1; i < rootCount; i++) readInt(refSize); // remaining root indices\n if (rootIndex >= cellCount) throw err('root index out of range');\n if (hasIdx) pos += cellCount * offSize; // skip the offsets index\n\n const cells: Cell[] = [];\n for (let i = 0; i < cellCount; i++) {\n if (pos + 2 > boc.length) throw err('truncated cell');\n const d1 = boc[pos++]!;\n const d2 = boc[pos++]!;\n const refCount = d1 & 0x07;\n if (refCount > MAX_REFS) throw err('too many references');\n\n const dataByteLen = (d2 + 1) >> 1;\n const incomplete = (d2 & 1) === 1;\n if (dataByteLen > MAX_CELL_DATA_BYTES) throw err('cell data too large');\n if (pos + dataByteLen > boc.length) throw err('truncated cell data');\n const data = boc.slice(pos, pos + dataByteLen);\n pos += dataByteLen;\n\n // Bit length from the completion tag (last set bit marks the end).\n let dataBits: number;\n if (incomplete && dataByteLen > 0) {\n const last = data[dataByteLen - 1]!;\n if (last === 0) {\n dataBits = (dataByteLen - 1) * 8;\n } else {\n let trailingZeros = 0;\n for (let b = 0; b < 8; b++) {\n if (last & (1 << b)) break;\n trailingZeros++;\n }\n dataBits = dataByteLen * 8 - 1 - trailingZeros;\n }\n } else {\n dataBits = dataByteLen * 8;\n }\n\n const refs: number[] = [];\n for (let r = 0; r < refCount; r++) {\n const ref = readInt(refSize);\n if (ref >= cellCount) throw err('reference out of range');\n if (ref <= i) throw err('non-topological cell reference');\n refs.push(ref);\n }\n cells.push({ dataBits, data, refs, depth: 0, hash: new Uint8Array(0) });\n }\n\n // Bottom-up (children first — guaranteed by the forward-only reference check).\n for (let i = cellCount - 1; i >= 0; i--) {\n const cell = cells[i]!;\n let maxChildDepth = -1;\n for (const r of cell.refs) {\n maxChildDepth = Math.max(maxChildDepth, cells[r]!.depth);\n }\n cell.depth = cell.refs.length === 0 ? 0 : maxChildDepth + 1;\n\n const dataBytes = (cell.dataBits + 7) >> 3;\n const incomplete = cell.dataBits % 8 !== 0;\n const repr: number[] = [cell.refs.length, dataBytes * 2 - (incomplete ? 1 : 0)];\n for (let b = 0; b < dataBytes; b++) repr.push(cell.data[b] ?? 0);\n if (incomplete && dataBytes > 0) {\n const shift = 7 - (cell.dataBits % 8);\n const last = repr.length - 1;\n repr[last] = (repr[last]! | (1 << shift)) & (0xff << shift) & 0xff;\n }\n for (const r of cell.refs) {\n repr.push((cells[r]!.depth >> 8) & 0xff, cells[r]!.depth & 0xff);\n }\n let bytes: Uint8Array = new Uint8Array(repr);\n for (const r of cell.refs) bytes = concatBytes(bytes, cells[r]!.hash);\n cell.hash = sha256(bytes);\n }\n\n return cells[rootIndex]!.hash;\n}\n","import { ed25519 } from '@noble/curves/ed25519';\nimport { sha256 } from '@noble/hashes/sha2';\nimport { TonDataType } from '../chains/ton';\nimport { concatBytes, utf8Encode } from '../core/bytes';\nimport type { VerifyResult } from './result';\nimport { failed, verified } from './result';\nimport { bocRootHash } from './ton-boc';\n\nexport interface VerifyTonSignatureArgs {\n /** The exact bytes the request carried in `signData`. */\n readonly signData: Uint8Array;\n readonly dataType: TonDataType;\n /** 64-byte Ed25519 signature from the reply. */\n readonly signature: Uint8Array;\n /** The 32-byte signer public key from linking (`accounts.ton()`). */\n readonly publicKey: Uint8Array;\n}\n\n/**\n * Recompute the exact digest the device signs — the BoC ROOT CELL's\n * representation hash for a transaction, or the TON Connect proof digest\n * `sha256(0xFFFF || \"ton-connect\" || sha256(payload))` — and verify the\n * Ed25519 signature against the linked key.\n */\nexport function verifyTonSignature(args: VerifyTonSignatureArgs): VerifyResult {\n if (args.signature.length !== 64) return failed('signature must be 64 bytes');\n if (args.publicKey.length !== 32) return failed('public key must be 32 bytes');\n\n let digest: Uint8Array;\n if (args.dataType === TonDataType.tonProof) {\n digest = sha256(\n concatBytes(new Uint8Array([0xff, 0xff]), utf8Encode('ton-connect'), sha256(args.signData)),\n );\n } else if (args.dataType === TonDataType.transaction) {\n try {\n digest = bocRootHash(args.signData);\n } catch (e) {\n return failed(`signData is not a readable BoC: ${(e as Error).message}`);\n }\n } else {\n return failed(`unknown dataType ${args.dataType satisfies never}`);\n }\n\n let ok: boolean;\n try {\n ok = ed25519.verify(args.signature, digest, args.publicKey);\n } catch (e) {\n return failed(`TON signature could not be checked: ${(e as Error).message}`);\n }\n return ok ? verified : failed('the signature does not belong to this account');\n}\n","import { secp256k1 } from '@noble/curves/secp256k1';\nimport { sha256 } from '@noble/hashes/sha2';\nimport { keccak_256 } from '@noble/hashes/sha3';\nimport { createBase58check } from '@scure/base';\nimport { concatBytes, equalBytes, utf8Decode } from '../core/bytes';\nimport type { SignedTronTx, TronLatestBlock } from '../tron-proto/messages';\nimport { splitSignedTronTx } from '../tron-proto/messages';\nimport { firstBytes, firstVarint, readFields } from '../tron-proto/wire';\nimport type { VerifyResult } from './result';\nimport { failed, verified } from './result';\n\nconst base58check = createBase58check(sha256);\n\nexport interface VerifyTronSignatureArgs {\n /** The `raw_data` bytes the request carried. */\n readonly rawData: Uint8Array;\n /** The base58 owner address the transaction spends from. */\n readonly from: string;\n /** The reference block the request carried (enables the rebuild-path window check). */\n readonly latestBlock?: TronLatestBlock;\n /** The reply: either the split frame from `TronSignatureResult.signedTx`, or the raw hex. */\n readonly signedTx: SignedTronTx | string;\n}\n\n/**\n * The Tron reply is a fully signed transaction broadcast VERBATIM, so it is\n * checked on both counts: every signature must recover to the owner address,\n * and the transaction must move what the user approved.\n *\n * Byte equality with the request's `rawData` is the strong form. When the\n * bytes differ (a firmware that rebuilds `raw_data` from the semantic\n * fields), the fallback compares the fields that decide where the money goes,\n * plus the validity window against the reference block.\n */\nexport function verifyTronSignature(args: VerifyTronSignatureArgs): VerifyResult {\n let signedTx: SignedTronTx;\n try {\n signedTx = typeof args.signedTx === 'string' ? splitSignedTronTx(args.signedTx) : args.signedTx;\n } catch (e) {\n return failed(`the returned Tron transaction is not readable: ${(e as Error).message}`);\n }\n if (signedTx.signatures.length === 0) {\n return failed('the returned Tron transaction carries no signature');\n }\n if (!args.from) {\n return failed('no owner address to check the signature against');\n }\n\n const digest = sha256(signedTx.rawData);\n for (const signature of signedTx.signatures) {\n const recovered = recoverTronAddress(digest, signature);\n if (recovered === null) return failed('signature could not be checked');\n if (recovered !== args.from) {\n return failed('the signature does not belong to this account');\n }\n }\n\n if (equalBytes(signedTx.rawData, args.rawData)) return verified;\n\n // Rebuild path: the firmware built its own raw_data from the semantic\n // fields. Compare the operation, then the validity window.\n const contractResult = compareContracts(args.rawData, signedTx.rawData);\n if (contractResult !== null) return contractResult;\n if (args.latestBlock === undefined) {\n return failed(\n 'the returned raw_data differs from the request and no latestBlock was provided to check the validity window',\n );\n }\n return compareWindow(signedTx.rawData, args.latestBlock);\n}\n\nfunction recoverTronAddress(digest: Uint8Array, signature: Uint8Array): string | null {\n if (signature.length < 65) return null;\n const recovery = signature[64]!;\n const recoveryId = recovery >= 27 ? (recovery - 27) & 1 : recovery & 1;\n try {\n const point = secp256k1.Signature.fromCompact(signature.slice(0, 64))\n .addRecoveryBit(recoveryId)\n .recoverPublicKey(digest);\n const hash = keccak_256(point.toRawBytes(false).slice(1));\n return base58check.encode(concatBytes(new Uint8Array([0x41]), hash.slice(12)));\n } catch {\n return null;\n }\n}\n\n// --- raw_data structural comparison ---------------------------------------\n\ninterface TronContract {\n readonly typeUrl: string;\n readonly type: bigint;\n readonly parameter: Uint8Array;\n}\n\ninterface TronRawData {\n readonly contracts: readonly TronContract[];\n readonly expiration: bigint;\n readonly timestamp: bigint;\n}\n\nfunction parseRawData(bytes: Uint8Array): TronRawData | null {\n try {\n const fields = readFields(bytes);\n const contracts: TronContract[] = [];\n for (const f of fields) {\n if (f.field === 11 && f.wireType === 2) {\n const c = readFields(f.bytes);\n const anyBytes = firstBytes(c, 2);\n const any = anyBytes ? readFields(anyBytes) : [];\n const typeUrlBytes = anyBytes ? firstBytes(any, 1) : null;\n contracts.push({\n typeUrl: typeUrlBytes ? utf8Decode(typeUrlBytes) : '',\n type: firstVarint(c, 1) ?? 0n,\n parameter: (anyBytes && firstBytes(any, 2)) || new Uint8Array(0),\n });\n }\n }\n return {\n contracts,\n expiration: firstVarint(fields, 8) ?? 0n,\n timestamp: firstVarint(fields, 14) ?? 0n,\n };\n } catch {\n return null;\n }\n}\n\n/** null = contracts match (continue to the window check); a result = verdict. */\nfunction compareContracts(askedBytes: Uint8Array, repliedBytes: Uint8Array): VerifyResult | null {\n const asked = parseRawData(askedBytes);\n const replied = parseRawData(repliedBytes);\n if (!asked) return failed('the Tron transaction built by the app could not be read');\n if (!replied) return failed('the Tron transaction built by the device could not be read');\n if (asked.contracts.length !== 1 || replied.contracts.length !== 1) {\n return failed('the Tron transaction does not carry exactly one contract');\n }\n const a = asked.contracts[0]!;\n const b = replied.contracts[0]!;\n const kindA = contractKind(a);\n const kindB = contractKind(b);\n if (kindA !== kindB) {\n return failed('the returned Tron transaction is a different kind of operation');\n }\n\n const pa = readFieldsSafe(a.parameter);\n const pb = readFieldsSafe(b.parameter);\n if (!pa || !pb) return failed('the Tron contract parameters could not be read');\n\n switch (kindA) {\n case 'transfer':\n // TransferContract {1: owner, 2: to, 3: amount}\n if (\n sameBytesField(pa, pb, 1) &&\n sameBytesField(pa, pb, 2) &&\n (firstVarint(pa, 3) ?? 0n) === (firstVarint(pb, 3) ?? 0n)\n ) {\n return null;\n }\n break;\n case 'transferAsset':\n // TransferAssetContract {1: asset, 2: owner, 3: to, 4: amount}\n if (\n sameBytesField(pa, pb, 1) &&\n sameBytesField(pa, pb, 2) &&\n sameBytesField(pa, pb, 3) &&\n (firstVarint(pa, 4) ?? 0n) === (firstVarint(pb, 4) ?? 0n)\n ) {\n return null;\n }\n break;\n case 'triggerSmartContract':\n // TriggerSmartContract {1: owner, 2: contract, 3: call_value, 4: data}.\n // call_value: zero and absent are the same thing — the two sides are\n // serialized by different protobuf writers that disagree on whether a\n // zero scalar is written, and every TRC-20 transfer carries call_value 0.\n if (\n sameBytesField(pa, pb, 1) &&\n sameBytesField(pa, pb, 2) &&\n (firstVarint(pa, 3) ?? 0n) === (firstVarint(pb, 3) ?? 0n) &&\n sameBytesField(pa, pb, 4)\n ) {\n return null;\n }\n break;\n default:\n // An operation this gate cannot compare field by field is not waved\n // through: without byte equality there is nothing left to bind it to\n // what the user approved.\n return failed('the returned Tron transaction carries an operation this check cannot compare');\n }\n return failed('the returned Tron transaction does not match the one approved');\n}\n\ntype ContractKind = 'transfer' | 'transferAsset' | 'triggerSmartContract' | 'other';\n\nfunction contractKind(contract: TronContract): ContractKind {\n if (contract.typeUrl.endsWith('.TransferContract') || contract.type === 1n) return 'transfer';\n if (contract.typeUrl.endsWith('.TransferAssetContract') || contract.type === 2n) {\n return 'transferAsset';\n }\n if (contract.typeUrl.endsWith('.TriggerSmartContract') || contract.type === 31n) {\n return 'triggerSmartContract';\n }\n return 'other';\n}\n\nfunction readFieldsSafe(bytes: Uint8Array): ReturnType<typeof readFields> | null {\n try {\n return readFields(bytes);\n } catch {\n return null;\n }\n}\n\nfunction sameBytesField(\n a: ReturnType<typeof readFields>,\n b: ReturnType<typeof readFields>,\n field: number,\n): boolean {\n const x = firstBytes(a, field) ?? new Uint8Array(0);\n const y = firstBytes(b, field) ?? new Uint8Array(0);\n return equalBytes(x, y);\n}\n\n/**\n * Firmware formulas, not policy: the two device-side transaction builders\n * stamp `timestamp` with the request's reference-block timestamp verbatim and\n * set `expiration` to +10 minutes (one builder) or +10 hours (the other). A\n * range spanning both cannot refuse a reply the live fleet produces.\n */\nconst MIN_EXPIRY_MS = 10n * 60n * 1000n;\nconst MAX_EXPIRY_MS = 10n * 60n * 60n * 1000n;\n\nfunction compareWindow(repliedBytes: Uint8Array, latestBlock: TronLatestBlock): VerifyResult {\n const replied = parseRawData(repliedBytes);\n if (!replied) return failed('the Tron transaction built by the device could not be read');\n const block = BigInt(latestBlock.timestamp);\n if (replied.timestamp !== block) {\n return failed(\n 'the returned Tron transaction is stamped against a different reference block than the one we sent',\n );\n }\n const validFor = replied.expiration - block;\n if (validFor < MIN_EXPIRY_MS || validFor > MAX_EXPIRY_MS) {\n return failed(\n `the returned Tron transaction is valid for ${validFor} ms after the reference block, outside the firmware's ${MIN_EXPIRY_MS}-${MAX_EXPIRY_MS} ms window`,\n );\n }\n return verified;\n}\n","import { secp256k1 } from '@noble/curves/secp256k1';\nimport { sha512 } from '@noble/hashes/sha2';\nimport { bytesToHex, concatBytes, equalBytes, hexToBytes } from '../core/bytes';\nimport type { VerifyResult } from './result';\nimport { failed, unverifiable, verified } from './result';\n\nexport interface VerifyXrpSignatureArgs {\n /** The signed binary transaction from the reply. */\n readonly signedTx: Uint8Array;\n /** The `SigningPubKey` hex your request JSON carried (33-byte compressed secp256k1). */\n readonly expectedSigningPubKey: string;\n}\n\n/**\n * XRP has no request id — this check IS the binding. The signed binary is\n * split into its canonical fields; `TxnSignature` is removed; the remainder\n * (prefixed with the XRPL signing tag `STX\\0`) is hashed with SHA-512-half\n * and the DER signature is verified against `SigningPubKey`, which must also\n * equal the key your request carried.\n *\n * The field walker covers the types Payment-class transactions use; a\n * transaction carrying an exotic field type comes back `checked: false`\n * rather than a false verdict.\n */\nexport function verifyXrpSignature(args: VerifyXrpSignatureArgs): VerifyResult {\n let fields: XrpField[];\n try {\n fields = splitFields(args.signedTx);\n } catch (e) {\n const message = (e as Error).message;\n if (message === 'unsupported-field') {\n return unverifiable('the transaction carries a field type this checker does not walk');\n }\n return failed(`the signed transaction is not readable: ${message}`);\n }\n\n const signingPubKey = fields.find((f) => f.header === 0x73);\n const txnSignature = fields.find((f) => f.header === 0x74);\n if (!signingPubKey || !txnSignature) {\n return failed('the signed transaction is missing SigningPubKey or TxnSignature');\n }\n const expected = hexToBytes(args.expectedSigningPubKey);\n if (!equalBytes(signingPubKey.value, expected)) {\n return failed(\n `the transaction was signed with a different key (${bytesToHex(signingPubKey.value)})`,\n );\n }\n\n // Signing payload: every field except TxnSignature, in the original\n // (canonical) order, behind the 'STX\\0' prefix; SHA-512 halved.\n const payload = concatBytes(\n new Uint8Array([0x53, 0x54, 0x58, 0x00]),\n ...fields.filter((f) => f.header !== 0x74).map((f) => f.raw),\n );\n const digest = sha512(payload).slice(0, 32);\n\n let ok: boolean;\n try {\n ok = secp256k1.verify(\n secp256k1.Signature.fromDER(txnSignature.value).toCompactRawBytes(),\n digest,\n expected,\n );\n } catch (e) {\n return failed(`XRP signature could not be checked: ${(e as Error).message}`);\n }\n return ok ? verified : failed('the signature does not verify against SigningPubKey');\n}\n\ninterface XrpField {\n /** One-byte header for the common fields (0x73 SigningPubKey, 0x74 TxnSignature). */\n readonly header: number;\n /** The field's VALUE bytes (VL prefix stripped for blob-like types). */\n readonly value: Uint8Array;\n /** The complete encoded field, header + length + value. */\n readonly raw: Uint8Array;\n}\n\n/** Split a canonical STObject into its top-level fields. */\nfunction splitFields(bytes: Uint8Array): XrpField[] {\n const fields: XrpField[] = [];\n let pos = 0;\n while (pos < bytes.length) {\n const field = parseField(bytes, pos);\n fields.push(field.field);\n pos = field.end;\n }\n return fields;\n}\n\n/** Parse ONE field at `pos`; returns the field and the offset past it. */\nfunction parseField(bytes: Uint8Array, pos: number): { field: XrpField; end: number } {\n const start = pos;\n const first = bytes[pos++];\n if (first === undefined) throw new Error('truncated');\n let type = first >> 4;\n let fieldCode = first & 0x0f;\n if (type === 0) {\n const t = bytes[pos++];\n if (t === undefined) throw new Error('truncated type');\n type = t;\n }\n if (fieldCode === 0) {\n const f = bytes[pos++];\n if (f === undefined) throw new Error('truncated field code');\n fieldCode = f;\n }\n\n let valueStart = pos;\n switch (type) {\n case 1: // UInt16\n pos += 2;\n break;\n case 2: // UInt32\n pos += 4;\n break;\n case 5: // Hash256\n pos += 32;\n break;\n case 6: {\n // Amount: native XRP = 8 bytes; issued currency = 48 bytes.\n const head = bytes[pos];\n if (head === undefined) throw new Error('truncated amount');\n pos += (head & 0x80) !== 0 ? 48 : 8;\n break;\n }\n case 7: // Blob (VL)\n case 8: {\n // AccountID (VL)\n const vl = readVl(bytes, pos);\n valueStart = vl.next;\n pos = vl.next + vl.length;\n break;\n }\n case 14: {\n // STObject: nested fields until the end marker 0xE1.\n while (bytes[pos] !== 0xe1) {\n if (pos >= bytes.length) throw new Error('unterminated inner object');\n pos = parseField(bytes, pos).end;\n }\n pos += 1;\n break;\n }\n case 15: {\n // STArray: a sequence of inner-object fields until 0xF1.\n while (bytes[pos] !== 0xf1) {\n if (pos >= bytes.length) throw new Error('unterminated array');\n pos = parseField(bytes, pos).end;\n }\n pos += 1;\n break;\n }\n default:\n throw new Error('unsupported-field');\n }\n if (pos > bytes.length) throw new Error('truncated field');\n return {\n field: {\n header: (type << 4) | (fieldCode <= 15 ? fieldCode : 0),\n value: bytes.slice(valueStart, pos),\n raw: bytes.slice(start, pos),\n },\n end: pos,\n };\n}\n\n/** XRPL variable-length prefix. */\nfunction readVl(bytes: Uint8Array, pos: number): { length: number; next: number } {\n const b1 = bytes[pos];\n if (b1 === undefined) throw new Error('truncated length');\n if (b1 <= 192) return { length: b1, next: pos + 1 };\n if (b1 <= 240) {\n const b2 = bytes[pos + 1];\n if (b2 === undefined) throw new Error('truncated length');\n return { length: 193 + (b1 - 193) * 256 + b2, next: pos + 2 };\n }\n const b2 = bytes[pos + 1];\n const b3 = bytes[pos + 2];\n if (b2 === undefined || b3 === undefined) throw new Error('truncated length');\n return { length: 12481 + (b1 - 241) * 65536 + b2 * 256 + b3, next: pos + 3 };\n}\n"],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { _ as Ur, a as SignRequest, r as EraConnectConfig } from "./shared-CI8zhQiE.cjs";
2
+ //#region src/chains/xrp.d.ts
3
+ /**
4
+ * XRP rides the XRP Toolkit convention: an untyped `ur:bytes` whose CBOR
5
+ * payload is the transaction JSON (request) or the canonical signed XRPL
6
+ * binary (reply). There is NO request id and NO chain-specific UR type — the
7
+ * content itself is the only binding, which is why `verifyXrpSignature`
8
+ * (from `@hwlt/era-connect/verify`) is not optional on this chain.
9
+ */
10
+ interface XrpSignRequestProps {
11
+ /**
12
+ * The unsigned transaction JSON. MUST already carry `SigningPubKey` (the
13
+ * device signs with `m/44'/144'/0'/0/0` — put THAT key's hex here),
14
+ * `TransactionType`, a classic `r…` `Account`, `Fee` and `Sequence`.
15
+ */
16
+ readonly transaction: Record<string, unknown> | string;
17
+ }
18
+ interface XrpSignatureResult {
19
+ /** The canonical signed XRPL binary transaction — submit it verbatim. */
20
+ readonly signedTx: Uint8Array;
21
+ }
22
+ declare class XrpChain {
23
+ private readonly context;
24
+ constructor(config?: EraConnectConfig);
25
+ /** Wrap the tx JSON in the `ur:bytes` request shape. Reply: `ur:bytes` with the signed binary. */
26
+ generateSignRequest(props: XrpSignRequestProps): SignRequest<XrpSignatureResult>;
27
+ /** Parse the `ur:bytes` reply into the signed binary transaction. */
28
+ parseSignature(input: Ur | string): XrpSignatureResult;
29
+ }
30
+ //#endregion
31
+ export { XrpSignRequestProps as n, XrpSignatureResult as r, XrpChain as t };
32
+ //# sourceMappingURL=xrp-BXAeK4iH.d.cts.map
@@ -0,0 +1,52 @@
1
+ const require_shared = require("./shared-Cu2yynP9.cjs");
2
+ //#region src/chains/xrp.ts
3
+ const REPLY_TYPES = ["bytes"];
4
+ var XrpChain = class {
5
+ constructor(config) {
6
+ this.context = require_shared.resolveContext(config);
7
+ }
8
+ /** Wrap the tx JSON in the `ur:bytes` request shape. Reply: `ur:bytes` with the signed binary. */
9
+ generateSignRequest(props) {
10
+ const text = typeof props.transaction === "string" ? props.transaction : JSON.stringify(props.transaction);
11
+ let parsed;
12
+ try {
13
+ parsed = JSON.parse(text);
14
+ } catch {
15
+ throw new require_shared.EraSdkError("invalid-props", "transaction is not valid JSON");
16
+ }
17
+ if (typeof parsed.TransactionType !== "string") throw new require_shared.EraSdkError("invalid-props", "transaction needs a TransactionType");
18
+ if (typeof parsed.Account !== "string" || !parsed.Account.startsWith("r")) throw new require_shared.EraSdkError("invalid-props", "transaction needs a classic r… Account");
19
+ if (typeof parsed.SigningPubKey !== "string" || parsed.SigningPubKey.length === 0) throw new require_shared.EraSdkError("invalid-props", "transaction needs SigningPubKey — the device signs with m/44'/144'/0'/0/0");
20
+ if (parsed.Fee === void 0 || parsed.Sequence === void 0) throw new require_shared.EraSdkError("invalid-props", "transaction needs Fee and Sequence");
21
+ const ur = new require_shared.Ur("bytes", require_shared.cborEncode(require_shared.cbBytes(require_shared.utf8Encode(text))));
22
+ return require_shared.makeSignRequest({
23
+ ur,
24
+ replyTypes: REPLY_TYPES,
25
+ context: this.context,
26
+ parse: (reply) => this.parseSignature(reply)
27
+ });
28
+ }
29
+ /** Parse the `ur:bytes` reply into the signed binary transaction. */
30
+ parseSignature(input) {
31
+ const ur = require_shared.toUr(input);
32
+ require_shared.requireUrType(ur, [...REPLY_TYPES], "xrp reply");
33
+ let decoded;
34
+ try {
35
+ decoded = require_shared.cborDecode(ur.cbor);
36
+ } catch (e) {
37
+ throw new require_shared.EraSdkError("malformed-cbor", `xrp reply: ${e.message}`);
38
+ }
39
+ const bytes = require_shared.asBytes(decoded);
40
+ if (!bytes || bytes.length === 0) throw new require_shared.EraSdkError("malformed-reply", "xrp reply carries no signed transaction bytes");
41
+ return { signedTx: bytes };
42
+ }
43
+ };
44
+ //#endregion
45
+ Object.defineProperty(exports, "XrpChain", {
46
+ enumerable: true,
47
+ get: function() {
48
+ return XrpChain;
49
+ }
50
+ });
51
+
52
+ //# sourceMappingURL=xrp-BrHXUnX5.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xrp-BrHXUnX5.cjs","names":["resolveContext","EraSdkError","UrValue","cborEncode","cbBytes","utf8Encode","makeSignRequest","toUr","cborDecode","asBytes"],"sources":["../src/chains/xrp.ts"],"sourcesContent":["import { cborDecode } from '../cbor/decode';\nimport { cborEncode } from '../cbor/encode';\nimport { asBytes, cbBytes } from '../cbor/model';\nimport { utf8Encode } from '../core/bytes';\nimport { EraSdkError } from '../core/errors';\nimport type { Ur } from '../ur/ur';\nimport { Ur as UrValue } from '../ur/ur';\nimport type { ChainContext, EraConnectConfig, SignRequest } from './shared';\nimport { makeSignRequest, requireUrType, resolveContext, toUr } from './shared';\n\n/**\n * XRP rides the XRP Toolkit convention: an untyped `ur:bytes` whose CBOR\n * payload is the transaction JSON (request) or the canonical signed XRPL\n * binary (reply). There is NO request id and NO chain-specific UR type — the\n * content itself is the only binding, which is why `verifyXrpSignature`\n * (from `@hwlt/era-connect/verify`) is not optional on this chain.\n */\nexport interface XrpSignRequestProps {\n /**\n * The unsigned transaction JSON. MUST already carry `SigningPubKey` (the\n * device signs with `m/44'/144'/0'/0/0` — put THAT key's hex here),\n * `TransactionType`, a classic `r…` `Account`, `Fee` and `Sequence`.\n */\n readonly transaction: Record<string, unknown> | string;\n}\n\nexport interface XrpSignatureResult {\n /** The canonical signed XRPL binary transaction — submit it verbatim. */\n readonly signedTx: Uint8Array;\n}\n\nconst REPLY_TYPES = ['bytes'] as const;\n\nexport class XrpChain {\n private readonly context: ChainContext;\n\n constructor(config?: EraConnectConfig) {\n this.context = resolveContext(config);\n }\n\n /** Wrap the tx JSON in the `ur:bytes` request shape. Reply: `ur:bytes` with the signed binary. */\n generateSignRequest(props: XrpSignRequestProps): SignRequest<XrpSignatureResult> {\n const text =\n typeof props.transaction === 'string' ? props.transaction : JSON.stringify(props.transaction);\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(text) as Record<string, unknown>;\n } catch {\n throw new EraSdkError('invalid-props', 'transaction is not valid JSON');\n }\n // Mirror the device's own acceptance gate so a refusal happens HERE with\n // a reason, not silently on the hardware.\n if (typeof parsed.TransactionType !== 'string') {\n throw new EraSdkError('invalid-props', 'transaction needs a TransactionType');\n }\n if (typeof parsed.Account !== 'string' || !parsed.Account.startsWith('r')) {\n throw new EraSdkError('invalid-props', 'transaction needs a classic r… Account');\n }\n if (typeof parsed.SigningPubKey !== 'string' || parsed.SigningPubKey.length === 0) {\n throw new EraSdkError(\n 'invalid-props',\n \"transaction needs SigningPubKey — the device signs with m/44'/144'/0'/0/0\",\n );\n }\n if (parsed.Fee === undefined || parsed.Sequence === undefined) {\n throw new EraSdkError('invalid-props', 'transaction needs Fee and Sequence');\n }\n\n const ur = new UrValue('bytes', cborEncode(cbBytes(utf8Encode(text))));\n return makeSignRequest({\n ur,\n replyTypes: REPLY_TYPES,\n context: this.context,\n parse: (reply) => this.parseSignature(reply),\n });\n }\n\n /** Parse the `ur:bytes` reply into the signed binary transaction. */\n parseSignature(input: Ur | string): XrpSignatureResult {\n const ur = toUr(input);\n requireUrType(ur, [...REPLY_TYPES], 'xrp reply');\n let decoded: ReturnType<typeof cborDecode>;\n try {\n decoded = cborDecode(ur.cbor);\n } catch (e) {\n throw new EraSdkError('malformed-cbor', `xrp reply: ${(e as Error).message}`);\n }\n const bytes = asBytes(decoded);\n if (!bytes || bytes.length === 0) {\n throw new EraSdkError('malformed-reply', 'xrp reply carries no signed transaction bytes');\n }\n return { signedTx: bytes };\n }\n}\n"],"mappings":";;AA+BA,MAAM,cAAc,CAAC,OAAO;AAE5B,IAAa,WAAb,MAAsB;CAGpB,YAAY,QAA2B;EACrC,KAAK,UAAUA,eAAAA,eAAe,MAAM;CACtC;;CAGA,oBAAoB,OAA6D;EAC/E,MAAM,OACJ,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAK,UAAU,MAAM,WAAW;EAC9F,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,MAAM,IAAI;EAC1B,QAAQ;GACN,MAAM,IAAIC,eAAAA,YAAY,iBAAiB,+BAA+B;EACxE;EAGA,IAAI,OAAO,OAAO,oBAAoB,UACpC,MAAM,IAAIA,eAAAA,YAAY,iBAAiB,qCAAqC;EAE9E,IAAI,OAAO,OAAO,YAAY,YAAY,CAAC,OAAO,QAAQ,WAAW,GAAG,GACtE,MAAM,IAAIA,eAAAA,YAAY,iBAAiB,wCAAwC;EAEjF,IAAI,OAAO,OAAO,kBAAkB,YAAY,OAAO,cAAc,WAAW,GAC9E,MAAM,IAAIA,eAAAA,YACR,iBACA,2EACF;EAEF,IAAI,OAAO,QAAQ,KAAA,KAAa,OAAO,aAAa,KAAA,GAClD,MAAM,IAAIA,eAAAA,YAAY,iBAAiB,oCAAoC;EAG7E,MAAM,KAAK,IAAIC,eAAAA,GAAQ,SAASC,eAAAA,WAAWC,eAAAA,QAAQC,eAAAA,WAAW,IAAI,CAAC,CAAC,CAAC;EACrE,OAAOC,eAAAA,gBAAgB;GACrB;GACA,YAAY;GACZ,SAAS,KAAK;GACd,QAAQ,UAAU,KAAK,eAAe,KAAK;EAC7C,CAAC;CACH;;CAGA,eAAe,OAAwC;EACrD,MAAM,KAAKC,eAAAA,KAAK,KAAK;EACrB,eAAA,cAAc,IAAI,CAAC,GAAG,WAAW,GAAG,WAAW;EAC/C,IAAI;EACJ,IAAI;GACF,UAAUC,eAAAA,WAAW,GAAG,IAAI;EAC9B,SAAS,GAAG;GACV,MAAM,IAAIP,eAAAA,YAAY,kBAAkB,cAAe,EAAY,SAAS;EAC9E;EACA,MAAM,QAAQQ,eAAAA,QAAQ,OAAO;EAC7B,IAAI,CAAC,SAAS,MAAM,WAAW,GAC7B,MAAM,IAAIR,eAAAA,YAAY,mBAAmB,+CAA+C;EAE1F,OAAO,EAAE,UAAU,MAAM;CAC3B;AACF"}
@@ -0,0 +1,47 @@
1
+ import { A as utf8Encode, K as EraSdkError, N as asBytes, _ as Ur, b as cborDecode, l as toUr, n as makeSignRequest, o as requireUrType, s as resolveContext, x as cborEncode, z as cbBytes } from "./shared-Bbgejrus.js";
2
+ //#region src/chains/xrp.ts
3
+ const REPLY_TYPES = ["bytes"];
4
+ var XrpChain = class {
5
+ constructor(config) {
6
+ this.context = resolveContext(config);
7
+ }
8
+ /** Wrap the tx JSON in the `ur:bytes` request shape. Reply: `ur:bytes` with the signed binary. */
9
+ generateSignRequest(props) {
10
+ const text = typeof props.transaction === "string" ? props.transaction : JSON.stringify(props.transaction);
11
+ let parsed;
12
+ try {
13
+ parsed = JSON.parse(text);
14
+ } catch {
15
+ throw new EraSdkError("invalid-props", "transaction is not valid JSON");
16
+ }
17
+ if (typeof parsed.TransactionType !== "string") throw new EraSdkError("invalid-props", "transaction needs a TransactionType");
18
+ if (typeof parsed.Account !== "string" || !parsed.Account.startsWith("r")) throw new EraSdkError("invalid-props", "transaction needs a classic r… Account");
19
+ if (typeof parsed.SigningPubKey !== "string" || parsed.SigningPubKey.length === 0) throw new EraSdkError("invalid-props", "transaction needs SigningPubKey — the device signs with m/44'/144'/0'/0/0");
20
+ if (parsed.Fee === void 0 || parsed.Sequence === void 0) throw new EraSdkError("invalid-props", "transaction needs Fee and Sequence");
21
+ const ur = new Ur("bytes", cborEncode(cbBytes(utf8Encode(text))));
22
+ return makeSignRequest({
23
+ ur,
24
+ replyTypes: REPLY_TYPES,
25
+ context: this.context,
26
+ parse: (reply) => this.parseSignature(reply)
27
+ });
28
+ }
29
+ /** Parse the `ur:bytes` reply into the signed binary transaction. */
30
+ parseSignature(input) {
31
+ const ur = toUr(input);
32
+ requireUrType(ur, [...REPLY_TYPES], "xrp reply");
33
+ let decoded;
34
+ try {
35
+ decoded = cborDecode(ur.cbor);
36
+ } catch (e) {
37
+ throw new EraSdkError("malformed-cbor", `xrp reply: ${e.message}`);
38
+ }
39
+ const bytes = asBytes(decoded);
40
+ if (!bytes || bytes.length === 0) throw new EraSdkError("malformed-reply", "xrp reply carries no signed transaction bytes");
41
+ return { signedTx: bytes };
42
+ }
43
+ };
44
+ //#endregion
45
+ export { XrpChain as t };
46
+
47
+ //# sourceMappingURL=xrp-C8LJO5b-.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xrp-C8LJO5b-.js","names":["UrValue"],"sources":["../src/chains/xrp.ts"],"sourcesContent":["import { cborDecode } from '../cbor/decode';\nimport { cborEncode } from '../cbor/encode';\nimport { asBytes, cbBytes } from '../cbor/model';\nimport { utf8Encode } from '../core/bytes';\nimport { EraSdkError } from '../core/errors';\nimport type { Ur } from '../ur/ur';\nimport { Ur as UrValue } from '../ur/ur';\nimport type { ChainContext, EraConnectConfig, SignRequest } from './shared';\nimport { makeSignRequest, requireUrType, resolveContext, toUr } from './shared';\n\n/**\n * XRP rides the XRP Toolkit convention: an untyped `ur:bytes` whose CBOR\n * payload is the transaction JSON (request) or the canonical signed XRPL\n * binary (reply). There is NO request id and NO chain-specific UR type — the\n * content itself is the only binding, which is why `verifyXrpSignature`\n * (from `@hwlt/era-connect/verify`) is not optional on this chain.\n */\nexport interface XrpSignRequestProps {\n /**\n * The unsigned transaction JSON. MUST already carry `SigningPubKey` (the\n * device signs with `m/44'/144'/0'/0/0` — put THAT key's hex here),\n * `TransactionType`, a classic `r…` `Account`, `Fee` and `Sequence`.\n */\n readonly transaction: Record<string, unknown> | string;\n}\n\nexport interface XrpSignatureResult {\n /** The canonical signed XRPL binary transaction — submit it verbatim. */\n readonly signedTx: Uint8Array;\n}\n\nconst REPLY_TYPES = ['bytes'] as const;\n\nexport class XrpChain {\n private readonly context: ChainContext;\n\n constructor(config?: EraConnectConfig) {\n this.context = resolveContext(config);\n }\n\n /** Wrap the tx JSON in the `ur:bytes` request shape. Reply: `ur:bytes` with the signed binary. */\n generateSignRequest(props: XrpSignRequestProps): SignRequest<XrpSignatureResult> {\n const text =\n typeof props.transaction === 'string' ? props.transaction : JSON.stringify(props.transaction);\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(text) as Record<string, unknown>;\n } catch {\n throw new EraSdkError('invalid-props', 'transaction is not valid JSON');\n }\n // Mirror the device's own acceptance gate so a refusal happens HERE with\n // a reason, not silently on the hardware.\n if (typeof parsed.TransactionType !== 'string') {\n throw new EraSdkError('invalid-props', 'transaction needs a TransactionType');\n }\n if (typeof parsed.Account !== 'string' || !parsed.Account.startsWith('r')) {\n throw new EraSdkError('invalid-props', 'transaction needs a classic r… Account');\n }\n if (typeof parsed.SigningPubKey !== 'string' || parsed.SigningPubKey.length === 0) {\n throw new EraSdkError(\n 'invalid-props',\n \"transaction needs SigningPubKey — the device signs with m/44'/144'/0'/0/0\",\n );\n }\n if (parsed.Fee === undefined || parsed.Sequence === undefined) {\n throw new EraSdkError('invalid-props', 'transaction needs Fee and Sequence');\n }\n\n const ur = new UrValue('bytes', cborEncode(cbBytes(utf8Encode(text))));\n return makeSignRequest({\n ur,\n replyTypes: REPLY_TYPES,\n context: this.context,\n parse: (reply) => this.parseSignature(reply),\n });\n }\n\n /** Parse the `ur:bytes` reply into the signed binary transaction. */\n parseSignature(input: Ur | string): XrpSignatureResult {\n const ur = toUr(input);\n requireUrType(ur, [...REPLY_TYPES], 'xrp reply');\n let decoded: ReturnType<typeof cborDecode>;\n try {\n decoded = cborDecode(ur.cbor);\n } catch (e) {\n throw new EraSdkError('malformed-cbor', `xrp reply: ${(e as Error).message}`);\n }\n const bytes = asBytes(decoded);\n if (!bytes || bytes.length === 0) {\n throw new EraSdkError('malformed-reply', 'xrp reply carries no signed transaction bytes');\n }\n return { signedTx: bytes };\n }\n}\n"],"mappings":";;AA+BA,MAAM,cAAc,CAAC,OAAO;AAE5B,IAAa,WAAb,MAAsB;CAGpB,YAAY,QAA2B;EACrC,KAAK,UAAU,eAAe,MAAM;CACtC;;CAGA,oBAAoB,OAA6D;EAC/E,MAAM,OACJ,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc,KAAK,UAAU,MAAM,WAAW;EAC9F,IAAI;EACJ,IAAI;GACF,SAAS,KAAK,MAAM,IAAI;EAC1B,QAAQ;GACN,MAAM,IAAI,YAAY,iBAAiB,+BAA+B;EACxE;EAGA,IAAI,OAAO,OAAO,oBAAoB,UACpC,MAAM,IAAI,YAAY,iBAAiB,qCAAqC;EAE9E,IAAI,OAAO,OAAO,YAAY,YAAY,CAAC,OAAO,QAAQ,WAAW,GAAG,GACtE,MAAM,IAAI,YAAY,iBAAiB,wCAAwC;EAEjF,IAAI,OAAO,OAAO,kBAAkB,YAAY,OAAO,cAAc,WAAW,GAC9E,MAAM,IAAI,YACR,iBACA,2EACF;EAEF,IAAI,OAAO,QAAQ,KAAA,KAAa,OAAO,aAAa,KAAA,GAClD,MAAM,IAAI,YAAY,iBAAiB,oCAAoC;EAG7E,MAAM,KAAK,IAAIA,GAAQ,SAAS,WAAW,QAAQ,WAAW,IAAI,CAAC,CAAC,CAAC;EACrE,OAAO,gBAAgB;GACrB;GACA,YAAY;GACZ,SAAS,KAAK;GACd,QAAQ,UAAU,KAAK,eAAe,KAAK;EAC7C,CAAC;CACH;;CAGA,eAAe,OAAwC;EACrD,MAAM,KAAK,KAAK,KAAK;EACrB,cAAc,IAAI,CAAC,GAAG,WAAW,GAAG,WAAW;EAC/C,IAAI;EACJ,IAAI;GACF,UAAU,WAAW,GAAG,IAAI;EAC9B,SAAS,GAAG;GACV,MAAM,IAAI,YAAY,kBAAkB,cAAe,EAAY,SAAS;EAC9E;EACA,MAAM,QAAQ,QAAQ,OAAO;EAC7B,IAAI,CAAC,SAAS,MAAM,WAAW,GAC7B,MAAM,IAAI,YAAY,mBAAmB,+CAA+C;EAE1F,OAAO,EAAE,UAAU,MAAM;CAC3B;AACF"}
@@ -0,0 +1,32 @@
1
+ import { _ as Ur, a as SignRequest, r as EraConnectConfig } from "./shared-CI8zhQiE.js";
2
+ //#region src/chains/xrp.d.ts
3
+ /**
4
+ * XRP rides the XRP Toolkit convention: an untyped `ur:bytes` whose CBOR
5
+ * payload is the transaction JSON (request) or the canonical signed XRPL
6
+ * binary (reply). There is NO request id and NO chain-specific UR type — the
7
+ * content itself is the only binding, which is why `verifyXrpSignature`
8
+ * (from `@hwlt/era-connect/verify`) is not optional on this chain.
9
+ */
10
+ interface XrpSignRequestProps {
11
+ /**
12
+ * The unsigned transaction JSON. MUST already carry `SigningPubKey` (the
13
+ * device signs with `m/44'/144'/0'/0/0` — put THAT key's hex here),
14
+ * `TransactionType`, a classic `r…` `Account`, `Fee` and `Sequence`.
15
+ */
16
+ readonly transaction: Record<string, unknown> | string;
17
+ }
18
+ interface XrpSignatureResult {
19
+ /** The canonical signed XRPL binary transaction — submit it verbatim. */
20
+ readonly signedTx: Uint8Array;
21
+ }
22
+ declare class XrpChain {
23
+ private readonly context;
24
+ constructor(config?: EraConnectConfig);
25
+ /** Wrap the tx JSON in the `ur:bytes` request shape. Reply: `ur:bytes` with the signed binary. */
26
+ generateSignRequest(props: XrpSignRequestProps): SignRequest<XrpSignatureResult>;
27
+ /** Parse the `ur:bytes` reply into the signed binary transaction. */
28
+ parseSignature(input: Ur | string): XrpSignatureResult;
29
+ }
30
+ //#endregion
31
+ export { XrpSignRequestProps as n, XrpSignatureResult as r, XrpChain as t };
32
+ //# sourceMappingURL=xrp-DqCXGYEk.d.ts.map
package/dist/xrp.cjs ADDED
@@ -0,0 +1,9 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_shared = require("./shared-Cu2yynP9.cjs");
3
+ const require_xrp = require("./xrp-BrHXUnX5.cjs");
4
+ exports.AnimatedUr = require_shared.AnimatedUr;
5
+ exports.EraSdkError = require_shared.EraSdkError;
6
+ exports.TypedUrScanner = require_shared.TypedUrScanner;
7
+ exports.Ur = require_shared.Ur;
8
+ exports.UrScanner = require_shared.UrScanner;
9
+ exports.XrpChain = require_xrp.XrpChain;
package/dist/xrp.d.cts ADDED
@@ -0,0 +1,3 @@
1
+ import { _ as Ur, a as SignRequest, c as TypedUrScanner, d as EraErrorCode, f as EraSdkError, l as UrScanner, p as AnimatedUr, r as EraConnectConfig } from "./shared-CI8zhQiE.cjs";
2
+ import { n as XrpSignRequestProps, r as XrpSignatureResult, t as XrpChain } from "./xrp-BXAeK4iH.cjs";
3
+ export { AnimatedUr, type EraConnectConfig, type EraErrorCode, EraSdkError, type SignRequest, TypedUrScanner, Ur, UrScanner, XrpChain, type XrpSignRequestProps, type XrpSignatureResult };
package/dist/xrp.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { _ as Ur, a as SignRequest, c as TypedUrScanner, d as EraErrorCode, f as EraSdkError, l as UrScanner, p as AnimatedUr, r as EraConnectConfig } from "./shared-CI8zhQiE.js";
2
+ import { n as XrpSignRequestProps, r as XrpSignatureResult, t as XrpChain } from "./xrp-DqCXGYEk.js";
3
+ export { AnimatedUr, type EraConnectConfig, type EraErrorCode, EraSdkError, type SignRequest, TypedUrScanner, Ur, UrScanner, XrpChain, type XrpSignRequestProps, type XrpSignatureResult };
package/dist/xrp.js ADDED
@@ -0,0 +1,3 @@
1
+ import { K as EraSdkError, _ as Ur, d as UrScanner, f as AnimatedUr, u as TypedUrScanner } from "./shared-Bbgejrus.js";
2
+ import { t as XrpChain } from "./xrp-C8LJO5b-.js";
3
+ export { AnimatedUr, EraSdkError, TypedUrScanner, Ur, UrScanner, XrpChain };