@qrkit/core 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +24 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +24 -23
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
@@ -45,27 +35,6 @@ __export(index_exports, {
|
|
|
45
35
|
});
|
|
46
36
|
module.exports = __toCommonJS(index_exports);
|
|
47
37
|
|
|
48
|
-
// src/bytes.ts
|
|
49
|
-
function bytesToBase64(bytes) {
|
|
50
|
-
let binary = "";
|
|
51
|
-
for (const byte of bytes) {
|
|
52
|
-
binary += String.fromCharCode(byte);
|
|
53
|
-
}
|
|
54
|
-
return btoa(binary);
|
|
55
|
-
}
|
|
56
|
-
function bytesToHex(bytes) {
|
|
57
|
-
return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
58
|
-
}
|
|
59
|
-
function hexToBytes(hex) {
|
|
60
|
-
const normalized = hex.trim().replace(/^0x/i, "");
|
|
61
|
-
if (normalized.length % 2 !== 0 || !/^[0-9a-f]*$/i.test(normalized)) {
|
|
62
|
-
throw new Error("Invalid hex string");
|
|
63
|
-
}
|
|
64
|
-
return new Uint8Array(
|
|
65
|
-
normalized.match(/.{2}/g)?.map((byte) => parseInt(byte, 16)) ?? []
|
|
66
|
-
);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
38
|
// src/btc/address.ts
|
|
70
39
|
var import_base = require("@scure/base");
|
|
71
40
|
var import_legacy = require("@noble/hashes/legacy.js");
|
|
@@ -99,6 +68,27 @@ function pubKeyToP2pkh(compressedPubKey) {
|
|
|
99
68
|
return base58check.encode(payload);
|
|
100
69
|
}
|
|
101
70
|
|
|
71
|
+
// src/bytes.ts
|
|
72
|
+
function bytesToBase64(bytes) {
|
|
73
|
+
let binary = "";
|
|
74
|
+
for (const byte of bytes) {
|
|
75
|
+
binary += String.fromCharCode(byte);
|
|
76
|
+
}
|
|
77
|
+
return btoa(binary);
|
|
78
|
+
}
|
|
79
|
+
function bytesToHex(bytes) {
|
|
80
|
+
return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
81
|
+
}
|
|
82
|
+
function hexToBytes(hex) {
|
|
83
|
+
const normalized = hex.trim().replace(/^0x/i, "");
|
|
84
|
+
if (normalized.length % 2 !== 0 || !/^[0-9a-f]*$/i.test(normalized)) {
|
|
85
|
+
throw new Error("Invalid hex string");
|
|
86
|
+
}
|
|
87
|
+
return new Uint8Array(
|
|
88
|
+
normalized.match(/.{2}/g)?.map((byte) => parseInt(byte, 16)) ?? []
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
102
92
|
// src/btc/deriveAccount.ts
|
|
103
93
|
function firstChild(accountKey) {
|
|
104
94
|
return accountKey.deriveChild(0).deriveChild(0);
|
|
@@ -135,10 +125,11 @@ function deriveBtcAccount(parsed) {
|
|
|
135
125
|
}
|
|
136
126
|
|
|
137
127
|
// src/eth/address.ts
|
|
128
|
+
var import_secp256k1 = require("@noble/curves/secp256k1.js");
|
|
138
129
|
var import_sha3 = require("@noble/hashes/sha3.js");
|
|
139
|
-
var secp = __toESM(require("@noble/secp256k1"), 1);
|
|
140
130
|
function pubKeyToEthAddress(compressedPubKey) {
|
|
141
|
-
const
|
|
131
|
+
const pubKeyHex = [...compressedPubKey].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
132
|
+
const uncompressed = import_secp256k1.secp256k1.Point.fromHex(pubKeyHex).toBytes(false);
|
|
142
133
|
const hash = (0, import_sha3.keccak_256)(uncompressed.slice(1));
|
|
143
134
|
const hex = [...hash.slice(12)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
144
135
|
return toChecksumAddress(hex);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/bytes.ts","../src/btc/address.ts","../src/btc/deriveAccount.ts","../src/eth/address.ts","../src/eth/deriveAccount.ts","../src/parseXpub.ts","../src/parseConnection.ts","../src/cbor.ts","../src/urEncoding.ts","../src/eth/signRequest.ts","../src/eth/signature.ts","../src/btc/signRequest.ts","../src/btc/signature.ts","../src/btc/psbt.ts"],"sourcesContent":["// Types\nexport type {\n ScannedUR,\n Chain,\n QRKitConfig,\n Account,\n EvmAccount,\n BtcAccount,\n} from \"./types.js\";\nexport type { ParsedXpub, XpubType } from \"./parseXpub.js\";\n\n// Connection\nexport { parseConnection } from \"./parseConnection.js\";\n\n// EVM signing\nexport {\n buildEthSignRequestUR,\n buildEthSignRequestURParts,\n EthDataType,\n} from \"./eth/signRequest.js\";\nexport type { EthDataTypeValue, EthSignRequestParams } from \"./eth/signRequest.js\";\nexport { parseEthSignature } from \"./eth/signature.js\";\n\n// BTC signing\nexport {\n buildBtcSignRequestUR,\n buildBtcSignRequestURParts,\n BtcDataType,\n} from \"./btc/signRequest.js\";\nexport type { BtcDataTypeValue, BtcSignRequestParams } from \"./btc/signRequest.js\";\nexport { parseBtcSignature } from \"./btc/signature.js\";\nexport type { BtcSignature } from \"./btc/signature.js\";\nexport {\n buildCryptoPsbtUR,\n buildCryptoPsbtURParts,\n parseCryptoPsbt,\n} from \"./btc/psbt.js\";\nexport type { CryptoPsbt } from \"./btc/psbt.js\";\n","export function bytesToBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\nexport function bytesToHex(bytes: Uint8Array): string {\n return [...bytes].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport function hexToBytes(hex: string): Uint8Array {\n const normalized = hex.trim().replace(/^0x/i, \"\");\n if (normalized.length % 2 !== 0 || !/^[0-9a-f]*$/i.test(normalized)) {\n throw new Error(\"Invalid hex string\");\n }\n\n return new Uint8Array(\n normalized.match(/.{2}/g)?.map((byte) => parseInt(byte, 16)) ?? [],\n );\n}\n","import { bech32, createBase58check } from \"@scure/base\";\nimport { ripemd160 } from \"@noble/hashes/legacy.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n\nexport type BtcScriptType = \"p2wpkh\" | \"p2sh-p2wpkh\" | \"p2pkh\";\n\nconst base58check = createBase58check(sha256);\n\nfunction hash160(bytes: Uint8Array): Uint8Array {\n return ripemd160(sha256(bytes));\n}\n\n/** Native SegWit — P2WPKH, `bc1q...` */\nexport function pubKeyToP2wpkh(compressedPubKey: Uint8Array): string {\n const h = hash160(compressedPubKey);\n const words = bech32.toWords(h);\n return bech32.encode(\"bc\", [0, ...words]);\n}\n\n/** Nested SegWit — P2SH-P2WPKH, `3...` */\nexport function pubKeyToP2shP2wpkh(compressedPubKey: Uint8Array): string {\n const h = hash160(compressedPubKey);\n // redeemScript = OP_0 <20-byte-pubkey-hash>\n const redeemScript = new Uint8Array(22);\n redeemScript[0] = 0x00;\n redeemScript[1] = 0x14;\n redeemScript.set(h, 2);\n const scriptHash = hash160(redeemScript);\n const payload = new Uint8Array(21);\n payload[0] = 0x05; // P2SH version byte\n payload.set(scriptHash, 1);\n return base58check.encode(payload);\n}\n\n/** Legacy — P2PKH, `1...` */\nexport function pubKeyToP2pkh(compressedPubKey: Uint8Array): string {\n const h = hash160(compressedPubKey);\n const payload = new Uint8Array(21);\n payload[0] = 0x00; // mainnet P2PKH version byte\n payload.set(h, 1);\n return base58check.encode(payload);\n}\n","import type { HDKey } from \"@scure/bip32\";\n\nimport { bytesToHex } from \"../bytes.js\";\nimport {\n pubKeyToP2pkh,\n pubKeyToP2shP2wpkh,\n pubKeyToP2wpkh,\n type BtcScriptType,\n} from \"./address.js\";\nimport type { ParsedXpub } from \"../parseXpub.js\";\n\nexport interface DerivedBtcAccount {\n address: string;\n scriptType: BtcScriptType;\n publicKey: string;\n /** source-fingerprint from the scanned xpub — required for signing */\n sourceFingerprint: number | undefined;\n /** device or key name as reported by the hardware wallet, if available */\n device: string | undefined;\n}\n\n// Derive the first external address (index 0) from an account-level xpub.\n// Account-level xpub is at depth 3 (m/purpose'/coin'/account').\n// External chain is child 0, then address index 0.\nfunction firstChild(accountKey: HDKey): HDKey {\n return accountKey.deriveChild(0).deriveChild(0);\n}\n\nfunction scriptTypeFromPurpose(purpose: number | undefined): BtcScriptType | undefined {\n if (purpose === 84) return \"p2wpkh\";\n if (purpose === 49) return \"p2sh-p2wpkh\";\n if (purpose === 44) return \"p2pkh\";\n return undefined;\n}\n\nfunction deriveAddress(pubKey: Uint8Array, scriptType: BtcScriptType): string {\n if (scriptType === \"p2wpkh\") return pubKeyToP2wpkh(pubKey);\n if (scriptType === \"p2sh-p2wpkh\") return pubKeyToP2shP2wpkh(pubKey);\n return pubKeyToP2pkh(pubKey);\n}\n\nexport function deriveBtcAccount(parsed: ParsedXpub[]): DerivedBtcAccount[] {\n const results: DerivedBtcAccount[] = [];\n\n for (const entry of parsed) {\n const { hdKey, purpose, coinType, sourceFingerprint, name } = entry;\n\n // BTC: coin type 0\n if (coinType !== 0) continue;\n\n const scriptType = scriptTypeFromPurpose(purpose);\n if (!scriptType) continue;\n\n const child = firstChild(hdKey);\n if (!child.publicKey) continue;\n\n results.push({\n address: deriveAddress(child.publicKey, scriptType),\n scriptType,\n publicKey: bytesToHex(child.publicKey),\n sourceFingerprint,\n device: name,\n });\n }\n\n return results;\n}\n","import { keccak_256 } from \"@noble/hashes/sha3.js\";\nimport * as secp from \"@noble/secp256k1\";\n\nexport function pubKeyToEthAddress(compressedPubKey: Uint8Array): string {\n const uncompressed = secp.Point.fromBytes(compressedPubKey).toBytes(false);\n const hash = keccak_256(uncompressed.slice(1));\n const hex = [...hash.slice(12)]\n .map((b: number) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n return toChecksumAddress(hex);\n}\n\nfunction toChecksumAddress(hex: string): string {\n const checksumHash = keccak_256(new TextEncoder().encode(hex));\n return (\n \"0x\" +\n [...hex]\n .map((c, i) => {\n if (c >= \"0\" && c <= \"9\") return c;\n const nibble =\n i % 2 === 0\n ? (checksumHash[Math.floor(i / 2)] >> 4) & 0xf\n : checksumHash[Math.floor(i / 2)] & 0xf;\n return nibble >= 8 ? c.toUpperCase() : c.toLowerCase();\n })\n .join(\"\")\n );\n}\n","import type { HDKey } from \"@scure/bip32\";\n\nimport { bytesToHex } from \"../bytes.js\";\nimport { pubKeyToEthAddress } from \"./address.js\";\nimport type { ParsedXpub } from \"../parseXpub.js\";\n\nexport interface DerivedAccount {\n address: string;\n publicKey: string;\n /** source-fingerprint from the scanned xpub — required by Shell for signing */\n sourceFingerprint: number | undefined;\n /** device or key name as reported by the hardware wallet, if available */\n device: string | undefined;\n}\n\n// Derive the first external address (index 0) from an account-level xpub.\n// Account-level xpub is at depth 3 (m/purpose'/coin'/account').\n// External chain is child 0, then address index 0.\nfunction firstChild(accountKey: HDKey): HDKey {\n return accountKey.deriveChild(0).deriveChild(0);\n}\n\nexport function deriveEvmAccount(parsed: ParsedXpub[]): DerivedAccount[] {\n const results: DerivedAccount[] = [];\n for (const entry of parsed) {\n const { hdKey, purpose, coinType, type, sourceFingerprint, name } = entry;\n const isEvm =\n (purpose === 44 && coinType === 60) || (purpose === undefined && type === \"xpub\");\n\n if (!isEvm) continue;\n\n const child = firstChild(hdKey);\n if (!child.publicKey) continue;\n\n results.push({\n address: pubKeyToEthAddress(child.publicKey),\n publicKey: bytesToHex(child.publicKey),\n sourceFingerprint,\n device: name,\n });\n }\n return results;\n}\n","import { HDKey } from \"@scure/bip32\";\nimport { decode as cborDecode, type TagDecoder } from \"cborg\";\n\nimport type { ScannedUR } from \"./types.js\";\n\nexport type XpubType = \"xpub\";\n\nexport interface ParsedXpub {\n hdKey: HDKey;\n type: XpubType;\n /** BIP-44 purpose index: 44 for EVM, 44/49/84 for supported BTC scripts */\n purpose: number | undefined;\n /** BIP-44 coin type: 60 = ETH, 0 = BTC */\n coinType: number | undefined;\n /** source-fingerprint from the origin keypath — required by Shell for signing */\n sourceFingerprint: number | undefined;\n /** device or key name from crypto-hdkey key 9, set by some wallets (e.g. Keystone) */\n name?: string;\n raw: string;\n}\n\ntype CborMap = Map<number, unknown>;\n\nfunction get(m: unknown, k: number): unknown {\n if (m instanceof Map) return (m as Map<number, unknown>).get(k);\n return undefined;\n}\n\nfunction bytesFromCbor(value: unknown): Uint8Array | undefined {\n if (value instanceof Uint8Array) return value;\n\n if (value instanceof Map && value.get(\"type\") === \"Buffer\") {\n const data = value.get(\"data\");\n if (\n Array.isArray(data) &&\n data.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 0xff)\n ) {\n return new Uint8Array(data);\n }\n }\n\n return undefined;\n}\n\nconst passthrough = (v: unknown) => v;\n\nfunction decodeCbor(cbor: Uint8Array): Map<number, unknown> {\n // Connection payloads often wrap the inner hdkey/output structures in semantic CBOR tags\n // (script expressions, crypto-output, vendor-specific wrappers, etc.). For connection\n // parsing we only care about the inner map/bytes shape, so tags are treated as annotations\n // and stripped during decode. Required structure is validated explicitly later.\n const tags = new Proxy([] as TagDecoder[], {\n get(target, property, receiver) {\n if (typeof property === \"string\" && /^\\d+$/.test(property)) {\n return passthrough;\n }\n return Reflect.get(target, property, receiver);\n },\n });\n\n return cborDecode(cbor, {\n useMaps: true,\n tags,\n }) as Map<number, unknown>;\n}\n\nfunction isCborMap(value: unknown): value is CborMap {\n return value instanceof Map;\n}\n\nfunction assertCryptoHdKeyShape(value: unknown): CborMap {\n if (!isCborMap(value)) {\n throw new Error(\"crypto-hdkey entry must be a CBOR map\");\n }\n\n if (!value.has(3) || !value.has(4)) {\n throw new Error(\"crypto-hdkey missing key-data or chain-code\");\n }\n\n return value;\n}\n\nfunction parseCryptoHdKey(map: CborMap, raw: string, fallbackName?: string): ParsedXpub {\n const keyData = bytesFromCbor(get(map, 3));\n const chainCode = bytesFromCbor(get(map, 4));\n\n if (!keyData || !chainCode) {\n throw new Error(\"crypto-hdkey missing key-data or chain-code\");\n }\n\n let purpose: number | undefined;\n let coinType: number | undefined;\n let sourceFingerprint: number | undefined;\n const origin = get(map, 6);\n if (origin) {\n const components = get(origin, 1);\n if (Array.isArray(components)) {\n if (components.length >= 1) purpose = components[0] as number;\n if (components.length >= 3) coinType = components[2] as number;\n }\n sourceFingerprint = get(origin, 2) as number | undefined;\n }\n\n const name = (get(map, 9) as string | undefined) ?? fallbackName;\n\n const hdKey = new HDKey({ publicKey: keyData, chainCode });\n return { hdKey, type: \"xpub\", purpose, coinType, sourceFingerprint, name, raw };\n}\n\nfunction parseScannedUR(scanned: ScannedUR): ParsedXpub | ParsedXpub[] {\n const { type, cbor } = scanned;\n const raw = `ur:${type}`;\n\n if (\n type !== \"crypto-hdkey\" &&\n type !== \"crypto-account\" &&\n type !== \"crypto-multi-accounts\"\n ) {\n throw new Error(`Unsupported UR type: ${type}`);\n }\n\n const map = decodeCbor(cbor);\n\n if (type === \"crypto-hdkey\") {\n return parseCryptoHdKey(assertCryptoHdKeyShape(map), raw);\n }\n\n const accounts = map.get(2) as unknown[] | undefined;\n if (!Array.isArray(accounts) || accounts.length === 0) {\n throw new Error(`${type} contains no keys`);\n }\n const fallbackName =\n type === \"crypto-multi-accounts\" ? (map.get(3) as string | undefined) : undefined;\n return accounts.map((entry) =>\n parseCryptoHdKey(assertCryptoHdKeyShape(entry), raw, fallbackName),\n );\n}\n\nexport function parseXpub(input: ScannedUR | string): ParsedXpub[] {\n if (typeof input !== \"string\") {\n const result = parseScannedUR(input);\n return Array.isArray(result) ? result : [result];\n }\n // Raw base58 xpub string — @scure/bip32 handles decoding directly\n const hdKey = HDKey.fromExtendedKey(input.trim());\n return [\n {\n hdKey,\n type: \"xpub\",\n purpose: undefined,\n coinType: undefined,\n sourceFingerprint: undefined,\n raw: input.trim(),\n },\n ];\n}\n","import { deriveBtcAccount } from \"./btc/deriveAccount.js\";\nimport { deriveEvmAccount } from \"./eth/deriveAccount.js\";\nimport { parseXpub } from \"./parseXpub.js\";\nimport type {\n Account,\n BtcAccount,\n Chain,\n EvmAccount,\n QRKitConfig,\n ScannedUR,\n} from \"./types.js\";\n\nconst ALL_CHAINS: Chain[] = [\"evm\", \"btc\"];\n\n/**\n * Parse a connection QR (crypto-hdkey or crypto-account) and return\n * only the accounts for the chains configured in QRKitConfig.\n *\n * A dApp configured with `chains: [\"evm\"]` will never see BTC accounts,\n * and vice versa. Both chains can be enabled with `chains: [\"evm\", \"btc\"]`.\n * If `chains` is omitted, all supported chains are tried.\n */\nexport function parseConnection(\n scannedUR: ScannedUR,\n config: QRKitConfig = {},\n): Account[] {\n const chains = config.chains ?? ALL_CHAINS;\n const parsed = parseXpub(scannedUR);\n const accounts: Account[] = [];\n\n if (chains.includes(\"evm\")) {\n for (const account of deriveEvmAccount(parsed)) {\n accounts.push({ chain: \"evm\", ...account } satisfies EvmAccount);\n }\n }\n\n if (chains.includes(\"btc\")) {\n for (const account of deriveBtcAccount(parsed)) {\n accounts.push({ chain: \"btc\", ...account } satisfies BtcAccount);\n }\n }\n\n return accounts;\n}\n","// Minimal CBOR encoder.\n// Supports only the types needed for eth-sign-request: uint, bytes, text, array, map (integer keys), bool, tag.\n\nfunction majorType(major: number, n: number): number[] {\n const base = major << 5;\n if (n <= 23) return [base | n];\n if (n <= 0xff) return [base | 0x18, n];\n if (n <= 0xffff) return [base | 0x19, (n >> 8) & 0xff, n & 0xff];\n return [base | 0x1a, (n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff];\n}\n\nexport function encodeItem(value: unknown): number[] {\n if (typeof value === \"boolean\") {\n return [value ? 0xf5 : 0xf4];\n }\n if (typeof value === \"number\") {\n return majorType(0, value);\n }\n if (value instanceof Uint8Array) {\n return [...majorType(2, value.length), ...value];\n }\n if (typeof value === \"string\") {\n const bytes = new TextEncoder().encode(value);\n return [...majorType(3, bytes.length), ...bytes];\n }\n if (Array.isArray(value)) {\n return [...majorType(4, value.length), ...value.flatMap(encodeItem)];\n }\n if (value instanceof CborTag) {\n return [...majorType(6, value.tag), ...encodeItem(value.value)];\n }\n if (value instanceof Map) {\n const entries = [...value.entries()];\n return [\n ...majorType(5, entries.length),\n ...entries.flatMap(([k, v]) => [...encodeItem(k), ...encodeItem(v)]),\n ];\n }\n throw new Error(`Unsupported CBOR value: ${typeof value}`);\n}\n\nexport class CborTag {\n tag: number;\n value: unknown;\n constructor(tag: number, value: unknown) {\n this.tag = tag;\n this.value = value;\n }\n}\n\nexport function encode(value: unknown): Uint8Array {\n return new Uint8Array(encodeItem(value));\n}\n","import { UR, UrFountainEncoder } from \"@qrkit/bc-ur-web\";\n\nexport function encodeURParts(\n cbor: Uint8Array,\n type: string,\n maxFragmentLength = 200,\n): string[] {\n const ur = UR.fromCbor({ type, payload: cbor });\n const encoder = new UrFountainEncoder(ur, maxFragmentLength);\n return encoder.getAllPartsUr().map((part) => part.toString().toUpperCase());\n}\n","import { encode, CborTag } from \"../cbor.js\";\nimport { encodeURParts } from \"../urEncoding.js\";\n\n// ERC-4527 eth-sign-request data types\nexport const EthDataType = {\n /** Legacy transaction (RLP-encoded). Wallet applies EIP-155: v = 35 + 2*chainId + recId */\n LegacyTransaction: 1,\n /** EIP-712 typed data bytes. Wallet hashes internally. */\n TypedData: 2,\n /** Personal message (EIP-191). Wallet prepends \"\\x19Ethereum Signed Message:\\n{len}\". */\n PersonalMessage: 3,\n /** EIP-1559 transaction (RLP-encoded). Wallet uses v = recId. */\n TypedTransaction: 4,\n} as const;\n\nexport type EthDataTypeValue = (typeof EthDataType)[keyof typeof EthDataType];\n\n// CBOR tag for crypto-keypath\nconst TAG_KEYPATH = 304;\n\nfunction randomBytes(n: number): Uint8Array {\n const buf = new Uint8Array(n);\n crypto.getRandomValues(buf);\n return buf;\n}\n\nfunction buildKeypath(\n purpose: number,\n coinType: number,\n sourceFingerprint: number | undefined,\n): CborTag {\n // m/purpose'/coinType'/0'/0/0\n const components = [purpose, true, coinType, true, 0, true, 0, false, 0, false];\n const keypathMap = new Map<number, unknown>([[1, components]]);\n if (sourceFingerprint !== undefined) {\n keypathMap.set(2, sourceFingerprint);\n }\n return new CborTag(TAG_KEYPATH, keypathMap);\n}\n\nexport interface EthSignRequestParams {\n /** Raw sign data. For PersonalMessage, a string is UTF-8 encoded automatically. */\n signData: Uint8Array | string;\n /** ERC-4527 data type. Defaults to PersonalMessage (3). Use EthDataType constants. */\n dataType?: number;\n address: string;\n sourceFingerprint: number | undefined;\n /** Chain ID — required by the wallet for v-value encoding on LegacyTransaction (type 1). */\n chainId?: number;\n origin?: string;\n}\n\nfunction buildEthSignRequestCbor(params: EthSignRequestParams): Uint8Array {\n const {\n signData,\n dataType = EthDataType.PersonalMessage,\n address,\n sourceFingerprint,\n chainId,\n origin = \"qrkit\",\n } = params;\n\n const requestId = randomBytes(16);\n const signBytes =\n typeof signData === \"string\" ? new TextEncoder().encode(signData) : signData;\n const keypath = buildKeypath(44, 60, sourceFingerprint);\n\n const addrHex = address.replace(/^0x/i, \"\");\n const addrBytes = new Uint8Array(addrHex.match(/.{2}/g)!.map((b) => parseInt(b, 16)));\n\n // Keys must be in strictly ascending order for zcbor (Shell firmware decoder).\n const map = new Map<number, unknown>([\n [1, new CborTag(37, requestId)], // request-id: uuid = #6.37(bstr)\n [2, signBytes], // sign-data\n [3, dataType], // data-type\n ]);\n\n if (chainId !== undefined) {\n map.set(4, chainId); // chain-id — must come before key 5\n }\n\n map.set(5, keypath); // derivation-path\n map.set(6, addrBytes); // address\n map.set(7, origin); // origin\n\n return encode(map);\n}\n\nexport function buildEthSignRequestURParts(params: EthSignRequestParams): string[] {\n return encodeURParts(buildEthSignRequestCbor(params), \"eth-sign-request\");\n}\n\nexport function buildEthSignRequestUR(params: EthSignRequestParams): string {\n return encodeURParts(buildEthSignRequestCbor(params), \"eth-sign-request\")[0];\n}\n","import { decode as cborDecode, type TagDecoder } from \"cborg\";\n\nimport { bytesToHex } from \"../bytes.js\";\nimport type { ScannedUR } from \"../types.js\";\n\nexport function parseEthSignature(scanned: ScannedUR): string {\n if (scanned.type !== \"eth-signature\") {\n throw new Error(`Expected eth-signature, got: ${scanned.type}`);\n }\n\n const map = cborDecode(scanned.cbor, {\n useMaps: true,\n tags: Object.assign([] as TagDecoder[], { 37: (v: unknown) => v }),\n }) as Map<number, unknown>;\n\n const sigBytes = map.get(2) as Uint8Array | undefined;\n if (!sigBytes || sigBytes.length < 64) {\n throw new Error(\"Invalid or missing signature bytes\");\n }\n\n return `0x${bytesToHex(sigBytes)}`;\n}\n","import { encode, CborTag } from \"../cbor.js\";\nimport { encodeURParts } from \"../urEncoding.js\";\nimport type { BtcScriptType } from \"./address.js\";\n\nexport const BtcDataType = {\n Message: 1,\n} as const;\n\nexport type BtcDataTypeValue = (typeof BtcDataType)[keyof typeof BtcDataType];\n\nconst TAG_KEYPATH = 304;\nconst PURPOSE_BY_SCRIPT_TYPE = {\n p2wpkh: 84,\n \"p2sh-p2wpkh\": 49,\n p2pkh: 44,\n} as const satisfies Record<BtcScriptType, number>;\n\nfunction randomBytes(n: number): Uint8Array {\n const buf = new Uint8Array(n);\n crypto.getRandomValues(buf);\n return buf;\n}\n\nfunction purposeFromScriptType(scriptType: BtcScriptType): number {\n return PURPOSE_BY_SCRIPT_TYPE[scriptType];\n}\n\nfunction buildKeypath(\n scriptType: BtcScriptType,\n sourceFingerprint: number | undefined,\n): CborTag {\n const purpose = purposeFromScriptType(scriptType);\n // m/purpose'/0'/0'/0/0\n const components = [purpose, true, 0, true, 0, true, 0, false, 0, false];\n const keypathMap = new Map<number, unknown>([[1, components]]);\n if (sourceFingerprint !== undefined) {\n keypathMap.set(2, sourceFingerprint);\n }\n return new CborTag(TAG_KEYPATH, keypathMap);\n}\n\nexport interface BtcSignRequestParams {\n /** Raw message data. Strings are UTF-8 encoded automatically. */\n signData: Uint8Array | string;\n address: string;\n /** BTC script type for choosing m/44', m/49', or m/84'. */\n scriptType: BtcScriptType;\n sourceFingerprint: number | undefined;\n origin?: string;\n}\n\nfunction buildBtcSignRequestCbor(params: BtcSignRequestParams): Uint8Array {\n const { signData, address, scriptType, sourceFingerprint, origin = \"qrkit\" } = params;\n const requestId = randomBytes(16);\n const signBytes =\n typeof signData === \"string\" ? new TextEncoder().encode(signData) : signData;\n const keypath = buildKeypath(scriptType, sourceFingerprint);\n\n return encode(\n new Map<number, unknown>([\n [1, new CborTag(37, requestId)], // request-id: uuid = #6.37(bstr)\n [2, signBytes], // sign-data\n [3, BtcDataType.Message], // data-type\n [4, [keypath]], // btc-derivation-paths\n [5, [address]], // btc-addresses\n [6, origin], // origin\n ]),\n );\n}\n\nexport function buildBtcSignRequestURParts(params: BtcSignRequestParams): string[] {\n return encodeURParts(buildBtcSignRequestCbor(params), \"btc-sign-request\");\n}\n\nexport function buildBtcSignRequestUR(params: BtcSignRequestParams): string {\n return encodeURParts(buildBtcSignRequestCbor(params), \"btc-sign-request\")[0];\n}\n","import { decode as cborDecode, type TagDecoder } from \"cborg\";\n\nimport { bytesToBase64, bytesToHex } from \"../bytes.js\";\nimport type { ScannedUR } from \"../types.js\";\n\nexport interface BtcSignature {\n signature: string;\n publicKey: string;\n requestId: string | undefined;\n}\n\nexport function parseBtcSignature(scanned: ScannedUR): BtcSignature {\n if (scanned.type !== \"btc-signature\") {\n throw new Error(`Expected btc-signature, got: ${scanned.type}`);\n }\n\n const map = cborDecode(scanned.cbor, {\n useMaps: true,\n tags: Object.assign([] as TagDecoder[], { 37: (v: unknown) => v }),\n }) as Map<number, unknown>;\n\n const requestId = map.get(1) as Uint8Array | undefined;\n const sigBytes = map.get(2) as Uint8Array | undefined;\n const publicKeyBytes = map.get(3) as Uint8Array | undefined;\n\n if (!sigBytes || sigBytes.length !== 65) {\n throw new Error(\"Invalid or missing BTC signature bytes\");\n }\n if (!publicKeyBytes || publicKeyBytes.length !== 33) {\n throw new Error(\"Invalid or missing BTC public key bytes\");\n }\n\n return {\n signature: bytesToBase64(sigBytes),\n publicKey: bytesToHex(publicKeyBytes),\n requestId: requestId ? bytesToHex(requestId) : undefined,\n };\n}\n","import { decode as cborDecode } from \"cborg\";\n\nimport { bytesToHex, hexToBytes } from \"../bytes.js\";\nimport { encode } from \"../cbor.js\";\nimport type { ScannedUR } from \"../types.js\";\nimport { encodeURParts } from \"../urEncoding.js\";\n\nexport interface CryptoPsbt {\n psbt: Uint8Array;\n psbtHex: string;\n}\n\nfunction normalizePsbt(psbt: Uint8Array | string): Uint8Array {\n try {\n return typeof psbt === \"string\" ? hexToBytes(psbt) : psbt;\n } catch (error) {\n throw new Error(\"Invalid PSBT hex\", { cause: error });\n }\n}\n\nexport function parseCryptoPsbt(scanned: ScannedUR): CryptoPsbt {\n if (scanned.type !== \"crypto-psbt\") {\n throw new Error(`Expected crypto-psbt, got: ${scanned.type}`);\n }\n\n const psbt = cborDecode(scanned.cbor) as unknown;\n if (!(psbt instanceof Uint8Array)) {\n throw new Error(\"Invalid crypto-psbt payload\");\n }\n\n return {\n psbt,\n psbtHex: bytesToHex(psbt),\n };\n}\n\nexport function buildCryptoPsbtURParts(psbt: Uint8Array | string): string[] {\n return encodeURParts(encode(normalizePsbt(psbt)), \"crypto-psbt\");\n}\n\nexport function buildCryptoPsbtUR(psbt: Uint8Array | string): string {\n return buildCryptoPsbtURParts(psbt)[0];\n}\n"],"mappings":"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","names":["firstChild","cborDecode","import_cborg","cborDecode","TAG_KEYPATH","randomBytes","buildKeypath","import_cborg","cborDecode","import_cborg","cborDecode"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/btc/address.ts","../src/bytes.ts","../src/btc/deriveAccount.ts","../src/eth/address.ts","../src/eth/deriveAccount.ts","../src/parseXpub.ts","../src/parseConnection.ts","../src/cbor.ts","../src/urEncoding.ts","../src/eth/signRequest.ts","../src/eth/signature.ts","../src/btc/signRequest.ts","../src/btc/signature.ts","../src/btc/psbt.ts"],"sourcesContent":["// Types\nexport type {\n ScannedUR,\n Chain,\n QRKitConfig,\n Account,\n EvmAccount,\n BtcAccount,\n} from \"./types.js\";\nexport type { ParsedXpub, XpubType } from \"./parseXpub.js\";\n\n// Connection\nexport { parseConnection } from \"./parseConnection.js\";\n\n// EVM signing\nexport {\n buildEthSignRequestUR,\n buildEthSignRequestURParts,\n EthDataType,\n} from \"./eth/signRequest.js\";\nexport type { EthDataTypeValue, EthSignRequestParams } from \"./eth/signRequest.js\";\nexport { parseEthSignature } from \"./eth/signature.js\";\n\n// BTC signing\nexport {\n buildBtcSignRequestUR,\n buildBtcSignRequestURParts,\n BtcDataType,\n} from \"./btc/signRequest.js\";\nexport type { BtcDataTypeValue, BtcSignRequestParams } from \"./btc/signRequest.js\";\nexport { parseBtcSignature } from \"./btc/signature.js\";\nexport type { BtcSignature } from \"./btc/signature.js\";\nexport {\n buildCryptoPsbtUR,\n buildCryptoPsbtURParts,\n parseCryptoPsbt,\n} from \"./btc/psbt.js\";\nexport type { CryptoPsbt } from \"./btc/psbt.js\";\n","import { bech32, createBase58check } from \"@scure/base\";\nimport { ripemd160 } from \"@noble/hashes/legacy.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n\nexport type BtcScriptType = \"p2wpkh\" | \"p2sh-p2wpkh\" | \"p2pkh\";\n\nconst base58check = createBase58check(sha256);\n\nfunction hash160(bytes: Uint8Array): Uint8Array {\n return ripemd160(sha256(bytes));\n}\n\n/** Native SegWit — P2WPKH, `bc1q...` */\nexport function pubKeyToP2wpkh(compressedPubKey: Uint8Array): string {\n const h = hash160(compressedPubKey);\n const words = bech32.toWords(h);\n return bech32.encode(\"bc\", [0, ...words]);\n}\n\n/** Nested SegWit — P2SH-P2WPKH, `3...` */\nexport function pubKeyToP2shP2wpkh(compressedPubKey: Uint8Array): string {\n const h = hash160(compressedPubKey);\n // redeemScript = OP_0 <20-byte-pubkey-hash>\n const redeemScript = new Uint8Array(22);\n redeemScript[0] = 0x00;\n redeemScript[1] = 0x14;\n redeemScript.set(h, 2);\n const scriptHash = hash160(redeemScript);\n const payload = new Uint8Array(21);\n payload[0] = 0x05; // P2SH version byte\n payload.set(scriptHash, 1);\n return base58check.encode(payload);\n}\n\n/** Legacy — P2PKH, `1...` */\nexport function pubKeyToP2pkh(compressedPubKey: Uint8Array): string {\n const h = hash160(compressedPubKey);\n const payload = new Uint8Array(21);\n payload[0] = 0x00; // mainnet P2PKH version byte\n payload.set(h, 1);\n return base58check.encode(payload);\n}\n","export function bytesToBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\nexport function bytesToHex(bytes: Uint8Array): string {\n return [...bytes].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport function hexToBytes(hex: string): Uint8Array {\n const normalized = hex.trim().replace(/^0x/i, \"\");\n if (normalized.length % 2 !== 0 || !/^[0-9a-f]*$/i.test(normalized)) {\n throw new Error(\"Invalid hex string\");\n }\n\n return new Uint8Array(\n normalized.match(/.{2}/g)?.map((byte) => parseInt(byte, 16)) ?? [],\n );\n}\n","import type { HDKey } from \"@scure/bip32\";\n\nimport {\n pubKeyToP2pkh,\n pubKeyToP2shP2wpkh,\n pubKeyToP2wpkh,\n type BtcScriptType,\n} from \"./address.js\";\n\nimport { bytesToHex } from \"../bytes.js\";\nimport type { ParsedXpub } from \"../parseXpub.js\";\n\nexport interface DerivedBtcAccount {\n address: string;\n scriptType: BtcScriptType;\n publicKey: string;\n /** source-fingerprint from the scanned xpub — required for signing */\n sourceFingerprint: number | undefined;\n /** device or key name as reported by the hardware wallet, if available */\n device: string | undefined;\n}\n\n// Derive the first external address (index 0) from an account-level xpub.\n// Account-level xpub is at depth 3 (m/purpose'/coin'/account').\n// External chain is child 0, then address index 0.\nfunction firstChild(accountKey: HDKey): HDKey {\n return accountKey.deriveChild(0).deriveChild(0);\n}\n\nfunction scriptTypeFromPurpose(purpose: number | undefined): BtcScriptType | undefined {\n if (purpose === 84) return \"p2wpkh\";\n if (purpose === 49) return \"p2sh-p2wpkh\";\n if (purpose === 44) return \"p2pkh\";\n return undefined;\n}\n\nfunction deriveAddress(pubKey: Uint8Array, scriptType: BtcScriptType): string {\n if (scriptType === \"p2wpkh\") return pubKeyToP2wpkh(pubKey);\n if (scriptType === \"p2sh-p2wpkh\") return pubKeyToP2shP2wpkh(pubKey);\n return pubKeyToP2pkh(pubKey);\n}\n\nexport function deriveBtcAccount(parsed: ParsedXpub[]): DerivedBtcAccount[] {\n const results: DerivedBtcAccount[] = [];\n\n for (const entry of parsed) {\n const { hdKey, purpose, coinType, sourceFingerprint, name } = entry;\n\n // BTC: coin type 0\n if (coinType !== 0) continue;\n\n const scriptType = scriptTypeFromPurpose(purpose);\n if (!scriptType) continue;\n\n const child = firstChild(hdKey);\n if (!child.publicKey) continue;\n\n results.push({\n address: deriveAddress(child.publicKey, scriptType),\n scriptType,\n publicKey: bytesToHex(child.publicKey),\n sourceFingerprint,\n device: name,\n });\n }\n\n return results;\n}\n","import { secp256k1 } from \"@noble/curves/secp256k1.js\";\nimport { keccak_256 } from \"@noble/hashes/sha3.js\";\n\nexport function pubKeyToEthAddress(compressedPubKey: Uint8Array): string {\n const pubKeyHex = [...compressedPubKey]\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n const uncompressed = secp256k1.Point.fromHex(pubKeyHex).toBytes(false);\n const hash = keccak_256(uncompressed.slice(1));\n const hex = [...hash.slice(12)]\n .map((b: number) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n return toChecksumAddress(hex);\n}\n\nfunction toChecksumAddress(hex: string): string {\n const checksumHash = keccak_256(new TextEncoder().encode(hex));\n return (\n \"0x\" +\n [...hex]\n .map((c, i) => {\n if (c >= \"0\" && c <= \"9\") return c;\n const nibble =\n i % 2 === 0\n ? (checksumHash[Math.floor(i / 2)] >> 4) & 0xf\n : checksumHash[Math.floor(i / 2)] & 0xf;\n return nibble >= 8 ? c.toUpperCase() : c.toLowerCase();\n })\n .join(\"\")\n );\n}\n","import type { HDKey } from \"@scure/bip32\";\n\nimport { bytesToHex } from \"../bytes.js\";\nimport { pubKeyToEthAddress } from \"./address.js\";\nimport type { ParsedXpub } from \"../parseXpub.js\";\n\nexport interface DerivedAccount {\n address: string;\n publicKey: string;\n /** source-fingerprint from the scanned xpub — required by Shell for signing */\n sourceFingerprint: number | undefined;\n /** device or key name as reported by the hardware wallet, if available */\n device: string | undefined;\n}\n\n// Derive the first external address (index 0) from an account-level xpub.\n// Account-level xpub is at depth 3 (m/purpose'/coin'/account').\n// External chain is child 0, then address index 0.\nfunction firstChild(accountKey: HDKey): HDKey {\n return accountKey.deriveChild(0).deriveChild(0);\n}\n\nexport function deriveEvmAccount(parsed: ParsedXpub[]): DerivedAccount[] {\n const results: DerivedAccount[] = [];\n for (const entry of parsed) {\n const { hdKey, purpose, coinType, type, sourceFingerprint, name } = entry;\n const isEvm =\n (purpose === 44 && coinType === 60) || (purpose === undefined && type === \"xpub\");\n\n if (!isEvm) continue;\n\n const child = firstChild(hdKey);\n if (!child.publicKey) continue;\n\n results.push({\n address: pubKeyToEthAddress(child.publicKey),\n publicKey: bytesToHex(child.publicKey),\n sourceFingerprint,\n device: name,\n });\n }\n return results;\n}\n","import { HDKey } from \"@scure/bip32\";\nimport { decode as cborDecode, type TagDecoder } from \"cborg\";\n\nimport type { ScannedUR } from \"./types.js\";\n\nexport type XpubType = \"xpub\";\n\nexport interface ParsedXpub {\n hdKey: HDKey;\n type: XpubType;\n /** BIP-44 purpose index: 44 for EVM, 44/49/84 for supported BTC scripts */\n purpose: number | undefined;\n /** BIP-44 coin type: 60 = ETH, 0 = BTC */\n coinType: number | undefined;\n /** source-fingerprint from the origin keypath — required by Shell for signing */\n sourceFingerprint: number | undefined;\n /** device or key name from crypto-hdkey key 9, set by some wallets (e.g. Keystone) */\n name?: string;\n raw: string;\n}\n\ntype CborMap = Map<number, unknown>;\n\nfunction get(m: unknown, k: number): unknown {\n if (m instanceof Map) return (m as Map<number, unknown>).get(k);\n return undefined;\n}\n\nfunction bytesFromCbor(value: unknown): Uint8Array | undefined {\n if (value instanceof Uint8Array) return value;\n\n if (value instanceof Map && value.get(\"type\") === \"Buffer\") {\n const data = value.get(\"data\");\n if (\n Array.isArray(data) &&\n data.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 0xff)\n ) {\n return new Uint8Array(data);\n }\n }\n\n return undefined;\n}\n\nconst passthrough = (v: unknown) => v;\n\nfunction decodeCbor(cbor: Uint8Array): Map<number, unknown> {\n // Connection payloads often wrap the inner hdkey/output structures in semantic CBOR tags\n // (script expressions, crypto-output, vendor-specific wrappers, etc.). For connection\n // parsing we only care about the inner map/bytes shape, so tags are treated as annotations\n // and stripped during decode. Required structure is validated explicitly later.\n const tags = new Proxy([] as TagDecoder[], {\n get(target, property, receiver) {\n if (typeof property === \"string\" && /^\\d+$/.test(property)) {\n return passthrough;\n }\n return Reflect.get(target, property, receiver);\n },\n });\n\n return cborDecode(cbor, {\n useMaps: true,\n tags,\n }) as Map<number, unknown>;\n}\n\nfunction isCborMap(value: unknown): value is CborMap {\n return value instanceof Map;\n}\n\nfunction assertCryptoHdKeyShape(value: unknown): CborMap {\n if (!isCborMap(value)) {\n throw new Error(\"crypto-hdkey entry must be a CBOR map\");\n }\n\n if (!value.has(3) || !value.has(4)) {\n throw new Error(\"crypto-hdkey missing key-data or chain-code\");\n }\n\n return value;\n}\n\nfunction parseCryptoHdKey(map: CborMap, raw: string, fallbackName?: string): ParsedXpub {\n const keyData = bytesFromCbor(get(map, 3));\n const chainCode = bytesFromCbor(get(map, 4));\n\n if (!keyData || !chainCode) {\n throw new Error(\"crypto-hdkey missing key-data or chain-code\");\n }\n\n let purpose: number | undefined;\n let coinType: number | undefined;\n let sourceFingerprint: number | undefined;\n const origin = get(map, 6);\n if (origin) {\n const components = get(origin, 1);\n if (Array.isArray(components)) {\n if (components.length >= 1) purpose = components[0] as number;\n if (components.length >= 3) coinType = components[2] as number;\n }\n sourceFingerprint = get(origin, 2) as number | undefined;\n }\n\n const name = (get(map, 9) as string | undefined) ?? fallbackName;\n\n const hdKey = new HDKey({ publicKey: keyData, chainCode });\n return { hdKey, type: \"xpub\", purpose, coinType, sourceFingerprint, name, raw };\n}\n\nfunction parseScannedUR(scanned: ScannedUR): ParsedXpub | ParsedXpub[] {\n const { type, cbor } = scanned;\n const raw = `ur:${type}`;\n\n if (\n type !== \"crypto-hdkey\" &&\n type !== \"crypto-account\" &&\n type !== \"crypto-multi-accounts\"\n ) {\n throw new Error(`Unsupported UR type: ${type}`);\n }\n\n const map = decodeCbor(cbor);\n\n if (type === \"crypto-hdkey\") {\n return parseCryptoHdKey(assertCryptoHdKeyShape(map), raw);\n }\n\n const accounts = map.get(2) as unknown[] | undefined;\n if (!Array.isArray(accounts) || accounts.length === 0) {\n throw new Error(`${type} contains no keys`);\n }\n const fallbackName =\n type === \"crypto-multi-accounts\" ? (map.get(3) as string | undefined) : undefined;\n return accounts.map((entry) =>\n parseCryptoHdKey(assertCryptoHdKeyShape(entry), raw, fallbackName),\n );\n}\n\nexport function parseXpub(input: ScannedUR | string): ParsedXpub[] {\n if (typeof input !== \"string\") {\n const result = parseScannedUR(input);\n return Array.isArray(result) ? result : [result];\n }\n // Raw base58 xpub string — @scure/bip32 handles decoding directly\n const hdKey = HDKey.fromExtendedKey(input.trim());\n return [\n {\n hdKey,\n type: \"xpub\",\n purpose: undefined,\n coinType: undefined,\n sourceFingerprint: undefined,\n raw: input.trim(),\n },\n ];\n}\n","import { deriveBtcAccount } from \"./btc/deriveAccount.js\";\nimport { deriveEvmAccount } from \"./eth/deriveAccount.js\";\nimport { parseXpub } from \"./parseXpub.js\";\nimport type {\n Account,\n BtcAccount,\n Chain,\n EvmAccount,\n QRKitConfig,\n ScannedUR,\n} from \"./types.js\";\n\nconst ALL_CHAINS: Chain[] = [\"evm\", \"btc\"];\n\n/**\n * Parse a connection QR (crypto-hdkey or crypto-account) and return\n * only the accounts for the chains configured in QRKitConfig.\n *\n * A dApp configured with `chains: [\"evm\"]` will never see BTC accounts,\n * and vice versa. Both chains can be enabled with `chains: [\"evm\", \"btc\"]`.\n * If `chains` is omitted, all supported chains are tried.\n */\nexport function parseConnection(\n scannedUR: ScannedUR,\n config: QRKitConfig = {},\n): Account[] {\n const chains = config.chains ?? ALL_CHAINS;\n const parsed = parseXpub(scannedUR);\n const accounts: Account[] = [];\n\n if (chains.includes(\"evm\")) {\n for (const account of deriveEvmAccount(parsed)) {\n accounts.push({ chain: \"evm\", ...account } satisfies EvmAccount);\n }\n }\n\n if (chains.includes(\"btc\")) {\n for (const account of deriveBtcAccount(parsed)) {\n accounts.push({ chain: \"btc\", ...account } satisfies BtcAccount);\n }\n }\n\n return accounts;\n}\n","// Minimal CBOR encoder.\n// Supports only the types needed for eth-sign-request: uint, bytes, text, array, map (integer keys), bool, tag.\n\nfunction majorType(major: number, n: number): number[] {\n const base = major << 5;\n if (n <= 23) return [base | n];\n if (n <= 0xff) return [base | 0x18, n];\n if (n <= 0xffff) return [base | 0x19, (n >> 8) & 0xff, n & 0xff];\n return [base | 0x1a, (n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff];\n}\n\nexport function encodeItem(value: unknown): number[] {\n if (typeof value === \"boolean\") {\n return [value ? 0xf5 : 0xf4];\n }\n if (typeof value === \"number\") {\n return majorType(0, value);\n }\n if (value instanceof Uint8Array) {\n return [...majorType(2, value.length), ...value];\n }\n if (typeof value === \"string\") {\n const bytes = new TextEncoder().encode(value);\n return [...majorType(3, bytes.length), ...bytes];\n }\n if (Array.isArray(value)) {\n return [...majorType(4, value.length), ...value.flatMap(encodeItem)];\n }\n if (value instanceof CborTag) {\n return [...majorType(6, value.tag), ...encodeItem(value.value)];\n }\n if (value instanceof Map) {\n const entries = [...value.entries()];\n return [\n ...majorType(5, entries.length),\n ...entries.flatMap(([k, v]) => [...encodeItem(k), ...encodeItem(v)]),\n ];\n }\n throw new Error(`Unsupported CBOR value: ${typeof value}`);\n}\n\nexport class CborTag {\n tag: number;\n value: unknown;\n constructor(tag: number, value: unknown) {\n this.tag = tag;\n this.value = value;\n }\n}\n\nexport function encode(value: unknown): Uint8Array {\n return new Uint8Array(encodeItem(value));\n}\n","import { UR, UrFountainEncoder } from \"@qrkit/bc-ur-web\";\n\nexport function encodeURParts(\n cbor: Uint8Array,\n type: string,\n maxFragmentLength = 200,\n): string[] {\n const ur = UR.fromCbor({ type, payload: cbor });\n const encoder = new UrFountainEncoder(ur, maxFragmentLength);\n return encoder.getAllPartsUr().map((part) => part.toString().toUpperCase());\n}\n","import { encode, CborTag } from \"../cbor.js\";\nimport { encodeURParts } from \"../urEncoding.js\";\n\n// ERC-4527 eth-sign-request data types\nexport const EthDataType = {\n /** Legacy transaction (RLP-encoded). Wallet applies EIP-155: v = 35 + 2*chainId + recId */\n LegacyTransaction: 1,\n /** EIP-712 typed data bytes. Wallet hashes internally. */\n TypedData: 2,\n /** Personal message (EIP-191). Wallet prepends \"\\x19Ethereum Signed Message:\\n{len}\". */\n PersonalMessage: 3,\n /** EIP-1559 transaction (RLP-encoded). Wallet uses v = recId. */\n TypedTransaction: 4,\n} as const;\n\nexport type EthDataTypeValue = (typeof EthDataType)[keyof typeof EthDataType];\n\n// CBOR tag for crypto-keypath\nconst TAG_KEYPATH = 304;\n\nfunction randomBytes(n: number): Uint8Array {\n const buf = new Uint8Array(n);\n crypto.getRandomValues(buf);\n return buf;\n}\n\nfunction buildKeypath(\n purpose: number,\n coinType: number,\n sourceFingerprint: number | undefined,\n): CborTag {\n // m/purpose'/coinType'/0'/0/0\n const components = [purpose, true, coinType, true, 0, true, 0, false, 0, false];\n const keypathMap = new Map<number, unknown>([[1, components]]);\n if (sourceFingerprint !== undefined) {\n keypathMap.set(2, sourceFingerprint);\n }\n return new CborTag(TAG_KEYPATH, keypathMap);\n}\n\nexport interface EthSignRequestParams {\n /** Raw sign data. For PersonalMessage, a string is UTF-8 encoded automatically. */\n signData: Uint8Array | string;\n /** ERC-4527 data type. Defaults to PersonalMessage (3). Use EthDataType constants. */\n dataType?: number;\n address: string;\n sourceFingerprint: number | undefined;\n /** Chain ID — required by the wallet for v-value encoding on LegacyTransaction (type 1). */\n chainId?: number;\n origin?: string;\n}\n\nfunction buildEthSignRequestCbor(params: EthSignRequestParams): Uint8Array {\n const {\n signData,\n dataType = EthDataType.PersonalMessage,\n address,\n sourceFingerprint,\n chainId,\n origin = \"qrkit\",\n } = params;\n\n const requestId = randomBytes(16);\n const signBytes =\n typeof signData === \"string\" ? new TextEncoder().encode(signData) : signData;\n const keypath = buildKeypath(44, 60, sourceFingerprint);\n\n const addrHex = address.replace(/^0x/i, \"\");\n const addrBytes = new Uint8Array(addrHex.match(/.{2}/g)!.map((b) => parseInt(b, 16)));\n\n // Keys must be in strictly ascending order for zcbor (Shell firmware decoder).\n const map = new Map<number, unknown>([\n [1, new CborTag(37, requestId)], // request-id: uuid = #6.37(bstr)\n [2, signBytes], // sign-data\n [3, dataType], // data-type\n ]);\n\n if (chainId !== undefined) {\n map.set(4, chainId); // chain-id — must come before key 5\n }\n\n map.set(5, keypath); // derivation-path\n map.set(6, addrBytes); // address\n map.set(7, origin); // origin\n\n return encode(map);\n}\n\nexport function buildEthSignRequestURParts(params: EthSignRequestParams): string[] {\n return encodeURParts(buildEthSignRequestCbor(params), \"eth-sign-request\");\n}\n\nexport function buildEthSignRequestUR(params: EthSignRequestParams): string {\n return encodeURParts(buildEthSignRequestCbor(params), \"eth-sign-request\")[0];\n}\n","import { decode as cborDecode, type TagDecoder } from \"cborg\";\n\nimport { bytesToHex } from \"../bytes.js\";\nimport type { ScannedUR } from \"../types.js\";\n\nexport function parseEthSignature(scanned: ScannedUR): string {\n if (scanned.type !== \"eth-signature\") {\n throw new Error(`Expected eth-signature, got: ${scanned.type}`);\n }\n\n const map = cborDecode(scanned.cbor, {\n useMaps: true,\n tags: Object.assign([] as TagDecoder[], { 37: (v: unknown) => v }),\n }) as Map<number, unknown>;\n\n const sigBytes = map.get(2) as Uint8Array | undefined;\n if (!sigBytes || sigBytes.length < 64) {\n throw new Error(\"Invalid or missing signature bytes\");\n }\n\n return `0x${bytesToHex(sigBytes)}`;\n}\n","import { encode, CborTag } from \"../cbor.js\";\nimport { encodeURParts } from \"../urEncoding.js\";\nimport type { BtcScriptType } from \"./address.js\";\n\nexport const BtcDataType = {\n Message: 1,\n} as const;\n\nexport type BtcDataTypeValue = (typeof BtcDataType)[keyof typeof BtcDataType];\n\nconst TAG_KEYPATH = 304;\nconst PURPOSE_BY_SCRIPT_TYPE = {\n p2wpkh: 84,\n \"p2sh-p2wpkh\": 49,\n p2pkh: 44,\n} as const satisfies Record<BtcScriptType, number>;\n\nfunction randomBytes(n: number): Uint8Array {\n const buf = new Uint8Array(n);\n crypto.getRandomValues(buf);\n return buf;\n}\n\nfunction purposeFromScriptType(scriptType: BtcScriptType): number {\n return PURPOSE_BY_SCRIPT_TYPE[scriptType];\n}\n\nfunction buildKeypath(\n scriptType: BtcScriptType,\n sourceFingerprint: number | undefined,\n): CborTag {\n const purpose = purposeFromScriptType(scriptType);\n // m/purpose'/0'/0'/0/0\n const components = [purpose, true, 0, true, 0, true, 0, false, 0, false];\n const keypathMap = new Map<number, unknown>([[1, components]]);\n if (sourceFingerprint !== undefined) {\n keypathMap.set(2, sourceFingerprint);\n }\n return new CborTag(TAG_KEYPATH, keypathMap);\n}\n\nexport interface BtcSignRequestParams {\n /** Raw message data. Strings are UTF-8 encoded automatically. */\n signData: Uint8Array | string;\n address: string;\n /** BTC script type for choosing m/44', m/49', or m/84'. */\n scriptType: BtcScriptType;\n sourceFingerprint: number | undefined;\n origin?: string;\n}\n\nfunction buildBtcSignRequestCbor(params: BtcSignRequestParams): Uint8Array {\n const { signData, address, scriptType, sourceFingerprint, origin = \"qrkit\" } = params;\n const requestId = randomBytes(16);\n const signBytes =\n typeof signData === \"string\" ? new TextEncoder().encode(signData) : signData;\n const keypath = buildKeypath(scriptType, sourceFingerprint);\n\n return encode(\n new Map<number, unknown>([\n [1, new CborTag(37, requestId)], // request-id: uuid = #6.37(bstr)\n [2, signBytes], // sign-data\n [3, BtcDataType.Message], // data-type\n [4, [keypath]], // btc-derivation-paths\n [5, [address]], // btc-addresses\n [6, origin], // origin\n ]),\n );\n}\n\nexport function buildBtcSignRequestURParts(params: BtcSignRequestParams): string[] {\n return encodeURParts(buildBtcSignRequestCbor(params), \"btc-sign-request\");\n}\n\nexport function buildBtcSignRequestUR(params: BtcSignRequestParams): string {\n return encodeURParts(buildBtcSignRequestCbor(params), \"btc-sign-request\")[0];\n}\n","import { decode as cborDecode, type TagDecoder } from \"cborg\";\n\nimport { bytesToBase64, bytesToHex } from \"../bytes.js\";\nimport type { ScannedUR } from \"../types.js\";\n\nexport interface BtcSignature {\n signature: string;\n publicKey: string;\n requestId: string | undefined;\n}\n\nexport function parseBtcSignature(scanned: ScannedUR): BtcSignature {\n if (scanned.type !== \"btc-signature\") {\n throw new Error(`Expected btc-signature, got: ${scanned.type}`);\n }\n\n const map = cborDecode(scanned.cbor, {\n useMaps: true,\n tags: Object.assign([] as TagDecoder[], { 37: (v: unknown) => v }),\n }) as Map<number, unknown>;\n\n const requestId = map.get(1) as Uint8Array | undefined;\n const sigBytes = map.get(2) as Uint8Array | undefined;\n const publicKeyBytes = map.get(3) as Uint8Array | undefined;\n\n if (!sigBytes || sigBytes.length !== 65) {\n throw new Error(\"Invalid or missing BTC signature bytes\");\n }\n if (!publicKeyBytes || publicKeyBytes.length !== 33) {\n throw new Error(\"Invalid or missing BTC public key bytes\");\n }\n\n return {\n signature: bytesToBase64(sigBytes),\n publicKey: bytesToHex(publicKeyBytes),\n requestId: requestId ? bytesToHex(requestId) : undefined,\n };\n}\n","import { decode as cborDecode } from \"cborg\";\n\nimport { bytesToHex, hexToBytes } from \"../bytes.js\";\nimport { encode } from \"../cbor.js\";\nimport type { ScannedUR } from \"../types.js\";\nimport { encodeURParts } from \"../urEncoding.js\";\n\nexport interface CryptoPsbt {\n psbt: Uint8Array;\n psbtHex: string;\n}\n\nfunction normalizePsbt(psbt: Uint8Array | string): Uint8Array {\n try {\n return typeof psbt === \"string\" ? hexToBytes(psbt) : psbt;\n } catch (error) {\n throw new Error(\"Invalid PSBT hex\", { cause: error });\n }\n}\n\nexport function parseCryptoPsbt(scanned: ScannedUR): CryptoPsbt {\n if (scanned.type !== \"crypto-psbt\") {\n throw new Error(`Expected crypto-psbt, got: ${scanned.type}`);\n }\n\n const psbt = cborDecode(scanned.cbor) as unknown;\n if (!(psbt instanceof Uint8Array)) {\n throw new Error(\"Invalid crypto-psbt payload\");\n }\n\n return {\n psbt,\n psbtHex: bytesToHex(psbt),\n };\n}\n\nexport function buildCryptoPsbtURParts(psbt: Uint8Array | string): string[] {\n return encodeURParts(encode(normalizePsbt(psbt)), \"crypto-psbt\");\n}\n\nexport function buildCryptoPsbtUR(psbt: Uint8Array | string): string {\n return buildCryptoPsbtURParts(psbt)[0];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAA0C;AAC1C,oBAA0B;AAC1B,kBAAuB;AAIvB,IAAM,kBAAc,+BAAkB,kBAAM;AAE5C,SAAS,QAAQ,OAA+B;AAC9C,aAAO,6BAAU,oBAAO,KAAK,CAAC;AAChC;AAGO,SAAS,eAAe,kBAAsC;AACnE,QAAM,IAAI,QAAQ,gBAAgB;AAClC,QAAM,QAAQ,mBAAO,QAAQ,CAAC;AAC9B,SAAO,mBAAO,OAAO,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC;AAC1C;AAGO,SAAS,mBAAmB,kBAAsC;AACvE,QAAM,IAAI,QAAQ,gBAAgB;AAElC,QAAM,eAAe,IAAI,WAAW,EAAE;AACtC,eAAa,CAAC,IAAI;AAClB,eAAa,CAAC,IAAI;AAClB,eAAa,IAAI,GAAG,CAAC;AACrB,QAAM,aAAa,QAAQ,YAAY;AACvC,QAAM,UAAU,IAAI,WAAW,EAAE;AACjC,UAAQ,CAAC,IAAI;AACb,UAAQ,IAAI,YAAY,CAAC;AACzB,SAAO,YAAY,OAAO,OAAO;AACnC;AAGO,SAAS,cAAc,kBAAsC;AAClE,QAAM,IAAI,QAAQ,gBAAgB;AAClC,QAAM,UAAU,IAAI,WAAW,EAAE;AACjC,UAAQ,CAAC,IAAI;AACb,UAAQ,IAAI,GAAG,CAAC;AAChB,SAAO,YAAY,OAAO,OAAO;AACnC;;;ACzCO,SAAS,cAAc,OAA2B;AACvD,MAAI,SAAS;AACb,aAAW,QAAQ,OAAO;AACxB,cAAU,OAAO,aAAa,IAAI;AAAA,EACpC;AACA,SAAO,KAAK,MAAM;AACpB;AAEO,SAAS,WAAW,OAA2B;AACpD,SAAO,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE;AACvE;AAEO,SAAS,WAAW,KAAyB;AAClD,QAAM,aAAa,IAAI,KAAK,EAAE,QAAQ,QAAQ,EAAE;AAChD,MAAI,WAAW,SAAS,MAAM,KAAK,CAAC,eAAe,KAAK,UAAU,GAAG;AACnE,UAAM,IAAI,MAAM,oBAAoB;AAAA,EACtC;AAEA,SAAO,IAAI;AAAA,IACT,WAAW,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,SAAS,MAAM,EAAE,CAAC,KAAK,CAAC;AAAA,EACnE;AACF;;;ACIA,SAAS,WAAW,YAA0B;AAC5C,SAAO,WAAW,YAAY,CAAC,EAAE,YAAY,CAAC;AAChD;AAEA,SAAS,sBAAsB,SAAwD;AACrF,MAAI,YAAY,GAAI,QAAO;AAC3B,MAAI,YAAY,GAAI,QAAO;AAC3B,MAAI,YAAY,GAAI,QAAO;AAC3B,SAAO;AACT;AAEA,SAAS,cAAc,QAAoB,YAAmC;AAC5E,MAAI,eAAe,SAAU,QAAO,eAAe,MAAM;AACzD,MAAI,eAAe,cAAe,QAAO,mBAAmB,MAAM;AAClE,SAAO,cAAc,MAAM;AAC7B;AAEO,SAAS,iBAAiB,QAA2C;AAC1E,QAAM,UAA+B,CAAC;AAEtC,aAAW,SAAS,QAAQ;AAC1B,UAAM,EAAE,OAAO,SAAS,UAAU,mBAAmB,KAAK,IAAI;AAG9D,QAAI,aAAa,EAAG;AAEpB,UAAM,aAAa,sBAAsB,OAAO;AAChD,QAAI,CAAC,WAAY;AAEjB,UAAM,QAAQ,WAAW,KAAK;AAC9B,QAAI,CAAC,MAAM,UAAW;AAEtB,YAAQ,KAAK;AAAA,MACX,SAAS,cAAc,MAAM,WAAW,UAAU;AAAA,MAClD;AAAA,MACA,WAAW,WAAW,MAAM,SAAS;AAAA,MACrC;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;ACnEA,uBAA0B;AAC1B,kBAA2B;AAEpB,SAAS,mBAAmB,kBAAsC;AACvE,QAAM,YAAY,CAAC,GAAG,gBAAgB,EACnC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AACV,QAAM,eAAe,2BAAU,MAAM,QAAQ,SAAS,EAAE,QAAQ,KAAK;AACrE,QAAM,WAAO,wBAAW,aAAa,MAAM,CAAC,CAAC;AAC7C,QAAM,MAAM,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC,EAC3B,IAAI,CAAC,MAAc,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAClD,KAAK,EAAE;AACV,SAAO,kBAAkB,GAAG;AAC9B;AAEA,SAAS,kBAAkB,KAAqB;AAC9C,QAAM,mBAAe,wBAAW,IAAI,YAAY,EAAE,OAAO,GAAG,CAAC;AAC7D,SACE,OACA,CAAC,GAAG,GAAG,EACJ,IAAI,CAAC,GAAG,MAAM;AACb,QAAI,KAAK,OAAO,KAAK,IAAK,QAAO;AACjC,UAAM,SACJ,IAAI,MAAM,IACL,aAAa,KAAK,MAAM,IAAI,CAAC,CAAC,KAAK,IAAK,KACzC,aAAa,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI;AACxC,WAAO,UAAU,IAAI,EAAE,YAAY,IAAI,EAAE,YAAY;AAAA,EACvD,CAAC,EACA,KAAK,EAAE;AAEd;;;ACZA,SAASA,YAAW,YAA0B;AAC5C,SAAO,WAAW,YAAY,CAAC,EAAE,YAAY,CAAC;AAChD;AAEO,SAAS,iBAAiB,QAAwC;AACvE,QAAM,UAA4B,CAAC;AACnC,aAAW,SAAS,QAAQ;AAC1B,UAAM,EAAE,OAAO,SAAS,UAAU,MAAM,mBAAmB,KAAK,IAAI;AACpE,UAAM,QACH,YAAY,MAAM,aAAa,MAAQ,YAAY,UAAa,SAAS;AAE5E,QAAI,CAAC,MAAO;AAEZ,UAAM,QAAQA,YAAW,KAAK;AAC9B,QAAI,CAAC,MAAM,UAAW;AAEtB,YAAQ,KAAK;AAAA,MACX,SAAS,mBAAmB,MAAM,SAAS;AAAA,MAC3C,WAAW,WAAW,MAAM,SAAS;AAAA,MACrC;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;AC1CA,mBAAsB;AACtB,mBAAsD;AAsBtD,SAAS,IAAI,GAAY,GAAoB;AAC3C,MAAI,aAAa,IAAK,QAAQ,EAA2B,IAAI,CAAC;AAC9D,SAAO;AACT;AAEA,SAAS,cAAc,OAAwC;AAC7D,MAAI,iBAAiB,WAAY,QAAO;AAExC,MAAI,iBAAiB,OAAO,MAAM,IAAI,MAAM,MAAM,UAAU;AAC1D,UAAM,OAAO,MAAM,IAAI,MAAM;AAC7B,QACE,MAAM,QAAQ,IAAI,KAClB,KAAK,MAAM,CAAC,SAAS,OAAO,UAAU,IAAI,KAAK,QAAQ,KAAK,QAAQ,GAAI,GACxE;AACA,aAAO,IAAI,WAAW,IAAI;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,cAAc,CAAC,MAAe;AAEpC,SAAS,WAAW,MAAwC;AAK1D,QAAM,OAAO,IAAI,MAAM,CAAC,GAAmB;AAAA,IACzC,IAAI,QAAQ,UAAU,UAAU;AAC9B,UAAI,OAAO,aAAa,YAAY,QAAQ,KAAK,QAAQ,GAAG;AAC1D,eAAO;AAAA,MACT;AACA,aAAO,QAAQ,IAAI,QAAQ,UAAU,QAAQ;AAAA,IAC/C;AAAA,EACF,CAAC;AAED,aAAO,aAAAC,QAAW,MAAM;AAAA,IACtB,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AACH;AAEA,SAAS,UAAU,OAAkC;AACnD,SAAO,iBAAiB;AAC1B;AAEA,SAAS,uBAAuB,OAAyB;AACvD,MAAI,CAAC,UAAU,KAAK,GAAG;AACrB,UAAM,IAAI,MAAM,uCAAuC;AAAA,EACzD;AAEA,MAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG;AAClC,UAAM,IAAI,MAAM,6CAA6C;AAAA,EAC/D;AAEA,SAAO;AACT;AAEA,SAAS,iBAAiB,KAAc,KAAa,cAAmC;AACtF,QAAM,UAAU,cAAc,IAAI,KAAK,CAAC,CAAC;AACzC,QAAM,YAAY,cAAc,IAAI,KAAK,CAAC,CAAC;AAE3C,MAAI,CAAC,WAAW,CAAC,WAAW;AAC1B,UAAM,IAAI,MAAM,6CAA6C;AAAA,EAC/D;AAEA,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,QAAM,SAAS,IAAI,KAAK,CAAC;AACzB,MAAI,QAAQ;AACV,UAAM,aAAa,IAAI,QAAQ,CAAC;AAChC,QAAI,MAAM,QAAQ,UAAU,GAAG;AAC7B,UAAI,WAAW,UAAU,EAAG,WAAU,WAAW,CAAC;AAClD,UAAI,WAAW,UAAU,EAAG,YAAW,WAAW,CAAC;AAAA,IACrD;AACA,wBAAoB,IAAI,QAAQ,CAAC;AAAA,EACnC;AAEA,QAAM,OAAQ,IAAI,KAAK,CAAC,KAA4B;AAEpD,QAAM,QAAQ,IAAI,mBAAM,EAAE,WAAW,SAAS,UAAU,CAAC;AACzD,SAAO,EAAE,OAAO,MAAM,QAAQ,SAAS,UAAU,mBAAmB,MAAM,IAAI;AAChF;AAEA,SAAS,eAAe,SAA+C;AACrE,QAAM,EAAE,MAAM,KAAK,IAAI;AACvB,QAAM,MAAM,MAAM,IAAI;AAEtB,MACE,SAAS,kBACT,SAAS,oBACT,SAAS,yBACT;AACA,UAAM,IAAI,MAAM,wBAAwB,IAAI,EAAE;AAAA,EAChD;AAEA,QAAM,MAAM,WAAW,IAAI;AAE3B,MAAI,SAAS,gBAAgB;AAC3B,WAAO,iBAAiB,uBAAuB,GAAG,GAAG,GAAG;AAAA,EAC1D;AAEA,QAAM,WAAW,IAAI,IAAI,CAAC;AAC1B,MAAI,CAAC,MAAM,QAAQ,QAAQ,KAAK,SAAS,WAAW,GAAG;AACrD,UAAM,IAAI,MAAM,GAAG,IAAI,mBAAmB;AAAA,EAC5C;AACA,QAAM,eACJ,SAAS,0BAA2B,IAAI,IAAI,CAAC,IAA2B;AAC1E,SAAO,SAAS;AAAA,IAAI,CAAC,UACnB,iBAAiB,uBAAuB,KAAK,GAAG,KAAK,YAAY;AAAA,EACnE;AACF;AAEO,SAAS,UAAU,OAAyC;AACjE,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,SAAS,eAAe,KAAK;AACnC,WAAO,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AAAA,EACjD;AAEA,QAAM,QAAQ,mBAAM,gBAAgB,MAAM,KAAK,CAAC;AAChD,SAAO;AAAA,IACL;AAAA,MACE;AAAA,MACA,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,MACV,mBAAmB;AAAA,MACnB,KAAK,MAAM,KAAK;AAAA,IAClB;AAAA,EACF;AACF;;;AC/IA,IAAM,aAAsB,CAAC,OAAO,KAAK;AAUlC,SAAS,gBACd,WACA,SAAsB,CAAC,GACZ;AACX,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,SAAS,UAAU,SAAS;AAClC,QAAM,WAAsB,CAAC;AAE7B,MAAI,OAAO,SAAS,KAAK,GAAG;AAC1B,eAAW,WAAW,iBAAiB,MAAM,GAAG;AAC9C,eAAS,KAAK,EAAE,OAAO,OAAO,GAAG,QAAQ,CAAsB;AAAA,IACjE;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,KAAK,GAAG;AAC1B,eAAW,WAAW,iBAAiB,MAAM,GAAG;AAC9C,eAAS,KAAK,EAAE,OAAO,OAAO,GAAG,QAAQ,CAAsB;AAAA,IACjE;AAAA,EACF;AAEA,SAAO;AACT;;;ACxCA,SAAS,UAAU,OAAe,GAAqB;AACrD,QAAM,OAAO,SAAS;AACtB,MAAI,KAAK,GAAI,QAAO,CAAC,OAAO,CAAC;AAC7B,MAAI,KAAK,IAAM,QAAO,CAAC,OAAO,IAAM,CAAC;AACrC,MAAI,KAAK,MAAQ,QAAO,CAAC,OAAO,IAAO,KAAK,IAAK,KAAM,IAAI,GAAI;AAC/D,SAAO,CAAC,OAAO,IAAO,KAAK,KAAM,KAAO,KAAK,KAAM,KAAO,KAAK,IAAK,KAAM,IAAI,GAAI;AACpF;AAEO,SAAS,WAAW,OAA0B;AACnD,MAAI,OAAO,UAAU,WAAW;AAC9B,WAAO,CAAC,QAAQ,MAAO,GAAI;AAAA,EAC7B;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,UAAU,GAAG,KAAK;AAAA,EAC3B;AACA,MAAI,iBAAiB,YAAY;AAC/B,WAAO,CAAC,GAAG,UAAU,GAAG,MAAM,MAAM,GAAG,GAAG,KAAK;AAAA,EACjD;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,KAAK;AAC5C,WAAO,CAAC,GAAG,UAAU,GAAG,MAAM,MAAM,GAAG,GAAG,KAAK;AAAA,EACjD;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,CAAC,GAAG,UAAU,GAAG,MAAM,MAAM,GAAG,GAAG,MAAM,QAAQ,UAAU,CAAC;AAAA,EACrE;AACA,MAAI,iBAAiB,SAAS;AAC5B,WAAO,CAAC,GAAG,UAAU,GAAG,MAAM,GAAG,GAAG,GAAG,WAAW,MAAM,KAAK,CAAC;AAAA,EAChE;AACA,MAAI,iBAAiB,KAAK;AACxB,UAAM,UAAU,CAAC,GAAG,MAAM,QAAQ,CAAC;AACnC,WAAO;AAAA,MACL,GAAG,UAAU,GAAG,QAAQ,MAAM;AAAA,MAC9B,GAAG,QAAQ,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC;AAAA,IACrE;AAAA,EACF;AACA,QAAM,IAAI,MAAM,2BAA2B,OAAO,KAAK,EAAE;AAC3D;AAEO,IAAM,UAAN,MAAc;AAAA,EACnB;AAAA,EACA;AAAA,EACA,YAAY,KAAa,OAAgB;AACvC,SAAK,MAAM;AACX,SAAK,QAAQ;AAAA,EACf;AACF;AAEO,SAAS,OAAO,OAA4B;AACjD,SAAO,IAAI,WAAW,WAAW,KAAK,CAAC;AACzC;;;ACpDA,uBAAsC;AAE/B,SAAS,cACd,MACA,MACA,oBAAoB,KACV;AACV,QAAM,KAAK,oBAAG,SAAS,EAAE,MAAM,SAAS,KAAK,CAAC;AAC9C,QAAM,UAAU,IAAI,mCAAkB,IAAI,iBAAiB;AAC3D,SAAO,QAAQ,cAAc,EAAE,IAAI,CAAC,SAAS,KAAK,SAAS,EAAE,YAAY,CAAC;AAC5E;;;ACNO,IAAM,cAAc;AAAA;AAAA,EAEzB,mBAAmB;AAAA;AAAA,EAEnB,WAAW;AAAA;AAAA,EAEX,iBAAiB;AAAA;AAAA,EAEjB,kBAAkB;AACpB;AAKA,IAAM,cAAc;AAEpB,SAAS,YAAY,GAAuB;AAC1C,QAAM,MAAM,IAAI,WAAW,CAAC;AAC5B,SAAO,gBAAgB,GAAG;AAC1B,SAAO;AACT;AAEA,SAAS,aACP,SACA,UACA,mBACS;AAET,QAAM,aAAa,CAAC,SAAS,MAAM,UAAU,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK;AAC9E,QAAM,aAAa,oBAAI,IAAqB,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC;AAC7D,MAAI,sBAAsB,QAAW;AACnC,eAAW,IAAI,GAAG,iBAAiB;AAAA,EACrC;AACA,SAAO,IAAI,QAAQ,aAAa,UAAU;AAC5C;AAcA,SAAS,wBAAwB,QAA0C;AACzE,QAAM;AAAA,IACJ;AAAA,IACA,WAAW,YAAY;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,EACX,IAAI;AAEJ,QAAM,YAAY,YAAY,EAAE;AAChC,QAAM,YACJ,OAAO,aAAa,WAAW,IAAI,YAAY,EAAE,OAAO,QAAQ,IAAI;AACtE,QAAM,UAAU,aAAa,IAAI,IAAI,iBAAiB;AAEtD,QAAM,UAAU,QAAQ,QAAQ,QAAQ,EAAE;AAC1C,QAAM,YAAY,IAAI,WAAW,QAAQ,MAAM,OAAO,EAAG,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC,CAAC;AAGpF,QAAM,MAAM,oBAAI,IAAqB;AAAA,IACnC,CAAC,GAAG,IAAI,QAAQ,IAAI,SAAS,CAAC;AAAA;AAAA,IAC9B,CAAC,GAAG,SAAS;AAAA;AAAA,IACb,CAAC,GAAG,QAAQ;AAAA;AAAA,EACd,CAAC;AAED,MAAI,YAAY,QAAW;AACzB,QAAI,IAAI,GAAG,OAAO;AAAA,EACpB;AAEA,MAAI,IAAI,GAAG,OAAO;AAClB,MAAI,IAAI,GAAG,SAAS;AACpB,MAAI,IAAI,GAAG,MAAM;AAEjB,SAAO,OAAO,GAAG;AACnB;AAEO,SAAS,2BAA2B,QAAwC;AACjF,SAAO,cAAc,wBAAwB,MAAM,GAAG,kBAAkB;AAC1E;AAEO,SAAS,sBAAsB,QAAsC;AAC1E,SAAO,cAAc,wBAAwB,MAAM,GAAG,kBAAkB,EAAE,CAAC;AAC7E;;;AC9FA,IAAAC,gBAAsD;AAK/C,SAAS,kBAAkB,SAA4B;AAC5D,MAAI,QAAQ,SAAS,iBAAiB;AACpC,UAAM,IAAI,MAAM,gCAAgC,QAAQ,IAAI,EAAE;AAAA,EAChE;AAEA,QAAM,UAAM,cAAAC,QAAW,QAAQ,MAAM;AAAA,IACnC,SAAS;AAAA,IACT,MAAM,OAAO,OAAO,CAAC,GAAmB,EAAE,IAAI,CAAC,MAAe,EAAE,CAAC;AAAA,EACnE,CAAC;AAED,QAAM,WAAW,IAAI,IAAI,CAAC;AAC1B,MAAI,CAAC,YAAY,SAAS,SAAS,IAAI;AACrC,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAEA,SAAO,KAAK,WAAW,QAAQ,CAAC;AAClC;;;ACjBO,IAAM,cAAc;AAAA,EACzB,SAAS;AACX;AAIA,IAAMC,eAAc;AACpB,IAAM,yBAAyB;AAAA,EAC7B,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,OAAO;AACT;AAEA,SAASC,aAAY,GAAuB;AAC1C,QAAM,MAAM,IAAI,WAAW,CAAC;AAC5B,SAAO,gBAAgB,GAAG;AAC1B,SAAO;AACT;AAEA,SAAS,sBAAsB,YAAmC;AAChE,SAAO,uBAAuB,UAAU;AAC1C;AAEA,SAASC,cACP,YACA,mBACS;AACT,QAAM,UAAU,sBAAsB,UAAU;AAEhD,QAAM,aAAa,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK;AACvE,QAAM,aAAa,oBAAI,IAAqB,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC;AAC7D,MAAI,sBAAsB,QAAW;AACnC,eAAW,IAAI,GAAG,iBAAiB;AAAA,EACrC;AACA,SAAO,IAAI,QAAQF,cAAa,UAAU;AAC5C;AAYA,SAAS,wBAAwB,QAA0C;AACzE,QAAM,EAAE,UAAU,SAAS,YAAY,mBAAmB,SAAS,QAAQ,IAAI;AAC/E,QAAM,YAAYC,aAAY,EAAE;AAChC,QAAM,YACJ,OAAO,aAAa,WAAW,IAAI,YAAY,EAAE,OAAO,QAAQ,IAAI;AACtE,QAAM,UAAUC,cAAa,YAAY,iBAAiB;AAE1D,SAAO;AAAA,IACL,oBAAI,IAAqB;AAAA,MACvB,CAAC,GAAG,IAAI,QAAQ,IAAI,SAAS,CAAC;AAAA;AAAA,MAC9B,CAAC,GAAG,SAAS;AAAA;AAAA,MACb,CAAC,GAAG,YAAY,OAAO;AAAA;AAAA,MACvB,CAAC,GAAG,CAAC,OAAO,CAAC;AAAA;AAAA,MACb,CAAC,GAAG,CAAC,OAAO,CAAC;AAAA;AAAA,MACb,CAAC,GAAG,MAAM;AAAA;AAAA,IACZ,CAAC;AAAA,EACH;AACF;AAEO,SAAS,2BAA2B,QAAwC;AACjF,SAAO,cAAc,wBAAwB,MAAM,GAAG,kBAAkB;AAC1E;AAEO,SAAS,sBAAsB,QAAsC;AAC1E,SAAO,cAAc,wBAAwB,MAAM,GAAG,kBAAkB,EAAE,CAAC;AAC7E;;;AC5EA,IAAAC,gBAAsD;AAW/C,SAAS,kBAAkB,SAAkC;AAClE,MAAI,QAAQ,SAAS,iBAAiB;AACpC,UAAM,IAAI,MAAM,gCAAgC,QAAQ,IAAI,EAAE;AAAA,EAChE;AAEA,QAAM,UAAM,cAAAC,QAAW,QAAQ,MAAM;AAAA,IACnC,SAAS;AAAA,IACT,MAAM,OAAO,OAAO,CAAC,GAAmB,EAAE,IAAI,CAAC,MAAe,EAAE,CAAC;AAAA,EACnE,CAAC;AAED,QAAM,YAAY,IAAI,IAAI,CAAC;AAC3B,QAAM,WAAW,IAAI,IAAI,CAAC;AAC1B,QAAM,iBAAiB,IAAI,IAAI,CAAC;AAEhC,MAAI,CAAC,YAAY,SAAS,WAAW,IAAI;AACvC,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AACA,MAAI,CAAC,kBAAkB,eAAe,WAAW,IAAI;AACnD,UAAM,IAAI,MAAM,yCAAyC;AAAA,EAC3D;AAEA,SAAO;AAAA,IACL,WAAW,cAAc,QAAQ;AAAA,IACjC,WAAW,WAAW,cAAc;AAAA,IACpC,WAAW,YAAY,WAAW,SAAS,IAAI;AAAA,EACjD;AACF;;;ACrCA,IAAAC,gBAAqC;AAYrC,SAAS,cAAc,MAAuC;AAC5D,MAAI;AACF,WAAO,OAAO,SAAS,WAAW,WAAW,IAAI,IAAI;AAAA,EACvD,SAAS,OAAO;AACd,UAAM,IAAI,MAAM,oBAAoB,EAAE,OAAO,MAAM,CAAC;AAAA,EACtD;AACF;AAEO,SAAS,gBAAgB,SAAgC;AAC9D,MAAI,QAAQ,SAAS,eAAe;AAClC,UAAM,IAAI,MAAM,8BAA8B,QAAQ,IAAI,EAAE;AAAA,EAC9D;AAEA,QAAM,WAAO,cAAAC,QAAW,QAAQ,IAAI;AACpC,MAAI,EAAE,gBAAgB,aAAa;AACjC,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AAEA,SAAO;AAAA,IACL;AAAA,IACA,SAAS,WAAW,IAAI;AAAA,EAC1B;AACF;AAEO,SAAS,uBAAuB,MAAqC;AAC1E,SAAO,cAAc,OAAO,cAAc,IAAI,CAAC,GAAG,aAAa;AACjE;AAEO,SAAS,kBAAkB,MAAmC;AACnE,SAAO,uBAAuB,IAAI,EAAE,CAAC;AACvC;","names":["firstChild","cborDecode","import_cborg","cborDecode","TAG_KEYPATH","randomBytes","buildKeypath","import_cborg","cborDecode","import_cborg","cborDecode"]}
|
package/dist/index.js
CHANGED
|
@@ -1,24 +1,3 @@
|
|
|
1
|
-
// src/bytes.ts
|
|
2
|
-
function bytesToBase64(bytes) {
|
|
3
|
-
let binary = "";
|
|
4
|
-
for (const byte of bytes) {
|
|
5
|
-
binary += String.fromCharCode(byte);
|
|
6
|
-
}
|
|
7
|
-
return btoa(binary);
|
|
8
|
-
}
|
|
9
|
-
function bytesToHex(bytes) {
|
|
10
|
-
return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
11
|
-
}
|
|
12
|
-
function hexToBytes(hex) {
|
|
13
|
-
const normalized = hex.trim().replace(/^0x/i, "");
|
|
14
|
-
if (normalized.length % 2 !== 0 || !/^[0-9a-f]*$/i.test(normalized)) {
|
|
15
|
-
throw new Error("Invalid hex string");
|
|
16
|
-
}
|
|
17
|
-
return new Uint8Array(
|
|
18
|
-
normalized.match(/.{2}/g)?.map((byte) => parseInt(byte, 16)) ?? []
|
|
19
|
-
);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
1
|
// src/btc/address.ts
|
|
23
2
|
import { bech32, createBase58check } from "@scure/base";
|
|
24
3
|
import { ripemd160 } from "@noble/hashes/legacy.js";
|
|
@@ -52,6 +31,27 @@ function pubKeyToP2pkh(compressedPubKey) {
|
|
|
52
31
|
return base58check.encode(payload);
|
|
53
32
|
}
|
|
54
33
|
|
|
34
|
+
// src/bytes.ts
|
|
35
|
+
function bytesToBase64(bytes) {
|
|
36
|
+
let binary = "";
|
|
37
|
+
for (const byte of bytes) {
|
|
38
|
+
binary += String.fromCharCode(byte);
|
|
39
|
+
}
|
|
40
|
+
return btoa(binary);
|
|
41
|
+
}
|
|
42
|
+
function bytesToHex(bytes) {
|
|
43
|
+
return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
44
|
+
}
|
|
45
|
+
function hexToBytes(hex) {
|
|
46
|
+
const normalized = hex.trim().replace(/^0x/i, "");
|
|
47
|
+
if (normalized.length % 2 !== 0 || !/^[0-9a-f]*$/i.test(normalized)) {
|
|
48
|
+
throw new Error("Invalid hex string");
|
|
49
|
+
}
|
|
50
|
+
return new Uint8Array(
|
|
51
|
+
normalized.match(/.{2}/g)?.map((byte) => parseInt(byte, 16)) ?? []
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
55
|
// src/btc/deriveAccount.ts
|
|
56
56
|
function firstChild(accountKey) {
|
|
57
57
|
return accountKey.deriveChild(0).deriveChild(0);
|
|
@@ -88,10 +88,11 @@ function deriveBtcAccount(parsed) {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
// src/eth/address.ts
|
|
91
|
+
import { secp256k1 } from "@noble/curves/secp256k1.js";
|
|
91
92
|
import { keccak_256 } from "@noble/hashes/sha3.js";
|
|
92
|
-
import * as secp from "@noble/secp256k1";
|
|
93
93
|
function pubKeyToEthAddress(compressedPubKey) {
|
|
94
|
-
const
|
|
94
|
+
const pubKeyHex = [...compressedPubKey].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
95
|
+
const uncompressed = secp256k1.Point.fromHex(pubKeyHex).toBytes(false);
|
|
95
96
|
const hash = keccak_256(uncompressed.slice(1));
|
|
96
97
|
const hex = [...hash.slice(12)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
97
98
|
return toChecksumAddress(hex);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bytes.ts","../src/btc/address.ts","../src/btc/deriveAccount.ts","../src/eth/address.ts","../src/eth/deriveAccount.ts","../src/parseXpub.ts","../src/parseConnection.ts","../src/cbor.ts","../src/urEncoding.ts","../src/eth/signRequest.ts","../src/eth/signature.ts","../src/btc/signRequest.ts","../src/btc/signature.ts","../src/btc/psbt.ts"],"sourcesContent":["export function bytesToBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\nexport function bytesToHex(bytes: Uint8Array): string {\n return [...bytes].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport function hexToBytes(hex: string): Uint8Array {\n const normalized = hex.trim().replace(/^0x/i, \"\");\n if (normalized.length % 2 !== 0 || !/^[0-9a-f]*$/i.test(normalized)) {\n throw new Error(\"Invalid hex string\");\n }\n\n return new Uint8Array(\n normalized.match(/.{2}/g)?.map((byte) => parseInt(byte, 16)) ?? [],\n );\n}\n","import { bech32, createBase58check } from \"@scure/base\";\nimport { ripemd160 } from \"@noble/hashes/legacy.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n\nexport type BtcScriptType = \"p2wpkh\" | \"p2sh-p2wpkh\" | \"p2pkh\";\n\nconst base58check = createBase58check(sha256);\n\nfunction hash160(bytes: Uint8Array): Uint8Array {\n return ripemd160(sha256(bytes));\n}\n\n/** Native SegWit — P2WPKH, `bc1q...` */\nexport function pubKeyToP2wpkh(compressedPubKey: Uint8Array): string {\n const h = hash160(compressedPubKey);\n const words = bech32.toWords(h);\n return bech32.encode(\"bc\", [0, ...words]);\n}\n\n/** Nested SegWit — P2SH-P2WPKH, `3...` */\nexport function pubKeyToP2shP2wpkh(compressedPubKey: Uint8Array): string {\n const h = hash160(compressedPubKey);\n // redeemScript = OP_0 <20-byte-pubkey-hash>\n const redeemScript = new Uint8Array(22);\n redeemScript[0] = 0x00;\n redeemScript[1] = 0x14;\n redeemScript.set(h, 2);\n const scriptHash = hash160(redeemScript);\n const payload = new Uint8Array(21);\n payload[0] = 0x05; // P2SH version byte\n payload.set(scriptHash, 1);\n return base58check.encode(payload);\n}\n\n/** Legacy — P2PKH, `1...` */\nexport function pubKeyToP2pkh(compressedPubKey: Uint8Array): string {\n const h = hash160(compressedPubKey);\n const payload = new Uint8Array(21);\n payload[0] = 0x00; // mainnet P2PKH version byte\n payload.set(h, 1);\n return base58check.encode(payload);\n}\n","import type { HDKey } from \"@scure/bip32\";\n\nimport { bytesToHex } from \"../bytes.js\";\nimport {\n pubKeyToP2pkh,\n pubKeyToP2shP2wpkh,\n pubKeyToP2wpkh,\n type BtcScriptType,\n} from \"./address.js\";\nimport type { ParsedXpub } from \"../parseXpub.js\";\n\nexport interface DerivedBtcAccount {\n address: string;\n scriptType: BtcScriptType;\n publicKey: string;\n /** source-fingerprint from the scanned xpub — required for signing */\n sourceFingerprint: number | undefined;\n /** device or key name as reported by the hardware wallet, if available */\n device: string | undefined;\n}\n\n// Derive the first external address (index 0) from an account-level xpub.\n// Account-level xpub is at depth 3 (m/purpose'/coin'/account').\n// External chain is child 0, then address index 0.\nfunction firstChild(accountKey: HDKey): HDKey {\n return accountKey.deriveChild(0).deriveChild(0);\n}\n\nfunction scriptTypeFromPurpose(purpose: number | undefined): BtcScriptType | undefined {\n if (purpose === 84) return \"p2wpkh\";\n if (purpose === 49) return \"p2sh-p2wpkh\";\n if (purpose === 44) return \"p2pkh\";\n return undefined;\n}\n\nfunction deriveAddress(pubKey: Uint8Array, scriptType: BtcScriptType): string {\n if (scriptType === \"p2wpkh\") return pubKeyToP2wpkh(pubKey);\n if (scriptType === \"p2sh-p2wpkh\") return pubKeyToP2shP2wpkh(pubKey);\n return pubKeyToP2pkh(pubKey);\n}\n\nexport function deriveBtcAccount(parsed: ParsedXpub[]): DerivedBtcAccount[] {\n const results: DerivedBtcAccount[] = [];\n\n for (const entry of parsed) {\n const { hdKey, purpose, coinType, sourceFingerprint, name } = entry;\n\n // BTC: coin type 0\n if (coinType !== 0) continue;\n\n const scriptType = scriptTypeFromPurpose(purpose);\n if (!scriptType) continue;\n\n const child = firstChild(hdKey);\n if (!child.publicKey) continue;\n\n results.push({\n address: deriveAddress(child.publicKey, scriptType),\n scriptType,\n publicKey: bytesToHex(child.publicKey),\n sourceFingerprint,\n device: name,\n });\n }\n\n return results;\n}\n","import { keccak_256 } from \"@noble/hashes/sha3.js\";\nimport * as secp from \"@noble/secp256k1\";\n\nexport function pubKeyToEthAddress(compressedPubKey: Uint8Array): string {\n const uncompressed = secp.Point.fromBytes(compressedPubKey).toBytes(false);\n const hash = keccak_256(uncompressed.slice(1));\n const hex = [...hash.slice(12)]\n .map((b: number) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n return toChecksumAddress(hex);\n}\n\nfunction toChecksumAddress(hex: string): string {\n const checksumHash = keccak_256(new TextEncoder().encode(hex));\n return (\n \"0x\" +\n [...hex]\n .map((c, i) => {\n if (c >= \"0\" && c <= \"9\") return c;\n const nibble =\n i % 2 === 0\n ? (checksumHash[Math.floor(i / 2)] >> 4) & 0xf\n : checksumHash[Math.floor(i / 2)] & 0xf;\n return nibble >= 8 ? c.toUpperCase() : c.toLowerCase();\n })\n .join(\"\")\n );\n}\n","import type { HDKey } from \"@scure/bip32\";\n\nimport { bytesToHex } from \"../bytes.js\";\nimport { pubKeyToEthAddress } from \"./address.js\";\nimport type { ParsedXpub } from \"../parseXpub.js\";\n\nexport interface DerivedAccount {\n address: string;\n publicKey: string;\n /** source-fingerprint from the scanned xpub — required by Shell for signing */\n sourceFingerprint: number | undefined;\n /** device or key name as reported by the hardware wallet, if available */\n device: string | undefined;\n}\n\n// Derive the first external address (index 0) from an account-level xpub.\n// Account-level xpub is at depth 3 (m/purpose'/coin'/account').\n// External chain is child 0, then address index 0.\nfunction firstChild(accountKey: HDKey): HDKey {\n return accountKey.deriveChild(0).deriveChild(0);\n}\n\nexport function deriveEvmAccount(parsed: ParsedXpub[]): DerivedAccount[] {\n const results: DerivedAccount[] = [];\n for (const entry of parsed) {\n const { hdKey, purpose, coinType, type, sourceFingerprint, name } = entry;\n const isEvm =\n (purpose === 44 && coinType === 60) || (purpose === undefined && type === \"xpub\");\n\n if (!isEvm) continue;\n\n const child = firstChild(hdKey);\n if (!child.publicKey) continue;\n\n results.push({\n address: pubKeyToEthAddress(child.publicKey),\n publicKey: bytesToHex(child.publicKey),\n sourceFingerprint,\n device: name,\n });\n }\n return results;\n}\n","import { HDKey } from \"@scure/bip32\";\nimport { decode as cborDecode, type TagDecoder } from \"cborg\";\n\nimport type { ScannedUR } from \"./types.js\";\n\nexport type XpubType = \"xpub\";\n\nexport interface ParsedXpub {\n hdKey: HDKey;\n type: XpubType;\n /** BIP-44 purpose index: 44 for EVM, 44/49/84 for supported BTC scripts */\n purpose: number | undefined;\n /** BIP-44 coin type: 60 = ETH, 0 = BTC */\n coinType: number | undefined;\n /** source-fingerprint from the origin keypath — required by Shell for signing */\n sourceFingerprint: number | undefined;\n /** device or key name from crypto-hdkey key 9, set by some wallets (e.g. Keystone) */\n name?: string;\n raw: string;\n}\n\ntype CborMap = Map<number, unknown>;\n\nfunction get(m: unknown, k: number): unknown {\n if (m instanceof Map) return (m as Map<number, unknown>).get(k);\n return undefined;\n}\n\nfunction bytesFromCbor(value: unknown): Uint8Array | undefined {\n if (value instanceof Uint8Array) return value;\n\n if (value instanceof Map && value.get(\"type\") === \"Buffer\") {\n const data = value.get(\"data\");\n if (\n Array.isArray(data) &&\n data.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 0xff)\n ) {\n return new Uint8Array(data);\n }\n }\n\n return undefined;\n}\n\nconst passthrough = (v: unknown) => v;\n\nfunction decodeCbor(cbor: Uint8Array): Map<number, unknown> {\n // Connection payloads often wrap the inner hdkey/output structures in semantic CBOR tags\n // (script expressions, crypto-output, vendor-specific wrappers, etc.). For connection\n // parsing we only care about the inner map/bytes shape, so tags are treated as annotations\n // and stripped during decode. Required structure is validated explicitly later.\n const tags = new Proxy([] as TagDecoder[], {\n get(target, property, receiver) {\n if (typeof property === \"string\" && /^\\d+$/.test(property)) {\n return passthrough;\n }\n return Reflect.get(target, property, receiver);\n },\n });\n\n return cborDecode(cbor, {\n useMaps: true,\n tags,\n }) as Map<number, unknown>;\n}\n\nfunction isCborMap(value: unknown): value is CborMap {\n return value instanceof Map;\n}\n\nfunction assertCryptoHdKeyShape(value: unknown): CborMap {\n if (!isCborMap(value)) {\n throw new Error(\"crypto-hdkey entry must be a CBOR map\");\n }\n\n if (!value.has(3) || !value.has(4)) {\n throw new Error(\"crypto-hdkey missing key-data or chain-code\");\n }\n\n return value;\n}\n\nfunction parseCryptoHdKey(map: CborMap, raw: string, fallbackName?: string): ParsedXpub {\n const keyData = bytesFromCbor(get(map, 3));\n const chainCode = bytesFromCbor(get(map, 4));\n\n if (!keyData || !chainCode) {\n throw new Error(\"crypto-hdkey missing key-data or chain-code\");\n }\n\n let purpose: number | undefined;\n let coinType: number | undefined;\n let sourceFingerprint: number | undefined;\n const origin = get(map, 6);\n if (origin) {\n const components = get(origin, 1);\n if (Array.isArray(components)) {\n if (components.length >= 1) purpose = components[0] as number;\n if (components.length >= 3) coinType = components[2] as number;\n }\n sourceFingerprint = get(origin, 2) as number | undefined;\n }\n\n const name = (get(map, 9) as string | undefined) ?? fallbackName;\n\n const hdKey = new HDKey({ publicKey: keyData, chainCode });\n return { hdKey, type: \"xpub\", purpose, coinType, sourceFingerprint, name, raw };\n}\n\nfunction parseScannedUR(scanned: ScannedUR): ParsedXpub | ParsedXpub[] {\n const { type, cbor } = scanned;\n const raw = `ur:${type}`;\n\n if (\n type !== \"crypto-hdkey\" &&\n type !== \"crypto-account\" &&\n type !== \"crypto-multi-accounts\"\n ) {\n throw new Error(`Unsupported UR type: ${type}`);\n }\n\n const map = decodeCbor(cbor);\n\n if (type === \"crypto-hdkey\") {\n return parseCryptoHdKey(assertCryptoHdKeyShape(map), raw);\n }\n\n const accounts = map.get(2) as unknown[] | undefined;\n if (!Array.isArray(accounts) || accounts.length === 0) {\n throw new Error(`${type} contains no keys`);\n }\n const fallbackName =\n type === \"crypto-multi-accounts\" ? (map.get(3) as string | undefined) : undefined;\n return accounts.map((entry) =>\n parseCryptoHdKey(assertCryptoHdKeyShape(entry), raw, fallbackName),\n );\n}\n\nexport function parseXpub(input: ScannedUR | string): ParsedXpub[] {\n if (typeof input !== \"string\") {\n const result = parseScannedUR(input);\n return Array.isArray(result) ? result : [result];\n }\n // Raw base58 xpub string — @scure/bip32 handles decoding directly\n const hdKey = HDKey.fromExtendedKey(input.trim());\n return [\n {\n hdKey,\n type: \"xpub\",\n purpose: undefined,\n coinType: undefined,\n sourceFingerprint: undefined,\n raw: input.trim(),\n },\n ];\n}\n","import { deriveBtcAccount } from \"./btc/deriveAccount.js\";\nimport { deriveEvmAccount } from \"./eth/deriveAccount.js\";\nimport { parseXpub } from \"./parseXpub.js\";\nimport type {\n Account,\n BtcAccount,\n Chain,\n EvmAccount,\n QRKitConfig,\n ScannedUR,\n} from \"./types.js\";\n\nconst ALL_CHAINS: Chain[] = [\"evm\", \"btc\"];\n\n/**\n * Parse a connection QR (crypto-hdkey or crypto-account) and return\n * only the accounts for the chains configured in QRKitConfig.\n *\n * A dApp configured with `chains: [\"evm\"]` will never see BTC accounts,\n * and vice versa. Both chains can be enabled with `chains: [\"evm\", \"btc\"]`.\n * If `chains` is omitted, all supported chains are tried.\n */\nexport function parseConnection(\n scannedUR: ScannedUR,\n config: QRKitConfig = {},\n): Account[] {\n const chains = config.chains ?? ALL_CHAINS;\n const parsed = parseXpub(scannedUR);\n const accounts: Account[] = [];\n\n if (chains.includes(\"evm\")) {\n for (const account of deriveEvmAccount(parsed)) {\n accounts.push({ chain: \"evm\", ...account } satisfies EvmAccount);\n }\n }\n\n if (chains.includes(\"btc\")) {\n for (const account of deriveBtcAccount(parsed)) {\n accounts.push({ chain: \"btc\", ...account } satisfies BtcAccount);\n }\n }\n\n return accounts;\n}\n","// Minimal CBOR encoder.\n// Supports only the types needed for eth-sign-request: uint, bytes, text, array, map (integer keys), bool, tag.\n\nfunction majorType(major: number, n: number): number[] {\n const base = major << 5;\n if (n <= 23) return [base | n];\n if (n <= 0xff) return [base | 0x18, n];\n if (n <= 0xffff) return [base | 0x19, (n >> 8) & 0xff, n & 0xff];\n return [base | 0x1a, (n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff];\n}\n\nexport function encodeItem(value: unknown): number[] {\n if (typeof value === \"boolean\") {\n return [value ? 0xf5 : 0xf4];\n }\n if (typeof value === \"number\") {\n return majorType(0, value);\n }\n if (value instanceof Uint8Array) {\n return [...majorType(2, value.length), ...value];\n }\n if (typeof value === \"string\") {\n const bytes = new TextEncoder().encode(value);\n return [...majorType(3, bytes.length), ...bytes];\n }\n if (Array.isArray(value)) {\n return [...majorType(4, value.length), ...value.flatMap(encodeItem)];\n }\n if (value instanceof CborTag) {\n return [...majorType(6, value.tag), ...encodeItem(value.value)];\n }\n if (value instanceof Map) {\n const entries = [...value.entries()];\n return [\n ...majorType(5, entries.length),\n ...entries.flatMap(([k, v]) => [...encodeItem(k), ...encodeItem(v)]),\n ];\n }\n throw new Error(`Unsupported CBOR value: ${typeof value}`);\n}\n\nexport class CborTag {\n tag: number;\n value: unknown;\n constructor(tag: number, value: unknown) {\n this.tag = tag;\n this.value = value;\n }\n}\n\nexport function encode(value: unknown): Uint8Array {\n return new Uint8Array(encodeItem(value));\n}\n","import { UR, UrFountainEncoder } from \"@qrkit/bc-ur-web\";\n\nexport function encodeURParts(\n cbor: Uint8Array,\n type: string,\n maxFragmentLength = 200,\n): string[] {\n const ur = UR.fromCbor({ type, payload: cbor });\n const encoder = new UrFountainEncoder(ur, maxFragmentLength);\n return encoder.getAllPartsUr().map((part) => part.toString().toUpperCase());\n}\n","import { encode, CborTag } from \"../cbor.js\";\nimport { encodeURParts } from \"../urEncoding.js\";\n\n// ERC-4527 eth-sign-request data types\nexport const EthDataType = {\n /** Legacy transaction (RLP-encoded). Wallet applies EIP-155: v = 35 + 2*chainId + recId */\n LegacyTransaction: 1,\n /** EIP-712 typed data bytes. Wallet hashes internally. */\n TypedData: 2,\n /** Personal message (EIP-191). Wallet prepends \"\\x19Ethereum Signed Message:\\n{len}\". */\n PersonalMessage: 3,\n /** EIP-1559 transaction (RLP-encoded). Wallet uses v = recId. */\n TypedTransaction: 4,\n} as const;\n\nexport type EthDataTypeValue = (typeof EthDataType)[keyof typeof EthDataType];\n\n// CBOR tag for crypto-keypath\nconst TAG_KEYPATH = 304;\n\nfunction randomBytes(n: number): Uint8Array {\n const buf = new Uint8Array(n);\n crypto.getRandomValues(buf);\n return buf;\n}\n\nfunction buildKeypath(\n purpose: number,\n coinType: number,\n sourceFingerprint: number | undefined,\n): CborTag {\n // m/purpose'/coinType'/0'/0/0\n const components = [purpose, true, coinType, true, 0, true, 0, false, 0, false];\n const keypathMap = new Map<number, unknown>([[1, components]]);\n if (sourceFingerprint !== undefined) {\n keypathMap.set(2, sourceFingerprint);\n }\n return new CborTag(TAG_KEYPATH, keypathMap);\n}\n\nexport interface EthSignRequestParams {\n /** Raw sign data. For PersonalMessage, a string is UTF-8 encoded automatically. */\n signData: Uint8Array | string;\n /** ERC-4527 data type. Defaults to PersonalMessage (3). Use EthDataType constants. */\n dataType?: number;\n address: string;\n sourceFingerprint: number | undefined;\n /** Chain ID — required by the wallet for v-value encoding on LegacyTransaction (type 1). */\n chainId?: number;\n origin?: string;\n}\n\nfunction buildEthSignRequestCbor(params: EthSignRequestParams): Uint8Array {\n const {\n signData,\n dataType = EthDataType.PersonalMessage,\n address,\n sourceFingerprint,\n chainId,\n origin = \"qrkit\",\n } = params;\n\n const requestId = randomBytes(16);\n const signBytes =\n typeof signData === \"string\" ? new TextEncoder().encode(signData) : signData;\n const keypath = buildKeypath(44, 60, sourceFingerprint);\n\n const addrHex = address.replace(/^0x/i, \"\");\n const addrBytes = new Uint8Array(addrHex.match(/.{2}/g)!.map((b) => parseInt(b, 16)));\n\n // Keys must be in strictly ascending order for zcbor (Shell firmware decoder).\n const map = new Map<number, unknown>([\n [1, new CborTag(37, requestId)], // request-id: uuid = #6.37(bstr)\n [2, signBytes], // sign-data\n [3, dataType], // data-type\n ]);\n\n if (chainId !== undefined) {\n map.set(4, chainId); // chain-id — must come before key 5\n }\n\n map.set(5, keypath); // derivation-path\n map.set(6, addrBytes); // address\n map.set(7, origin); // origin\n\n return encode(map);\n}\n\nexport function buildEthSignRequestURParts(params: EthSignRequestParams): string[] {\n return encodeURParts(buildEthSignRequestCbor(params), \"eth-sign-request\");\n}\n\nexport function buildEthSignRequestUR(params: EthSignRequestParams): string {\n return encodeURParts(buildEthSignRequestCbor(params), \"eth-sign-request\")[0];\n}\n","import { decode as cborDecode, type TagDecoder } from \"cborg\";\n\nimport { bytesToHex } from \"../bytes.js\";\nimport type { ScannedUR } from \"../types.js\";\n\nexport function parseEthSignature(scanned: ScannedUR): string {\n if (scanned.type !== \"eth-signature\") {\n throw new Error(`Expected eth-signature, got: ${scanned.type}`);\n }\n\n const map = cborDecode(scanned.cbor, {\n useMaps: true,\n tags: Object.assign([] as TagDecoder[], { 37: (v: unknown) => v }),\n }) as Map<number, unknown>;\n\n const sigBytes = map.get(2) as Uint8Array | undefined;\n if (!sigBytes || sigBytes.length < 64) {\n throw new Error(\"Invalid or missing signature bytes\");\n }\n\n return `0x${bytesToHex(sigBytes)}`;\n}\n","import { encode, CborTag } from \"../cbor.js\";\nimport { encodeURParts } from \"../urEncoding.js\";\nimport type { BtcScriptType } from \"./address.js\";\n\nexport const BtcDataType = {\n Message: 1,\n} as const;\n\nexport type BtcDataTypeValue = (typeof BtcDataType)[keyof typeof BtcDataType];\n\nconst TAG_KEYPATH = 304;\nconst PURPOSE_BY_SCRIPT_TYPE = {\n p2wpkh: 84,\n \"p2sh-p2wpkh\": 49,\n p2pkh: 44,\n} as const satisfies Record<BtcScriptType, number>;\n\nfunction randomBytes(n: number): Uint8Array {\n const buf = new Uint8Array(n);\n crypto.getRandomValues(buf);\n return buf;\n}\n\nfunction purposeFromScriptType(scriptType: BtcScriptType): number {\n return PURPOSE_BY_SCRIPT_TYPE[scriptType];\n}\n\nfunction buildKeypath(\n scriptType: BtcScriptType,\n sourceFingerprint: number | undefined,\n): CborTag {\n const purpose = purposeFromScriptType(scriptType);\n // m/purpose'/0'/0'/0/0\n const components = [purpose, true, 0, true, 0, true, 0, false, 0, false];\n const keypathMap = new Map<number, unknown>([[1, components]]);\n if (sourceFingerprint !== undefined) {\n keypathMap.set(2, sourceFingerprint);\n }\n return new CborTag(TAG_KEYPATH, keypathMap);\n}\n\nexport interface BtcSignRequestParams {\n /** Raw message data. Strings are UTF-8 encoded automatically. */\n signData: Uint8Array | string;\n address: string;\n /** BTC script type for choosing m/44', m/49', or m/84'. */\n scriptType: BtcScriptType;\n sourceFingerprint: number | undefined;\n origin?: string;\n}\n\nfunction buildBtcSignRequestCbor(params: BtcSignRequestParams): Uint8Array {\n const { signData, address, scriptType, sourceFingerprint, origin = \"qrkit\" } = params;\n const requestId = randomBytes(16);\n const signBytes =\n typeof signData === \"string\" ? new TextEncoder().encode(signData) : signData;\n const keypath = buildKeypath(scriptType, sourceFingerprint);\n\n return encode(\n new Map<number, unknown>([\n [1, new CborTag(37, requestId)], // request-id: uuid = #6.37(bstr)\n [2, signBytes], // sign-data\n [3, BtcDataType.Message], // data-type\n [4, [keypath]], // btc-derivation-paths\n [5, [address]], // btc-addresses\n [6, origin], // origin\n ]),\n );\n}\n\nexport function buildBtcSignRequestURParts(params: BtcSignRequestParams): string[] {\n return encodeURParts(buildBtcSignRequestCbor(params), \"btc-sign-request\");\n}\n\nexport function buildBtcSignRequestUR(params: BtcSignRequestParams): string {\n return encodeURParts(buildBtcSignRequestCbor(params), \"btc-sign-request\")[0];\n}\n","import { decode as cborDecode, type TagDecoder } from \"cborg\";\n\nimport { bytesToBase64, bytesToHex } from \"../bytes.js\";\nimport type { ScannedUR } from \"../types.js\";\n\nexport interface BtcSignature {\n signature: string;\n publicKey: string;\n requestId: string | undefined;\n}\n\nexport function parseBtcSignature(scanned: ScannedUR): BtcSignature {\n if (scanned.type !== \"btc-signature\") {\n throw new Error(`Expected btc-signature, got: ${scanned.type}`);\n }\n\n const map = cborDecode(scanned.cbor, {\n useMaps: true,\n tags: Object.assign([] as TagDecoder[], { 37: (v: unknown) => v }),\n }) as Map<number, unknown>;\n\n const requestId = map.get(1) as Uint8Array | undefined;\n const sigBytes = map.get(2) as Uint8Array | undefined;\n const publicKeyBytes = map.get(3) as Uint8Array | undefined;\n\n if (!sigBytes || sigBytes.length !== 65) {\n throw new Error(\"Invalid or missing BTC signature bytes\");\n }\n if (!publicKeyBytes || publicKeyBytes.length !== 33) {\n throw new Error(\"Invalid or missing BTC public key bytes\");\n }\n\n return {\n signature: bytesToBase64(sigBytes),\n publicKey: bytesToHex(publicKeyBytes),\n requestId: requestId ? bytesToHex(requestId) : undefined,\n };\n}\n","import { decode as cborDecode } from \"cborg\";\n\nimport { bytesToHex, hexToBytes } from \"../bytes.js\";\nimport { encode } from \"../cbor.js\";\nimport type { ScannedUR } from \"../types.js\";\nimport { encodeURParts } from \"../urEncoding.js\";\n\nexport interface CryptoPsbt {\n psbt: Uint8Array;\n psbtHex: string;\n}\n\nfunction normalizePsbt(psbt: Uint8Array | string): Uint8Array {\n try {\n return typeof psbt === \"string\" ? hexToBytes(psbt) : psbt;\n } catch (error) {\n throw new Error(\"Invalid PSBT hex\", { cause: error });\n }\n}\n\nexport function parseCryptoPsbt(scanned: ScannedUR): CryptoPsbt {\n if (scanned.type !== \"crypto-psbt\") {\n throw new Error(`Expected crypto-psbt, got: ${scanned.type}`);\n }\n\n const psbt = cborDecode(scanned.cbor) as unknown;\n if (!(psbt instanceof Uint8Array)) {\n throw new Error(\"Invalid crypto-psbt payload\");\n }\n\n return {\n psbt,\n psbtHex: bytesToHex(psbt),\n };\n}\n\nexport function buildCryptoPsbtURParts(psbt: Uint8Array | string): string[] {\n return encodeURParts(encode(normalizePsbt(psbt)), \"crypto-psbt\");\n}\n\nexport function buildCryptoPsbtUR(psbt: Uint8Array | string): string {\n return buildCryptoPsbtURParts(psbt)[0];\n}\n"],"mappings":"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","names":["firstChild","cborDecode","cborDecode","TAG_KEYPATH","randomBytes","buildKeypath","cborDecode","cborDecode","cborDecode","cborDecode"]}
|
|
1
|
+
{"version":3,"sources":["../src/btc/address.ts","../src/bytes.ts","../src/btc/deriveAccount.ts","../src/eth/address.ts","../src/eth/deriveAccount.ts","../src/parseXpub.ts","../src/parseConnection.ts","../src/cbor.ts","../src/urEncoding.ts","../src/eth/signRequest.ts","../src/eth/signature.ts","../src/btc/signRequest.ts","../src/btc/signature.ts","../src/btc/psbt.ts"],"sourcesContent":["import { bech32, createBase58check } from \"@scure/base\";\nimport { ripemd160 } from \"@noble/hashes/legacy.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\n\nexport type BtcScriptType = \"p2wpkh\" | \"p2sh-p2wpkh\" | \"p2pkh\";\n\nconst base58check = createBase58check(sha256);\n\nfunction hash160(bytes: Uint8Array): Uint8Array {\n return ripemd160(sha256(bytes));\n}\n\n/** Native SegWit — P2WPKH, `bc1q...` */\nexport function pubKeyToP2wpkh(compressedPubKey: Uint8Array): string {\n const h = hash160(compressedPubKey);\n const words = bech32.toWords(h);\n return bech32.encode(\"bc\", [0, ...words]);\n}\n\n/** Nested SegWit — P2SH-P2WPKH, `3...` */\nexport function pubKeyToP2shP2wpkh(compressedPubKey: Uint8Array): string {\n const h = hash160(compressedPubKey);\n // redeemScript = OP_0 <20-byte-pubkey-hash>\n const redeemScript = new Uint8Array(22);\n redeemScript[0] = 0x00;\n redeemScript[1] = 0x14;\n redeemScript.set(h, 2);\n const scriptHash = hash160(redeemScript);\n const payload = new Uint8Array(21);\n payload[0] = 0x05; // P2SH version byte\n payload.set(scriptHash, 1);\n return base58check.encode(payload);\n}\n\n/** Legacy — P2PKH, `1...` */\nexport function pubKeyToP2pkh(compressedPubKey: Uint8Array): string {\n const h = hash160(compressedPubKey);\n const payload = new Uint8Array(21);\n payload[0] = 0x00; // mainnet P2PKH version byte\n payload.set(h, 1);\n return base58check.encode(payload);\n}\n","export function bytesToBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\nexport function bytesToHex(bytes: Uint8Array): string {\n return [...bytes].map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport function hexToBytes(hex: string): Uint8Array {\n const normalized = hex.trim().replace(/^0x/i, \"\");\n if (normalized.length % 2 !== 0 || !/^[0-9a-f]*$/i.test(normalized)) {\n throw new Error(\"Invalid hex string\");\n }\n\n return new Uint8Array(\n normalized.match(/.{2}/g)?.map((byte) => parseInt(byte, 16)) ?? [],\n );\n}\n","import type { HDKey } from \"@scure/bip32\";\n\nimport {\n pubKeyToP2pkh,\n pubKeyToP2shP2wpkh,\n pubKeyToP2wpkh,\n type BtcScriptType,\n} from \"./address.js\";\n\nimport { bytesToHex } from \"../bytes.js\";\nimport type { ParsedXpub } from \"../parseXpub.js\";\n\nexport interface DerivedBtcAccount {\n address: string;\n scriptType: BtcScriptType;\n publicKey: string;\n /** source-fingerprint from the scanned xpub — required for signing */\n sourceFingerprint: number | undefined;\n /** device or key name as reported by the hardware wallet, if available */\n device: string | undefined;\n}\n\n// Derive the first external address (index 0) from an account-level xpub.\n// Account-level xpub is at depth 3 (m/purpose'/coin'/account').\n// External chain is child 0, then address index 0.\nfunction firstChild(accountKey: HDKey): HDKey {\n return accountKey.deriveChild(0).deriveChild(0);\n}\n\nfunction scriptTypeFromPurpose(purpose: number | undefined): BtcScriptType | undefined {\n if (purpose === 84) return \"p2wpkh\";\n if (purpose === 49) return \"p2sh-p2wpkh\";\n if (purpose === 44) return \"p2pkh\";\n return undefined;\n}\n\nfunction deriveAddress(pubKey: Uint8Array, scriptType: BtcScriptType): string {\n if (scriptType === \"p2wpkh\") return pubKeyToP2wpkh(pubKey);\n if (scriptType === \"p2sh-p2wpkh\") return pubKeyToP2shP2wpkh(pubKey);\n return pubKeyToP2pkh(pubKey);\n}\n\nexport function deriveBtcAccount(parsed: ParsedXpub[]): DerivedBtcAccount[] {\n const results: DerivedBtcAccount[] = [];\n\n for (const entry of parsed) {\n const { hdKey, purpose, coinType, sourceFingerprint, name } = entry;\n\n // BTC: coin type 0\n if (coinType !== 0) continue;\n\n const scriptType = scriptTypeFromPurpose(purpose);\n if (!scriptType) continue;\n\n const child = firstChild(hdKey);\n if (!child.publicKey) continue;\n\n results.push({\n address: deriveAddress(child.publicKey, scriptType),\n scriptType,\n publicKey: bytesToHex(child.publicKey),\n sourceFingerprint,\n device: name,\n });\n }\n\n return results;\n}\n","import { secp256k1 } from \"@noble/curves/secp256k1.js\";\nimport { keccak_256 } from \"@noble/hashes/sha3.js\";\n\nexport function pubKeyToEthAddress(compressedPubKey: Uint8Array): string {\n const pubKeyHex = [...compressedPubKey]\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n const uncompressed = secp256k1.Point.fromHex(pubKeyHex).toBytes(false);\n const hash = keccak_256(uncompressed.slice(1));\n const hex = [...hash.slice(12)]\n .map((b: number) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n return toChecksumAddress(hex);\n}\n\nfunction toChecksumAddress(hex: string): string {\n const checksumHash = keccak_256(new TextEncoder().encode(hex));\n return (\n \"0x\" +\n [...hex]\n .map((c, i) => {\n if (c >= \"0\" && c <= \"9\") return c;\n const nibble =\n i % 2 === 0\n ? (checksumHash[Math.floor(i / 2)] >> 4) & 0xf\n : checksumHash[Math.floor(i / 2)] & 0xf;\n return nibble >= 8 ? c.toUpperCase() : c.toLowerCase();\n })\n .join(\"\")\n );\n}\n","import type { HDKey } from \"@scure/bip32\";\n\nimport { bytesToHex } from \"../bytes.js\";\nimport { pubKeyToEthAddress } from \"./address.js\";\nimport type { ParsedXpub } from \"../parseXpub.js\";\n\nexport interface DerivedAccount {\n address: string;\n publicKey: string;\n /** source-fingerprint from the scanned xpub — required by Shell for signing */\n sourceFingerprint: number | undefined;\n /** device or key name as reported by the hardware wallet, if available */\n device: string | undefined;\n}\n\n// Derive the first external address (index 0) from an account-level xpub.\n// Account-level xpub is at depth 3 (m/purpose'/coin'/account').\n// External chain is child 0, then address index 0.\nfunction firstChild(accountKey: HDKey): HDKey {\n return accountKey.deriveChild(0).deriveChild(0);\n}\n\nexport function deriveEvmAccount(parsed: ParsedXpub[]): DerivedAccount[] {\n const results: DerivedAccount[] = [];\n for (const entry of parsed) {\n const { hdKey, purpose, coinType, type, sourceFingerprint, name } = entry;\n const isEvm =\n (purpose === 44 && coinType === 60) || (purpose === undefined && type === \"xpub\");\n\n if (!isEvm) continue;\n\n const child = firstChild(hdKey);\n if (!child.publicKey) continue;\n\n results.push({\n address: pubKeyToEthAddress(child.publicKey),\n publicKey: bytesToHex(child.publicKey),\n sourceFingerprint,\n device: name,\n });\n }\n return results;\n}\n","import { HDKey } from \"@scure/bip32\";\nimport { decode as cborDecode, type TagDecoder } from \"cborg\";\n\nimport type { ScannedUR } from \"./types.js\";\n\nexport type XpubType = \"xpub\";\n\nexport interface ParsedXpub {\n hdKey: HDKey;\n type: XpubType;\n /** BIP-44 purpose index: 44 for EVM, 44/49/84 for supported BTC scripts */\n purpose: number | undefined;\n /** BIP-44 coin type: 60 = ETH, 0 = BTC */\n coinType: number | undefined;\n /** source-fingerprint from the origin keypath — required by Shell for signing */\n sourceFingerprint: number | undefined;\n /** device or key name from crypto-hdkey key 9, set by some wallets (e.g. Keystone) */\n name?: string;\n raw: string;\n}\n\ntype CborMap = Map<number, unknown>;\n\nfunction get(m: unknown, k: number): unknown {\n if (m instanceof Map) return (m as Map<number, unknown>).get(k);\n return undefined;\n}\n\nfunction bytesFromCbor(value: unknown): Uint8Array | undefined {\n if (value instanceof Uint8Array) return value;\n\n if (value instanceof Map && value.get(\"type\") === \"Buffer\") {\n const data = value.get(\"data\");\n if (\n Array.isArray(data) &&\n data.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 0xff)\n ) {\n return new Uint8Array(data);\n }\n }\n\n return undefined;\n}\n\nconst passthrough = (v: unknown) => v;\n\nfunction decodeCbor(cbor: Uint8Array): Map<number, unknown> {\n // Connection payloads often wrap the inner hdkey/output structures in semantic CBOR tags\n // (script expressions, crypto-output, vendor-specific wrappers, etc.). For connection\n // parsing we only care about the inner map/bytes shape, so tags are treated as annotations\n // and stripped during decode. Required structure is validated explicitly later.\n const tags = new Proxy([] as TagDecoder[], {\n get(target, property, receiver) {\n if (typeof property === \"string\" && /^\\d+$/.test(property)) {\n return passthrough;\n }\n return Reflect.get(target, property, receiver);\n },\n });\n\n return cborDecode(cbor, {\n useMaps: true,\n tags,\n }) as Map<number, unknown>;\n}\n\nfunction isCborMap(value: unknown): value is CborMap {\n return value instanceof Map;\n}\n\nfunction assertCryptoHdKeyShape(value: unknown): CborMap {\n if (!isCborMap(value)) {\n throw new Error(\"crypto-hdkey entry must be a CBOR map\");\n }\n\n if (!value.has(3) || !value.has(4)) {\n throw new Error(\"crypto-hdkey missing key-data or chain-code\");\n }\n\n return value;\n}\n\nfunction parseCryptoHdKey(map: CborMap, raw: string, fallbackName?: string): ParsedXpub {\n const keyData = bytesFromCbor(get(map, 3));\n const chainCode = bytesFromCbor(get(map, 4));\n\n if (!keyData || !chainCode) {\n throw new Error(\"crypto-hdkey missing key-data or chain-code\");\n }\n\n let purpose: number | undefined;\n let coinType: number | undefined;\n let sourceFingerprint: number | undefined;\n const origin = get(map, 6);\n if (origin) {\n const components = get(origin, 1);\n if (Array.isArray(components)) {\n if (components.length >= 1) purpose = components[0] as number;\n if (components.length >= 3) coinType = components[2] as number;\n }\n sourceFingerprint = get(origin, 2) as number | undefined;\n }\n\n const name = (get(map, 9) as string | undefined) ?? fallbackName;\n\n const hdKey = new HDKey({ publicKey: keyData, chainCode });\n return { hdKey, type: \"xpub\", purpose, coinType, sourceFingerprint, name, raw };\n}\n\nfunction parseScannedUR(scanned: ScannedUR): ParsedXpub | ParsedXpub[] {\n const { type, cbor } = scanned;\n const raw = `ur:${type}`;\n\n if (\n type !== \"crypto-hdkey\" &&\n type !== \"crypto-account\" &&\n type !== \"crypto-multi-accounts\"\n ) {\n throw new Error(`Unsupported UR type: ${type}`);\n }\n\n const map = decodeCbor(cbor);\n\n if (type === \"crypto-hdkey\") {\n return parseCryptoHdKey(assertCryptoHdKeyShape(map), raw);\n }\n\n const accounts = map.get(2) as unknown[] | undefined;\n if (!Array.isArray(accounts) || accounts.length === 0) {\n throw new Error(`${type} contains no keys`);\n }\n const fallbackName =\n type === \"crypto-multi-accounts\" ? (map.get(3) as string | undefined) : undefined;\n return accounts.map((entry) =>\n parseCryptoHdKey(assertCryptoHdKeyShape(entry), raw, fallbackName),\n );\n}\n\nexport function parseXpub(input: ScannedUR | string): ParsedXpub[] {\n if (typeof input !== \"string\") {\n const result = parseScannedUR(input);\n return Array.isArray(result) ? result : [result];\n }\n // Raw base58 xpub string — @scure/bip32 handles decoding directly\n const hdKey = HDKey.fromExtendedKey(input.trim());\n return [\n {\n hdKey,\n type: \"xpub\",\n purpose: undefined,\n coinType: undefined,\n sourceFingerprint: undefined,\n raw: input.trim(),\n },\n ];\n}\n","import { deriveBtcAccount } from \"./btc/deriveAccount.js\";\nimport { deriveEvmAccount } from \"./eth/deriveAccount.js\";\nimport { parseXpub } from \"./parseXpub.js\";\nimport type {\n Account,\n BtcAccount,\n Chain,\n EvmAccount,\n QRKitConfig,\n ScannedUR,\n} from \"./types.js\";\n\nconst ALL_CHAINS: Chain[] = [\"evm\", \"btc\"];\n\n/**\n * Parse a connection QR (crypto-hdkey or crypto-account) and return\n * only the accounts for the chains configured in QRKitConfig.\n *\n * A dApp configured with `chains: [\"evm\"]` will never see BTC accounts,\n * and vice versa. Both chains can be enabled with `chains: [\"evm\", \"btc\"]`.\n * If `chains` is omitted, all supported chains are tried.\n */\nexport function parseConnection(\n scannedUR: ScannedUR,\n config: QRKitConfig = {},\n): Account[] {\n const chains = config.chains ?? ALL_CHAINS;\n const parsed = parseXpub(scannedUR);\n const accounts: Account[] = [];\n\n if (chains.includes(\"evm\")) {\n for (const account of deriveEvmAccount(parsed)) {\n accounts.push({ chain: \"evm\", ...account } satisfies EvmAccount);\n }\n }\n\n if (chains.includes(\"btc\")) {\n for (const account of deriveBtcAccount(parsed)) {\n accounts.push({ chain: \"btc\", ...account } satisfies BtcAccount);\n }\n }\n\n return accounts;\n}\n","// Minimal CBOR encoder.\n// Supports only the types needed for eth-sign-request: uint, bytes, text, array, map (integer keys), bool, tag.\n\nfunction majorType(major: number, n: number): number[] {\n const base = major << 5;\n if (n <= 23) return [base | n];\n if (n <= 0xff) return [base | 0x18, n];\n if (n <= 0xffff) return [base | 0x19, (n >> 8) & 0xff, n & 0xff];\n return [base | 0x1a, (n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff];\n}\n\nexport function encodeItem(value: unknown): number[] {\n if (typeof value === \"boolean\") {\n return [value ? 0xf5 : 0xf4];\n }\n if (typeof value === \"number\") {\n return majorType(0, value);\n }\n if (value instanceof Uint8Array) {\n return [...majorType(2, value.length), ...value];\n }\n if (typeof value === \"string\") {\n const bytes = new TextEncoder().encode(value);\n return [...majorType(3, bytes.length), ...bytes];\n }\n if (Array.isArray(value)) {\n return [...majorType(4, value.length), ...value.flatMap(encodeItem)];\n }\n if (value instanceof CborTag) {\n return [...majorType(6, value.tag), ...encodeItem(value.value)];\n }\n if (value instanceof Map) {\n const entries = [...value.entries()];\n return [\n ...majorType(5, entries.length),\n ...entries.flatMap(([k, v]) => [...encodeItem(k), ...encodeItem(v)]),\n ];\n }\n throw new Error(`Unsupported CBOR value: ${typeof value}`);\n}\n\nexport class CborTag {\n tag: number;\n value: unknown;\n constructor(tag: number, value: unknown) {\n this.tag = tag;\n this.value = value;\n }\n}\n\nexport function encode(value: unknown): Uint8Array {\n return new Uint8Array(encodeItem(value));\n}\n","import { UR, UrFountainEncoder } from \"@qrkit/bc-ur-web\";\n\nexport function encodeURParts(\n cbor: Uint8Array,\n type: string,\n maxFragmentLength = 200,\n): string[] {\n const ur = UR.fromCbor({ type, payload: cbor });\n const encoder = new UrFountainEncoder(ur, maxFragmentLength);\n return encoder.getAllPartsUr().map((part) => part.toString().toUpperCase());\n}\n","import { encode, CborTag } from \"../cbor.js\";\nimport { encodeURParts } from \"../urEncoding.js\";\n\n// ERC-4527 eth-sign-request data types\nexport const EthDataType = {\n /** Legacy transaction (RLP-encoded). Wallet applies EIP-155: v = 35 + 2*chainId + recId */\n LegacyTransaction: 1,\n /** EIP-712 typed data bytes. Wallet hashes internally. */\n TypedData: 2,\n /** Personal message (EIP-191). Wallet prepends \"\\x19Ethereum Signed Message:\\n{len}\". */\n PersonalMessage: 3,\n /** EIP-1559 transaction (RLP-encoded). Wallet uses v = recId. */\n TypedTransaction: 4,\n} as const;\n\nexport type EthDataTypeValue = (typeof EthDataType)[keyof typeof EthDataType];\n\n// CBOR tag for crypto-keypath\nconst TAG_KEYPATH = 304;\n\nfunction randomBytes(n: number): Uint8Array {\n const buf = new Uint8Array(n);\n crypto.getRandomValues(buf);\n return buf;\n}\n\nfunction buildKeypath(\n purpose: number,\n coinType: number,\n sourceFingerprint: number | undefined,\n): CborTag {\n // m/purpose'/coinType'/0'/0/0\n const components = [purpose, true, coinType, true, 0, true, 0, false, 0, false];\n const keypathMap = new Map<number, unknown>([[1, components]]);\n if (sourceFingerprint !== undefined) {\n keypathMap.set(2, sourceFingerprint);\n }\n return new CborTag(TAG_KEYPATH, keypathMap);\n}\n\nexport interface EthSignRequestParams {\n /** Raw sign data. For PersonalMessage, a string is UTF-8 encoded automatically. */\n signData: Uint8Array | string;\n /** ERC-4527 data type. Defaults to PersonalMessage (3). Use EthDataType constants. */\n dataType?: number;\n address: string;\n sourceFingerprint: number | undefined;\n /** Chain ID — required by the wallet for v-value encoding on LegacyTransaction (type 1). */\n chainId?: number;\n origin?: string;\n}\n\nfunction buildEthSignRequestCbor(params: EthSignRequestParams): Uint8Array {\n const {\n signData,\n dataType = EthDataType.PersonalMessage,\n address,\n sourceFingerprint,\n chainId,\n origin = \"qrkit\",\n } = params;\n\n const requestId = randomBytes(16);\n const signBytes =\n typeof signData === \"string\" ? new TextEncoder().encode(signData) : signData;\n const keypath = buildKeypath(44, 60, sourceFingerprint);\n\n const addrHex = address.replace(/^0x/i, \"\");\n const addrBytes = new Uint8Array(addrHex.match(/.{2}/g)!.map((b) => parseInt(b, 16)));\n\n // Keys must be in strictly ascending order for zcbor (Shell firmware decoder).\n const map = new Map<number, unknown>([\n [1, new CborTag(37, requestId)], // request-id: uuid = #6.37(bstr)\n [2, signBytes], // sign-data\n [3, dataType], // data-type\n ]);\n\n if (chainId !== undefined) {\n map.set(4, chainId); // chain-id — must come before key 5\n }\n\n map.set(5, keypath); // derivation-path\n map.set(6, addrBytes); // address\n map.set(7, origin); // origin\n\n return encode(map);\n}\n\nexport function buildEthSignRequestURParts(params: EthSignRequestParams): string[] {\n return encodeURParts(buildEthSignRequestCbor(params), \"eth-sign-request\");\n}\n\nexport function buildEthSignRequestUR(params: EthSignRequestParams): string {\n return encodeURParts(buildEthSignRequestCbor(params), \"eth-sign-request\")[0];\n}\n","import { decode as cborDecode, type TagDecoder } from \"cborg\";\n\nimport { bytesToHex } from \"../bytes.js\";\nimport type { ScannedUR } from \"../types.js\";\n\nexport function parseEthSignature(scanned: ScannedUR): string {\n if (scanned.type !== \"eth-signature\") {\n throw new Error(`Expected eth-signature, got: ${scanned.type}`);\n }\n\n const map = cborDecode(scanned.cbor, {\n useMaps: true,\n tags: Object.assign([] as TagDecoder[], { 37: (v: unknown) => v }),\n }) as Map<number, unknown>;\n\n const sigBytes = map.get(2) as Uint8Array | undefined;\n if (!sigBytes || sigBytes.length < 64) {\n throw new Error(\"Invalid or missing signature bytes\");\n }\n\n return `0x${bytesToHex(sigBytes)}`;\n}\n","import { encode, CborTag } from \"../cbor.js\";\nimport { encodeURParts } from \"../urEncoding.js\";\nimport type { BtcScriptType } from \"./address.js\";\n\nexport const BtcDataType = {\n Message: 1,\n} as const;\n\nexport type BtcDataTypeValue = (typeof BtcDataType)[keyof typeof BtcDataType];\n\nconst TAG_KEYPATH = 304;\nconst PURPOSE_BY_SCRIPT_TYPE = {\n p2wpkh: 84,\n \"p2sh-p2wpkh\": 49,\n p2pkh: 44,\n} as const satisfies Record<BtcScriptType, number>;\n\nfunction randomBytes(n: number): Uint8Array {\n const buf = new Uint8Array(n);\n crypto.getRandomValues(buf);\n return buf;\n}\n\nfunction purposeFromScriptType(scriptType: BtcScriptType): number {\n return PURPOSE_BY_SCRIPT_TYPE[scriptType];\n}\n\nfunction buildKeypath(\n scriptType: BtcScriptType,\n sourceFingerprint: number | undefined,\n): CborTag {\n const purpose = purposeFromScriptType(scriptType);\n // m/purpose'/0'/0'/0/0\n const components = [purpose, true, 0, true, 0, true, 0, false, 0, false];\n const keypathMap = new Map<number, unknown>([[1, components]]);\n if (sourceFingerprint !== undefined) {\n keypathMap.set(2, sourceFingerprint);\n }\n return new CborTag(TAG_KEYPATH, keypathMap);\n}\n\nexport interface BtcSignRequestParams {\n /** Raw message data. Strings are UTF-8 encoded automatically. */\n signData: Uint8Array | string;\n address: string;\n /** BTC script type for choosing m/44', m/49', or m/84'. */\n scriptType: BtcScriptType;\n sourceFingerprint: number | undefined;\n origin?: string;\n}\n\nfunction buildBtcSignRequestCbor(params: BtcSignRequestParams): Uint8Array {\n const { signData, address, scriptType, sourceFingerprint, origin = \"qrkit\" } = params;\n const requestId = randomBytes(16);\n const signBytes =\n typeof signData === \"string\" ? new TextEncoder().encode(signData) : signData;\n const keypath = buildKeypath(scriptType, sourceFingerprint);\n\n return encode(\n new Map<number, unknown>([\n [1, new CborTag(37, requestId)], // request-id: uuid = #6.37(bstr)\n [2, signBytes], // sign-data\n [3, BtcDataType.Message], // data-type\n [4, [keypath]], // btc-derivation-paths\n [5, [address]], // btc-addresses\n [6, origin], // origin\n ]),\n );\n}\n\nexport function buildBtcSignRequestURParts(params: BtcSignRequestParams): string[] {\n return encodeURParts(buildBtcSignRequestCbor(params), \"btc-sign-request\");\n}\n\nexport function buildBtcSignRequestUR(params: BtcSignRequestParams): string {\n return encodeURParts(buildBtcSignRequestCbor(params), \"btc-sign-request\")[0];\n}\n","import { decode as cborDecode, type TagDecoder } from \"cborg\";\n\nimport { bytesToBase64, bytesToHex } from \"../bytes.js\";\nimport type { ScannedUR } from \"../types.js\";\n\nexport interface BtcSignature {\n signature: string;\n publicKey: string;\n requestId: string | undefined;\n}\n\nexport function parseBtcSignature(scanned: ScannedUR): BtcSignature {\n if (scanned.type !== \"btc-signature\") {\n throw new Error(`Expected btc-signature, got: ${scanned.type}`);\n }\n\n const map = cborDecode(scanned.cbor, {\n useMaps: true,\n tags: Object.assign([] as TagDecoder[], { 37: (v: unknown) => v }),\n }) as Map<number, unknown>;\n\n const requestId = map.get(1) as Uint8Array | undefined;\n const sigBytes = map.get(2) as Uint8Array | undefined;\n const publicKeyBytes = map.get(3) as Uint8Array | undefined;\n\n if (!sigBytes || sigBytes.length !== 65) {\n throw new Error(\"Invalid or missing BTC signature bytes\");\n }\n if (!publicKeyBytes || publicKeyBytes.length !== 33) {\n throw new Error(\"Invalid or missing BTC public key bytes\");\n }\n\n return {\n signature: bytesToBase64(sigBytes),\n publicKey: bytesToHex(publicKeyBytes),\n requestId: requestId ? bytesToHex(requestId) : undefined,\n };\n}\n","import { decode as cborDecode } from \"cborg\";\n\nimport { bytesToHex, hexToBytes } from \"../bytes.js\";\nimport { encode } from \"../cbor.js\";\nimport type { ScannedUR } from \"../types.js\";\nimport { encodeURParts } from \"../urEncoding.js\";\n\nexport interface CryptoPsbt {\n psbt: Uint8Array;\n psbtHex: string;\n}\n\nfunction normalizePsbt(psbt: Uint8Array | string): Uint8Array {\n try {\n return typeof psbt === \"string\" ? hexToBytes(psbt) : psbt;\n } catch (error) {\n throw new Error(\"Invalid PSBT hex\", { cause: error });\n }\n}\n\nexport function parseCryptoPsbt(scanned: ScannedUR): CryptoPsbt {\n if (scanned.type !== \"crypto-psbt\") {\n throw new Error(`Expected crypto-psbt, got: ${scanned.type}`);\n }\n\n const psbt = cborDecode(scanned.cbor) as unknown;\n if (!(psbt instanceof Uint8Array)) {\n throw new Error(\"Invalid crypto-psbt payload\");\n }\n\n return {\n psbt,\n psbtHex: bytesToHex(psbt),\n };\n}\n\nexport function buildCryptoPsbtURParts(psbt: Uint8Array | string): string[] {\n return encodeURParts(encode(normalizePsbt(psbt)), \"crypto-psbt\");\n}\n\nexport function buildCryptoPsbtUR(psbt: Uint8Array | string): string {\n return buildCryptoPsbtURParts(psbt)[0];\n}\n"],"mappings":"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","names":["firstChild","cborDecode","cborDecode","TAG_KEYPATH","randomBytes","buildKeypath","cborDecode","cborDecode","cborDecode","cborDecode"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qrkit/core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Protocol core for QR-based airgapped wallet flows — UR decoding, xpub parsing, address derivation, sign request and signature handling.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
"dist"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
+
"@noble/curves": "^2.0.1",
|
|
21
22
|
"@noble/hashes": "^2.0.1",
|
|
22
|
-
"@noble/secp256k1": "^3.0.0",
|
|
23
23
|
"@qrkit/bc-ur-web": "^2.0.1",
|
|
24
24
|
"@scure/base": "^2.0.0",
|
|
25
25
|
"@scure/bip32": "^2.0.1",
|