@secondlayer/stacks 0.2.1 → 0.2.2
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/shared/{stacks-9mdk86wp.js → stacks-6m1z4j07.js} +14 -10
- package/dist/shared/stacks-6m1z4j07.js.map +10 -0
- package/dist/shared/{stacks-wrb1es85.js → stacks-96gaxfcf.js} +5 -5
- package/dist/shared/{stacks-v3zy6zds.cjs → stacks-etf219gs.cjs} +11 -7
- package/dist/shared/stacks-etf219gs.cjs.map +10 -0
- package/dist/shared/{stacks-yfveb68e.js → stacks-je937aas.js} +3 -3
- package/dist/shared/{stacks-qyt8m5v0.js → stacks-jrnmh4kc.js} +3 -3
- package/dist/shared/{stacks-vd9jcp0b.js → stacks-k9p8m3wf.js} +7 -7
- package/dist/shared/{stacks-9avax1yf.js → stacks-p93g814f.js} +3 -3
- package/dist/shared/{stacks-qcx67vqa.js → stacks-q79dx28x.js} +3 -3
- package/dist/shared/{stacks-r1t6g3c3.cjs → stacks-ra02bpny.cjs} +8 -3
- package/dist/shared/{stacks-r1t6g3c3.cjs.map → stacks-ra02bpny.cjs.map} +3 -3
- package/dist/shared/{stacks-fedzr2ka.js → stacks-rg1g0fja.js} +3 -3
- package/dist/shared/{stacks-bycy6t9k.js → stacks-rwfgts3s.js} +2 -2
- package/dist/shared/{stacks-gjvbq6w7.js → stacks-s10yb9gz.js} +2 -2
- package/dist/shared/{stacks-nqytwfcc.js → stacks-s7z5q8be.js} +8 -3
- package/dist/shared/{stacks-nqytwfcc.js.map → stacks-s7z5q8be.js.map} +3 -3
- package/dist/shared/{stacks-vbke9mqw.cjs → stacks-v6ja2eh7.cjs} +16 -6
- package/dist/shared/{stacks-vbke9mqw.cjs.map → stacks-v6ja2eh7.cjs.map} +4 -4
- package/dist/shared/{stacks-vyb9rx8q.js → stacks-xp9n3r0t.js} +20 -10
- package/dist/shared/{stacks-vyb9rx8q.js.map → stacks-xp9n3r0t.js.map} +4 -4
- package/dist/src/accounts/index.js +2 -2
- package/dist/src/actions/index.d.cts +7 -0
- package/dist/src/actions/index.d.ts +7 -0
- package/dist/src/actions/index.js +10 -10
- package/dist/src/bns/index.js +10 -10
- package/dist/src/clarity/index.js +5 -5
- package/dist/src/connect/index.cjs.map +2 -2
- package/dist/src/connect/index.js.map +2 -2
- package/dist/src/connect/walletconnect/index.cjs.map +1 -1
- package/dist/src/connect/walletconnect/index.js.map +1 -1
- package/dist/src/index.d.cts +7 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.js +8 -8
- package/dist/src/postconditions/index.js +3 -3
- package/dist/src/pox/index.js +9 -9
- package/dist/src/stackingdao/index.js +9 -9
- package/dist/src/transactions/index.d.cts +7 -0
- package/dist/src/transactions/index.d.ts +7 -0
- package/dist/src/transactions/index.js +6 -6
- package/dist/src/utils/index.js +3 -3
- package/package.json +1 -1
- package/dist/shared/stacks-9mdk86wp.js.map +0 -10
- package/dist/shared/stacks-v3zy6zds.cjs.map +0 -10
- /package/dist/shared/{stacks-wrb1es85.js.map → stacks-96gaxfcf.js.map} +0 -0
- /package/dist/shared/{stacks-yfveb68e.js.map → stacks-je937aas.js.map} +0 -0
- /package/dist/shared/{stacks-qyt8m5v0.js.map → stacks-jrnmh4kc.js.map} +0 -0
- /package/dist/shared/{stacks-vd9jcp0b.js.map → stacks-k9p8m3wf.js.map} +0 -0
- /package/dist/shared/{stacks-9avax1yf.js.map → stacks-p93g814f.js.map} +0 -0
- /package/dist/shared/{stacks-qcx67vqa.js.map → stacks-q79dx28x.js.map} +0 -0
- /package/dist/shared/{stacks-fedzr2ka.js.map → stacks-rg1g0fja.js.map} +0 -0
- /package/dist/shared/{stacks-bycy6t9k.js.map → stacks-rwfgts3s.js.map} +0 -0
- /package/dist/shared/{stacks-gjvbq6w7.js.map → stacks-s10yb9gz.js.map} +0 -0
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
"import { BaseError } from \"../errors/base.ts\";\n\nexport class ConnectError extends BaseError {\n override name = \"ConnectError\";\n}\n\nexport enum JsonRpcErrorCode {\n ParseError = -32700,\n InvalidRequest = -32600,\n MethodNotFound = -32601,\n InvalidParams = -32602,\n InternalError = -32603,\n UserRejection = -31001,\n}\n\nexport class JsonRpcError extends ConnectError {\n override name = \"JsonRpcError\";\n code: number;\n data?: unknown;\n\n constructor(\n message: string,\n code: number,\n options?: { data?: unknown; cause?: Error }\n ) {\n const details =\n options?.data !== undefined\n ? typeof options.data === \"string\"\n ? options.data\n : JSON.stringify(options.data)\n : undefined;\n super(message, { cause: options?.cause, details });\n this.code = code;\n this.data = options?.data;\n }\n}\n",
|
|
7
7
|
"import type { WalletProvider } from \"./types.ts\";\nimport { ConnectError } from \"./errors.ts\";\n\ndeclare const window:\n | {\n StacksProvider?: WalletProvider;\n LeatherProvider?: WalletProvider;\n XverseProvider?: WalletProvider;\n HiroWalletProvider?: WalletProvider;\n }\n | undefined;\n\nlet customProvider: WalletProvider | null = null;\n\n/** Set a custom provider (e.g. WalletConnectProvider). Pass null to clear. */\nexport function setProvider(provider: WalletProvider | null): void {\n customProvider = provider;\n}\n\nexport function getProvider(): WalletProvider {\n if (customProvider) return customProvider;\n\n if (typeof window === \"undefined\") {\n throw new ConnectError(\"No Stacks wallet found\");\n }\n\n const provider =\n window.StacksProvider ??\n window.LeatherProvider ??\n window.XverseProvider ??\n window.HiroWalletProvider;\n\n if (!provider) throw new ConnectError(\"No Stacks wallet found\");\n return provider;\n}\n\nexport function isWalletInstalled(): boolean {\n return (\n typeof window !== \"undefined\" &&\n !!(\n window.StacksProvider ||\n window.LeatherProvider ||\n window.XverseProvider ||\n window.HiroWalletProvider\n )\n );\n}\n",
|
|
8
8
|
"import type { AddressEntry } from \"./types.ts\";\n\nconst STORAGE_KEY = \"@secondlayer/connect\";\n\nexport interface StorageData {\n addresses: {\n stx: AddressEntry[];\n btc: AddressEntry[];\n };\n version: string;\n updatedAt: number;\n}\n\nfunction toHex(str: string): string {\n return Array.from(new TextEncoder().encode(str))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\nfunction fromHex(hex: string): string {\n const bytes = new Uint8Array(\n hex.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))\n );\n return new TextDecoder().decode(bytes);\n}\n\ninterface SimpleStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n}\n\ndeclare const localStorage: SimpleStorage | undefined;\n\nfunction getLocalStorage(): SimpleStorage | undefined {\n return typeof localStorage !== \"undefined\" ? localStorage : undefined;\n}\n\nexport function getStorageData(): StorageData | null {\n try {\n const raw = getLocalStorage()?.getItem(STORAGE_KEY);\n if (!raw) return null;\n return JSON.parse(fromHex(raw)) as StorageData;\n } catch {\n return null;\n }\n}\n\nexport function setStorageData(data: StorageData): void {\n const encoded = toHex(JSON.stringify(data));\n getLocalStorage()?.setItem(STORAGE_KEY, encoded);\n}\n\nexport function clearStorage(): void {\n getLocalStorage()?.removeItem(STORAGE_KEY);\n}\n\nexport function cacheAddresses(addresses: AddressEntry[]): void {\n const stx = addresses.filter(\n (a) => a.address.startsWith(\"SP\") || a.address.startsWith(\"ST\")\n );\n const btc = addresses.filter(\n (a) => !a.address.startsWith(\"SP\") && !a.address.startsWith(\"ST\")\n );\n\n setStorageData({\n addresses: { stx, btc },\n version: \"0.0.1\",\n updatedAt: Date.now(),\n });\n}\n",
|
|
9
|
-
"const hexes = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, \"0\"));\n\nexport function bytesToHex(bytes: Uint8Array): string {\n let hex = \"\";\n for (const b of bytes) {\n hex += hexes[b];\n }\n return hex;\n}\n\nexport function hexToBytes(hex: string): Uint8Array {\n hex = without0x(hex);\n if (hex.length % 2) hex = `0${hex}`;\n\n const array = new Uint8Array(hex.length / 2);\n for (let i = 0; i < array.length; i++) {\n const j = i * 2;\n const byte = Number.parseInt(hex.slice(j, j + 2), 16);\n if (Number.isNaN(byte) || byte < 0) throw new Error(\"Invalid byte sequence\");\n array[i] = byte;\n }\n return array;\n}\n\nexport function with0x(value: string): string {\n return /^0x/i.test(value) ? value : `0x${value}`;\n}\n\nexport function without0x(value: string): string {\n return /^0x/i.test(value) ? value.slice(2) : value;\n}\n\nexport function utf8ToBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\nexport function bytesToUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\nexport function asciiToBytes(str: string): Uint8Array {\n const bytes = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n bytes[i] = str.charCodeAt(i) & 0xff;\n }\n return bytes;\n}\n\nexport function bytesToAscii(bytes: Uint8Array): string {\n return String.fromCharCode(...bytes);\n}\n\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n if (arrays.length === 1) return arrays[0]!;\n const length = arrays.reduce((a, arr) => a + arr.length, 0);\n const result = new Uint8Array(length);\n let pad = 0;\n for (const arr of arrays) {\n result.set(arr, pad);\n pad += arr.length;\n }\n return result;\n}\n\nexport type IntegerType = number | string | bigint | Uint8Array;\n\nexport function intToBigInt(value: IntegerType): bigint {\n if (typeof value === \"bigint\") return value;\n if (typeof value === \"string\") return BigInt(value);\n if (typeof value === \"number\") {\n if (!Number.isInteger(value))\n throw new RangeError(\"Values of type 'number' must be an integer.\");\n if (value > Number.MAX_SAFE_INTEGER)\n throw new RangeError(\n `Values of type 'number' must be <= ${Number.MAX_SAFE_INTEGER}. Use BigInt instead.`\n );\n return BigInt(value);\n }\n if (value instanceof Uint8Array) return BigInt(`0x${bytesToHex(value)}`);\n throw new TypeError(\"Must be a number, bigint, string, or Uint8Array.\");\n}\n\nexport function intToBytes(value: IntegerType, byteLength: number): Uint8Array {\n return bigIntToBytes(intToBigInt(value), byteLength);\n}\n\nexport function bigIntToBytes(value: bigint, length: number = 16): Uint8Array {\n const hex = value.toString(16).padStart(length * 2, \"0\");\n return hexToBytes(hex);\n}\n\nexport function intToHex(integer: IntegerType, byteLength = 8): string {\n const value = typeof integer === \"bigint\" ? integer : intToBigInt(integer);\n return value.toString(16).padStart(byteLength * 2, \"0\");\n}\n\nexport function toTwos(value: bigint, width: bigint): bigint {\n const limit = BigInt(1) << (width - BigInt(1));\n if (value < -limit || value > limit - BigInt(1)) {\n throw new Error(`Unable to represent integer in width: ${width}`);\n }\n if (value >= BigInt(0)) return value;\n return value + (BigInt(1) << width);\n}\n\nexport function fromTwos(value: bigint, width: bigint): bigint {\n if (value & (BigInt(1) << (width - BigInt(1)))) {\n return value - (BigInt(1) << width);\n }\n return value;\n}\n\nexport function bytesToTwosBigInt(bytes: Uint8Array): bigint {\n return fromTwos(BigInt(`0x${
|
|
9
|
+
"const hexes = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, \"0\"));\n\nexport function bytesToHex(bytes: Uint8Array): string {\n let hex = \"\";\n for (const b of bytes) {\n hex += hexes[b];\n }\n return hex;\n}\n\nexport function hexToBytes(hex: string): Uint8Array {\n hex = without0x(hex);\n if (hex.length % 2) hex = `0${hex}`;\n\n const array = new Uint8Array(hex.length / 2);\n for (let i = 0; i < array.length; i++) {\n const j = i * 2;\n const byte = Number.parseInt(hex.slice(j, j + 2), 16);\n if (Number.isNaN(byte) || byte < 0) throw new Error(\"Invalid byte sequence\");\n array[i] = byte;\n }\n return array;\n}\n\nexport function with0x(value: string): string {\n return /^0x/i.test(value) ? value : `0x${value}`;\n}\n\nexport function without0x(value: string): string {\n return /^0x/i.test(value) ? value.slice(2) : value;\n}\n\nexport function utf8ToBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\nexport function bytesToUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\nexport function asciiToBytes(str: string): Uint8Array {\n const bytes = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n bytes[i] = str.charCodeAt(i) & 0xff;\n }\n return bytes;\n}\n\nexport function bytesToAscii(bytes: Uint8Array): string {\n return String.fromCharCode(...bytes);\n}\n\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n if (arrays.length === 1) return arrays[0]!;\n const length = arrays.reduce((a, arr) => a + arr.length, 0);\n const result = new Uint8Array(length);\n let pad = 0;\n for (const arr of arrays) {\n result.set(arr, pad);\n pad += arr.length;\n }\n return result;\n}\n\nexport type IntegerType = number | string | bigint | Uint8Array;\n\nexport function intToBigInt(value: IntegerType): bigint {\n if (typeof value === \"bigint\") return value;\n if (typeof value === \"string\") return BigInt(value);\n if (typeof value === \"number\") {\n if (!Number.isInteger(value))\n throw new RangeError(\"Values of type 'number' must be an integer.\");\n if (value > Number.MAX_SAFE_INTEGER)\n throw new RangeError(\n `Values of type 'number' must be <= ${Number.MAX_SAFE_INTEGER}. Use BigInt instead.`\n );\n return BigInt(value);\n }\n if (value instanceof Uint8Array) return BigInt(`0x${bytesToHex(value)}`);\n throw new TypeError(\"Must be a number, bigint, string, or Uint8Array.\");\n}\n\nexport function intToBytes(value: IntegerType, byteLength: number): Uint8Array {\n return bigIntToBytes(intToBigInt(value), byteLength);\n}\n\nexport function bigIntToBytes(value: bigint, length: number = 16): Uint8Array {\n const hex = value.toString(16).padStart(length * 2, \"0\");\n return hexToBytes(hex);\n}\n\nexport function intToHex(integer: IntegerType, byteLength = 8): string {\n const value = typeof integer === \"bigint\" ? integer : intToBigInt(integer);\n return value.toString(16).padStart(byteLength * 2, \"0\");\n}\n\nexport function toTwos(value: bigint, width: bigint): bigint {\n const limit = BigInt(1) << (width - BigInt(1));\n if (value < -limit || value > limit - BigInt(1)) {\n throw new Error(`Unable to represent integer in width: ${width}`);\n }\n if (value >= BigInt(0)) return value;\n return value + (BigInt(1) << width);\n}\n\nexport function fromTwos(value: bigint, width: bigint): bigint {\n if (value & (BigInt(1) << (width - BigInt(1)))) {\n return value - (BigInt(1) << width);\n }\n return value;\n}\n\nexport function bytesToTwosBigInt(bytes: Uint8Array): bigint {\n if (bytes.length === 0) return 0n;\n const hex = bytesToHex(bytes);\n if (hex.length === 0) return 0n;\n return fromTwos(BigInt(`0x${hex}`), BigInt(bytes.byteLength * 8));\n}\n\nexport function writeUInt32BE(value: number): Uint8Array {\n const buf = new Uint8Array(4);\n buf[0] = (value >>> 24) & 0xff;\n buf[1] = (value >>> 16) & 0xff;\n buf[2] = (value >>> 8) & 0xff;\n buf[3] = value & 0xff;\n return buf;\n}\n\nexport function readUInt32BE(bytes: Uint8Array, offset = 0): number {\n return (\n ((bytes[offset]! << 24) |\n (bytes[offset + 1]! << 16) |\n (bytes[offset + 2]! << 8) |\n bytes[offset + 3]!) >>>\n 0\n );\n}\n\nexport function writeUInt16BE(value: number): Uint8Array {\n const buf = new Uint8Array(2);\n buf[0] = (value >>> 8) & 0xff;\n buf[1] = value & 0xff;\n return buf;\n}\n\nexport function readUInt16BE(bytes: Uint8Array, offset = 0): number {\n return ((bytes[offset]! << 8) | bytes[offset + 1]!) >>> 0;\n}\n\nexport function writeUInt8(value: number): Uint8Array {\n return new Uint8Array([value & 0xff]);\n}\n",
|
|
10
10
|
"import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { bytesToHex, hexToBytes } from \"./encoding.ts\";\n\nconst C32 = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\nconst HEX = \"0123456789abcdef\";\n\nfunction c32normalize(input: string): string {\n return input.toUpperCase().replace(/O/g, \"0\").replace(/L|I/g, \"1\");\n}\n\nfunction c32encode(inputHex: string): string {\n if (inputHex.length % 2 !== 0) inputHex = `0${inputHex}`;\n inputHex = inputHex.toLowerCase();\n\n const res: string[] = [];\n let carry = 0;\n for (let i = inputHex.length - 1; i >= 0; i--) {\n if (carry < 4) {\n const currentCode = HEX.indexOf(inputHex[i]!) >> carry;\n const nextCode = i !== 0 ? HEX.indexOf(inputHex[i - 1]!) : 0;\n const nextBits = 1 + carry;\n const nextLowBits = (nextCode % (1 << nextBits)) << (5 - nextBits);\n res.unshift(C32[currentCode + nextLowBits]!);\n carry = nextBits;\n } else {\n carry = 0;\n }\n }\n\n // Strip leading c32 zeros\n let leadingZeros = 0;\n while (leadingZeros < res.length && res[leadingZeros] === \"0\") leadingZeros++;\n const stripped = res.slice(leadingZeros);\n\n // Preserve leading zero bytes from hex\n const bytes = hexToBytes(inputHex);\n let zeroBytesCount = 0;\n while (zeroBytesCount < bytes.length && bytes[zeroBytesCount] === 0) zeroBytesCount++;\n const prefix = Array(zeroBytesCount).fill(C32[0]) as string[];\n\n return [...prefix, ...stripped].join(\"\");\n}\n\nfunction c32decode(c32input: string): string {\n c32input = c32normalize(c32input);\n if (!c32input.match(`^[${C32}]*$`)) throw new Error(\"Not a c32-encoded string\");\n\n const zeroPrefix = c32input.match(`^${C32[0]}*`);\n const numLeadingZeroBytes = zeroPrefix ? zeroPrefix[0]!.length : 0;\n\n const res: string[] = [];\n let carry = 0;\n let carryBits = 0;\n for (let i = c32input.length - 1; i >= 0; i--) {\n if (carryBits === 4) {\n res.unshift(HEX[carry]!);\n carryBits = 0;\n carry = 0;\n }\n const currentValue = (C32.indexOf(c32input[i]!) << carryBits) + carry;\n res.unshift(HEX[currentValue % 16]!);\n carryBits += 1;\n carry = currentValue >> 4;\n if (carry > 1 << carryBits) throw new Error(\"Panic error in c32 decoding\");\n }\n res.unshift(HEX[carry]!);\n\n if (res.length % 2 === 1) res.unshift(\"0\");\n\n // Strip leading hex zeros\n let hexLeadingZeros = 0;\n while (hexLeadingZeros < res.length && res[hexLeadingZeros] === \"0\") hexLeadingZeros++;\n let hexStr = res.slice(hexLeadingZeros - (hexLeadingZeros % 2)).join(\"\");\n\n for (let i = 0; i < numLeadingZeroBytes; i++) hexStr = `00${hexStr}`;\n\n return hexStr;\n}\n\nfunction c32checksum(dataHex: string): string {\n return bytesToHex(sha256(sha256(hexToBytes(dataHex))).slice(0, 4));\n}\n\nfunction c32checkEncode(version: number, data: string): string {\n if (version < 0 || version >= 32) throw new Error(\"Invalid version (must be between 0 and 31)\");\n if (!data.match(/^[0-9a-fA-F]*$/)) throw new Error(\"Invalid data (not a hex string)\");\n\n data = data.toLowerCase();\n if (data.length % 2 !== 0) data = `0${data}`;\n\n let versionHex = version.toString(16);\n if (versionHex.length === 1) versionHex = `0${versionHex}`;\n\n const checksumHex = c32checksum(`${versionHex}${data}`);\n return `${C32[version]}${c32encode(`${data}${checksumHex}`)}`;\n}\n\nfunction c32checkDecode(c32data: string): [number, string] {\n c32data = c32normalize(c32data);\n const dataHex = c32decode(c32data.slice(1));\n const version = C32.indexOf(c32data[0]!);\n const checksum = dataHex.slice(-8);\n\n let versionHex = version.toString(16);\n if (versionHex.length === 1) versionHex = `0${versionHex}`;\n\n if (c32checksum(`${versionHex}${dataHex.substring(0, dataHex.length - 8)}`) !== checksum) {\n throw new Error(\"Invalid c32check string: checksum mismatch\");\n }\n\n return [version, dataHex.substring(0, dataHex.length - 8)];\n}\n\nexport function c32address(version: number, hash160hex: string): string {\n if (!hash160hex.match(/^[0-9a-fA-F]{40}$/)) {\n throw new Error(\"Invalid argument: not a hash160 hex string\");\n }\n return `S${c32checkEncode(version, hash160hex)}`;\n}\n\nexport function c32addressDecode(c32addr: string): [number, string] {\n if (c32addr.length <= 5) throw new Error(\"Invalid c32 address: invalid length\");\n if (c32addr[0] !== \"S\") throw new Error('Invalid c32 address: must start with \"S\"');\n return c32checkDecode(c32addr.slice(1));\n}\n",
|
|
11
11
|
"export type ClarityType =\n | \"int\"\n | \"uint\"\n | \"buffer\"\n | \"true\"\n | \"false\"\n | \"address\"\n | \"contract\"\n | \"ok\"\n | \"err\"\n | \"none\"\n | \"some\"\n | \"list\"\n | \"tuple\"\n | \"ascii\"\n | \"utf8\";\n\n/** Wire type IDs matching the Stacks binary format (SIP-005) */\nexport const ClarityWireType = {\n int: 0x00,\n uint: 0x01,\n buffer: 0x02,\n true: 0x03,\n false: 0x04,\n address: 0x05,\n contract: 0x06,\n ok: 0x07,\n err: 0x08,\n none: 0x09,\n some: 0x0a,\n list: 0x0b,\n tuple: 0x0c,\n ascii: 0x0d,\n utf8: 0x0e,\n} as const satisfies Record<ClarityType, number>;\n\n/** Reverse lookup: wire byte → ClarityType string */\nconst wireTypeToClarity = Object.fromEntries(\n Object.entries(ClarityWireType).map(([k, v]) => [v, k])\n) as Record<number, ClarityType>;\n\nexport function clarityTypeFromByte(byte: number): ClarityType {\n const type = wireTypeToClarity[byte];\n if (!type) throw new Error(`Unknown clarity wire type: ${byte}`);\n return type;\n}\n\n// CV types\n\nexport type IntCV = { readonly type: \"int\"; readonly value: bigint };\nexport type UIntCV = { readonly type: \"uint\"; readonly value: bigint };\nexport type BooleanCV = TrueCV | FalseCV;\nexport type TrueCV = { readonly type: \"true\" };\nexport type FalseCV = { readonly type: \"false\" };\nexport type BufferCV = { readonly type: \"buffer\"; readonly value: string }; // hex\nexport type NoneCV = { readonly type: \"none\" };\nexport type SomeCV = {\n readonly type: \"some\";\n readonly value: ClarityValue;\n};\nexport type OptionalCV = NoneCV | SomeCV;\nexport type ResponseOkCV = {\n readonly type: \"ok\";\n readonly value: ClarityValue;\n};\nexport type ResponseErrorCV = {\n readonly type: \"err\";\n readonly value: ClarityValue;\n};\nexport type ResponseCV = ResponseOkCV | ResponseErrorCV;\nexport type StandardPrincipalCV = {\n readonly type: \"address\";\n readonly value: string;\n};\nexport type ContractPrincipalCV = {\n readonly type: \"contract\";\n readonly value: string; // \"address.name\"\n};\nexport type PrincipalCV = StandardPrincipalCV | ContractPrincipalCV;\nexport type ListCV = {\n type: \"list\";\n value: ClarityValue[];\n};\nexport type TupleData = {\n [key: string]: ClarityValue;\n};\nexport type TupleCV = {\n type: \"tuple\";\n value: TupleData;\n};\nexport type StringAsciiCV = {\n readonly type: \"ascii\";\n readonly value: string;\n};\nexport type StringUtf8CV = {\n readonly type: \"utf8\";\n readonly value: string;\n};\n\nexport type ClarityValue =\n | IntCV\n | UIntCV\n | BooleanCV\n | BufferCV\n | NoneCV\n | SomeCV\n | ResponseOkCV\n | ResponseErrorCV\n | StandardPrincipalCV\n | ContractPrincipalCV\n | ListCV\n | TupleCV\n | StringAsciiCV\n | StringUtf8CV;\n",
|
|
12
12
|
"import {\n bytesToHex,\n hexToBytes,\n concatBytes,\n bigIntToBytes,\n toTwos,\n asciiToBytes,\n utf8ToBytes,\n writeUInt32BE,\n intToHex,\n} from \"../utils/encoding.ts\";\nimport { c32addressDecode } from \"../utils/c32.ts\";\nimport { ClarityWireType, type ClarityValue, type ClarityType } from \"./types.ts\";\n\nconst CLARITY_INT_SIZE = 128n;\nconst CLARITY_INT_BYTE_SIZE = 16;\n\nfunction typeIdByte(type: ClarityType): number {\n return ClarityWireType[type];\n}\n\nfunction withTypeId(type: ClarityType, bytes: Uint8Array): Uint8Array {\n return concatBytes(new Uint8Array([typeIdByte(type)]), bytes);\n}\n\nfunction serializeAddress(c32Address: string): Uint8Array {\n const [version, hash160] = c32addressDecode(c32Address);\n return concatBytes(new Uint8Array([version]), hexToBytes(hash160));\n}\n\nfunction serializeLPString(str: string, prefixBytes = 1): Uint8Array {\n const content = utf8ToBytes(str);\n const lengthPrefix = hexToBytes(intToHex(content.byteLength, prefixBytes));\n return concatBytes(lengthPrefix, content);\n}\n\nexport function serializeCVBytes(value: ClarityValue): Uint8Array {\n switch (value.type) {\n case \"true\":\n case \"false\":\n return new Uint8Array([typeIdByte(value.type)]);\n\n case \"int\": {\n const bytes = bigIntToBytes(\n toTwos(BigInt(value.value), CLARITY_INT_SIZE),\n CLARITY_INT_BYTE_SIZE\n );\n return withTypeId(value.type, bytes);\n }\n\n case \"uint\": {\n const bytes = bigIntToBytes(BigInt(value.value), CLARITY_INT_BYTE_SIZE);\n return withTypeId(value.type, bytes);\n }\n\n case \"buffer\": {\n const bufBytes = hexToBytes(value.value);\n return withTypeId(\n value.type,\n concatBytes(writeUInt32BE(bufBytes.length), bufBytes)\n );\n }\n\n case \"none\":\n return new Uint8Array([typeIdByte(value.type)]);\n\n case \"some\":\n return withTypeId(value.type, serializeCVBytes(value.value));\n\n case \"ok\":\n case \"err\":\n return withTypeId(value.type, serializeCVBytes(value.value));\n\n case \"address\":\n return withTypeId(value.type, serializeAddress(value.value));\n\n case \"contract\": {\n const [addr, name] = value.value.split(\".\");\n if (!addr || !name) throw new Error(`Invalid contract principal: ${value.value}`);\n return withTypeId(\n value.type,\n concatBytes(serializeAddress(addr), serializeLPString(name))\n );\n }\n\n case \"list\": {\n const parts: Uint8Array[] = [writeUInt32BE(value.value.length)];\n for (const item of value.value) {\n parts.push(serializeCVBytes(item));\n }\n return withTypeId(value.type, concatBytes(...parts));\n }\n\n case \"tuple\": {\n const keys = Object.keys(value.value).sort((a, b) => a.localeCompare(b));\n const parts: Uint8Array[] = [writeUInt32BE(keys.length)];\n for (const key of keys) {\n parts.push(serializeLPString(key));\n parts.push(serializeCVBytes(value.value[key]!));\n }\n return withTypeId(value.type, concatBytes(...parts));\n }\n\n case \"ascii\": {\n const strBytes = asciiToBytes(value.value);\n return withTypeId(\n value.type,\n concatBytes(writeUInt32BE(strBytes.length), strBytes)\n );\n }\n\n case \"utf8\": {\n const strBytes = utf8ToBytes(value.value);\n return withTypeId(\n value.type,\n concatBytes(writeUInt32BE(strBytes.length), strBytes)\n );\n }\n\n default:\n throw new Error(`Cannot serialize unknown clarity type`);\n }\n}\n\nexport function serializeCV(value: ClarityValue): string {\n return bytesToHex(serializeCVBytes(value));\n}\n",
|
|
13
13
|
"import type { Methods, MethodParams, MethodResult } from \"./types.ts\";\nimport { getProvider } from \"./provider.ts\";\nimport { ConnectError, JsonRpcError } from \"./errors.ts\";\nimport { cacheAddresses } from \"./storage.ts\";\nimport { serializeCVBytes } from \"../clarity/serialize.ts\";\nimport { bytesToHex } from \"../utils/encoding.ts\";\n\nconst POST_CONDITION_TYPES = new Set([\n \"stx-postcondition\",\n \"ft-postcondition\",\n \"nft-postcondition\",\n]);\n\nfunction isClarityValue(obj: unknown): obj is { type: string } {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"type\" in obj &&\n typeof (obj as any).type === \"string\" &&\n !POST_CONDITION_TYPES.has((obj as any).type)\n );\n}\n\nfunction serializeParams(value: unknown): unknown {\n if (value === null || value === undefined) return value;\n if (typeof value === \"bigint\") return value.toString();\n if (Array.isArray(value)) return value.map(serializeParams);\n\n if (typeof value === \"object\") {\n if (value instanceof Uint8Array) return value;\n\n if (POST_CONDITION_TYPES.has((value as any).type)) return value;\n\n if (isClarityValue(value)) {\n return bytesToHex(serializeCVBytes(value as any));\n }\n\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) {\n result[k] = serializeParams(v);\n }\n return result;\n }\n\n return value;\n}\n\nconst ADDRESS_METHODS = new Set([\"getAddresses\", \"stx_getAddresses\"]);\n\nexport async function request<M extends keyof Methods>(\n method: M,\n ...args: MethodParams<M> extends undefined\n ? []\n : [params: MethodParams<M>]\n): Promise<MethodResult<M>> {\n const provider = getProvider();\n\n const params = args[0];\n const serialized = params ? serializeParams(params) : undefined;\n\n let result: any;\n try {\n result = await provider.request(method as string, serialized);\n } catch (err: any) {\n if (err?.code !== undefined) {\n throw new JsonRpcError(err.message ?? String(err), err.code, {\n data: err.data,\n });\n }\n throw new ConnectError(err?.message ?? \"Wallet request failed\", {\n cause: err instanceof Error ? err : undefined,\n });\n }\n\n if (ADDRESS_METHODS.has(method as string) && result?.addresses) {\n cacheAddresses(result.addresses);\n }\n\n return result as MethodResult<M>;\n}\n",
|
|
14
14
|
"import type { AddressesResult } from \"./types.ts\";\nimport { request } from \"./request.ts\";\nimport { getProvider } from \"./provider.ts\";\nimport { clearStorage, getStorageData } from \"./storage.ts\";\n\nexport async function connect(): Promise<AddressesResult> {\n return request(\"getAddresses\");\n}\n\nexport function disconnect(): void {\n clearStorage();\n try {\n getProvider().disconnect?.();\n } catch {\n // provider may not exist — that's fine\n }\n}\n\nexport function isConnected(): boolean {\n const data = getStorageData();\n return (data?.addresses?.stx?.length ?? 0) > 0;\n}\n"
|
|
15
15
|
],
|
|
16
|
-
"mappings": "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",
|
|
16
|
+
"mappings": "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",
|
|
17
17
|
"debugId": "3C3F545063FC926364756E2164756E21",
|
|
18
18
|
"names": []
|
|
19
19
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"/** WalletConnect v2 envelope encryption (Type 0 + Type 1) + relay JWT auth */\n\nimport { ed25519, x25519 } from \"@noble/curves/ed25519.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { hkdf } from \"@noble/hashes/hkdf.js\";\nimport { randomBytes } from \"@noble/hashes/utils.js\";\nimport { gcm } from \"@noble/ciphers/aes.js\";\nimport { base58, base64urlnopad } from \"@scure/base\";\nimport { bytesToHex, hexToBytes } from \"../../utils/encoding.ts\";\n\nconst IV_LENGTH = 12;\nconst KEY_LENGTH = 32;\nconst TYPE_0 = 0x00;\nconst TYPE_1 = 0x01;\n\n// -- Key generation --\n\nexport function generateKeyPair() {\n const privateKey = randomBytes(KEY_LENGTH);\n const publicKey = x25519.getPublicKey(privateKey);\n return { privateKey, publicKey };\n}\n\nexport function generateSymKey(): Uint8Array {\n return randomBytes(KEY_LENGTH);\n}\n\n/** Derive symmetric key from X25519 shared secret via HKDF */\nexport function deriveSymKey(\n selfPrivate: Uint8Array,\n peerPublic: Uint8Array,\n): Uint8Array {\n const shared = x25519.getSharedSecret(selfPrivate, peerPublic);\n return hkdf(sha256, shared, undefined, undefined, KEY_LENGTH);\n}\n\n/** Topic = first 32 bytes of SHA-256(symKey) as hex */\nexport function symKeyToTopic(symKey: Uint8Array): string {\n return bytesToHex(sha256(symKey));\n}\n\n// -- Base64 helpers (browser-safe) --\n\nexport function encodeBase64(data: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < data.length; i++) binary += String.fromCharCode(data[i]!);\n return btoa(binary);\n}\n\nexport function decodeBase64(str: string): Uint8Array {\n const binary = atob(str);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n}\n\n// -- Type 0 envelope (symmetric, pairing) --\n// Layout: [0x00][12-byte IV][ciphertext + 16-byte tag]\n\nexport function encryptType0(\n symKey: Uint8Array,\n plaintext: string,\n): Uint8Array {\n const iv = randomBytes(IV_LENGTH);\n const data = new TextEncoder().encode(plaintext);\n const cipher = gcm(symKey, iv);\n const sealed = cipher.encrypt(data);\n const envelope = new Uint8Array(1 + IV_LENGTH + sealed.length);\n envelope[0] = TYPE_0;\n envelope.set(iv, 1);\n envelope.set(sealed, 1 + IV_LENGTH);\n return envelope;\n}\n\nexport function decryptType0(\n symKey: Uint8Array,\n envelope: Uint8Array,\n): string {\n if (envelope[0] !== TYPE_0) throw new Error(\"Not a type-0 envelope\");\n const iv = envelope.subarray(1, 1 + IV_LENGTH);\n const sealed = envelope.subarray(1 + IV_LENGTH);\n const cipher = gcm(symKey, iv);\n const plain = cipher.decrypt(sealed);\n return new TextDecoder().decode(plain);\n}\n\n// -- Type 1 envelope (asymmetric, session proposal) --\n// Layout: [0x01][32-byte sender pubkey][12-byte IV][ciphertext + 16-byte tag]\n\nexport function encryptType1(\n senderPrivate: Uint8Array,\n receiverPublic: Uint8Array,\n plaintext: string,\n): Uint8Array {\n const senderPublic = x25519.getPublicKey(senderPrivate);\n const symKey = deriveSymKey(senderPrivate, receiverPublic);\n const iv = randomBytes(IV_LENGTH);\n const data = new TextEncoder().encode(plaintext);\n const cipher = gcm(symKey, iv);\n const sealed = cipher.encrypt(data);\n const envelope = new Uint8Array(1 + KEY_LENGTH + IV_LENGTH + sealed.length);\n envelope[0] = TYPE_1;\n envelope.set(senderPublic, 1);\n envelope.set(iv, 1 + KEY_LENGTH);\n envelope.set(sealed, 1 + KEY_LENGTH + IV_LENGTH);\n return envelope;\n}\n\nexport function decryptType1(\n receiverPrivate: Uint8Array,\n envelope: Uint8Array,\n): string {\n if (envelope[0] !== TYPE_1) throw new Error(\"Not a type-1 envelope\");\n const senderPublic = envelope.subarray(1, 1 + KEY_LENGTH);\n const iv = envelope.subarray(1 + KEY_LENGTH, 1 + KEY_LENGTH + IV_LENGTH);\n const sealed = envelope.subarray(1 + KEY_LENGTH + IV_LENGTH);\n const symKey = deriveSymKey(receiverPrivate, senderPublic);\n const cipher = gcm(symKey, iv);\n const plain = cipher.decrypt(sealed);\n return new TextDecoder().decode(plain);\n}\n\n// -- Unified decrypt --\n\nexport function decrypt(\n keyOrPrivate: Uint8Array,\n envelope: Uint8Array,\n): string {\n return envelope[0] === TYPE_1\n ? decryptType1(keyOrPrivate, envelope)\n : decryptType0(keyOrPrivate, envelope);\n}\n\n// -- Relay JWT auth (Ed25519 + did:key) --\n\n/** Ed25519 multicodec varint prefix */\nconst ED25519_MULTICODEC = new Uint8Array([0xed, 0x01]);\n\nfunction encodeDidKey(publicKey: Uint8Array): string {\n const prefixed = new Uint8Array(ED25519_MULTICODEC.length + publicKey.length);\n prefixed.set(ED25519_MULTICODEC);\n prefixed.set(publicKey, ED25519_MULTICODEC.length);\n return `did:key:z${base58.encode(prefixed)}`;\n}\n\nfunction base64urlEncode(data: Uint8Array | string): string {\n const bytes =\n typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n return base64urlnopad.encode(bytes);\n}\n\n/** Generate a signed JWT for WC relay authentication */\nexport function createRelayAuthJwt(\n relayUrl: string,\n): { jwt: string; clientId: string } {\n const privateKey = ed25519.utils.randomSecretKey();\n const publicKey = ed25519.getPublicKey(privateKey);\n const clientId = encodeDidKey(publicKey);\n\n const now = Math.floor(Date.now() / 1000);\n const header = base64urlEncode(JSON.stringify({ alg: \"EdDSA\", typ: \"JWT\" }));\n const payload = base64urlEncode(\n JSON.stringify({\n iss: clientId,\n sub: bytesToHex(randomBytes(32)),\n aud: relayUrl,\n iat: now,\n exp: now + 86400, // 24 hours\n act: \"client_auth\",\n }),\n );\n\n const message = new TextEncoder().encode(`${header}.${payload}`);\n const signature = base64urlEncode(ed25519.sign(message, privateKey));\n\n return { jwt: `${header}.${payload}.${signature}`, clientId };\n}\n\nexport { bytesToHex, hexToBytes };\n",
|
|
6
6
|
"/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nfunction isBytes(a) {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n/** Asserts something is Uint8Array. */\nfunction abytes(b) {\n if (!isBytes(b))\n throw new Error('Uint8Array expected');\n}\nfunction isArrayOf(isString, arr) {\n if (!Array.isArray(arr))\n return false;\n if (arr.length === 0)\n return true;\n if (isString) {\n return arr.every((item) => typeof item === 'string');\n }\n else {\n return arr.every((item) => Number.isSafeInteger(item));\n }\n}\nfunction afn(input) {\n if (typeof input !== 'function')\n throw new Error('function expected');\n return true;\n}\nfunction astr(label, input) {\n if (typeof input !== 'string')\n throw new Error(`${label}: string expected`);\n return true;\n}\nfunction anumber(n) {\n if (!Number.isSafeInteger(n))\n throw new Error(`invalid integer: ${n}`);\n}\nfunction aArr(input) {\n if (!Array.isArray(input))\n throw new Error('array expected');\n}\nfunction astrArr(label, input) {\n if (!isArrayOf(true, input))\n throw new Error(`${label}: array of strings expected`);\n}\nfunction anumArr(label, input) {\n if (!isArrayOf(false, input))\n throw new Error(`${label}: array of numbers expected`);\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction chain(...args) {\n const id = (a) => a;\n // Wrap call in closure so JIT can inline calls\n const wrap = (a, b) => (c) => a(b(c));\n // Construct chain of args[-1].encode(args[-2].encode([...]))\n const encode = args.map((x) => x.encode).reduceRight(wrap, id);\n // Construct chain of args[0].decode(args[1].decode(...))\n const decode = args.map((x) => x.decode).reduce(wrap, id);\n return { encode, decode };\n}\n/**\n * Encodes integer radix representation to array of strings using alphabet and back.\n * Could also be array of strings.\n * @__NO_SIDE_EFFECTS__\n */\nfunction alphabet(letters) {\n // mapping 1 to \"b\"\n const lettersA = typeof letters === 'string' ? letters.split('') : letters;\n const len = lettersA.length;\n astrArr('alphabet', lettersA);\n // mapping \"b\" to 1\n const indexes = new Map(lettersA.map((l, i) => [l, i]));\n return {\n encode: (digits) => {\n aArr(digits);\n return digits.map((i) => {\n if (!Number.isSafeInteger(i) || i < 0 || i >= len)\n throw new Error(`alphabet.encode: digit index outside alphabet \"${i}\". Allowed: ${letters}`);\n return lettersA[i];\n });\n },\n decode: (input) => {\n aArr(input);\n return input.map((letter) => {\n astr('alphabet.decode', letter);\n const i = indexes.get(letter);\n if (i === undefined)\n throw new Error(`Unknown letter: \"${letter}\". Allowed: ${letters}`);\n return i;\n });\n },\n };\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction join(separator = '') {\n astr('join', separator);\n return {\n encode: (from) => {\n astrArr('join.decode', from);\n return from.join(separator);\n },\n decode: (to) => {\n astr('join.decode', to);\n return to.split(separator);\n },\n };\n}\n/**\n * Pad strings array so it has integer number of bits\n * @__NO_SIDE_EFFECTS__\n */\nfunction padding(bits, chr = '=') {\n anumber(bits);\n astr('padding', chr);\n return {\n encode(data) {\n astrArr('padding.encode', data);\n while ((data.length * bits) % 8)\n data.push(chr);\n return data;\n },\n decode(input) {\n astrArr('padding.decode', input);\n let end = input.length;\n if ((end * bits) % 8)\n throw new Error('padding: invalid, string should have whole number of bytes');\n for (; end > 0 && input[end - 1] === chr; end--) {\n const last = end - 1;\n const byte = last * bits;\n if (byte % 8 === 0)\n throw new Error('padding: invalid, string has too much padding');\n }\n return input.slice(0, end);\n },\n };\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction normalize(fn) {\n afn(fn);\n return { encode: (from) => from, decode: (to) => fn(to) };\n}\n/**\n * Slow: O(n^2) time complexity\n */\nfunction convertRadix(data, from, to) {\n // base 1 is impossible\n if (from < 2)\n throw new Error(`convertRadix: invalid from=${from}, base cannot be less than 2`);\n if (to < 2)\n throw new Error(`convertRadix: invalid to=${to}, base cannot be less than 2`);\n aArr(data);\n if (!data.length)\n return [];\n let pos = 0;\n const res = [];\n const digits = Array.from(data, (d) => {\n anumber(d);\n if (d < 0 || d >= from)\n throw new Error(`invalid integer: ${d}`);\n return d;\n });\n const dlen = digits.length;\n while (true) {\n let carry = 0;\n let done = true;\n for (let i = pos; i < dlen; i++) {\n const digit = digits[i];\n const fromCarry = from * carry;\n const digitBase = fromCarry + digit;\n if (!Number.isSafeInteger(digitBase) ||\n fromCarry / from !== carry ||\n digitBase - digit !== fromCarry) {\n throw new Error('convertRadix: carry overflow');\n }\n const div = digitBase / to;\n carry = digitBase % to;\n const rounded = Math.floor(div);\n digits[i] = rounded;\n if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)\n throw new Error('convertRadix: carry overflow');\n if (!done)\n continue;\n else if (!rounded)\n pos = i;\n else\n done = false;\n }\n res.push(carry);\n if (done)\n break;\n }\n for (let i = 0; i < data.length - 1 && data[i] === 0; i++)\n res.push(0);\n return res.reverse();\n}\nconst gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));\nconst radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));\nconst powers = /* @__PURE__ */ (() => {\n let res = [];\n for (let i = 0; i < 40; i++)\n res.push(2 ** i);\n return res;\n})();\n/**\n * Implemented with numbers, because BigInt is 5x slower\n */\nfunction convertRadix2(data, from, to, padding) {\n aArr(data);\n if (from <= 0 || from > 32)\n throw new Error(`convertRadix2: wrong from=${from}`);\n if (to <= 0 || to > 32)\n throw new Error(`convertRadix2: wrong to=${to}`);\n if (radix2carry(from, to) > 32) {\n throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);\n }\n let carry = 0;\n let pos = 0; // bitwise position in current element\n const max = powers[from];\n const mask = powers[to] - 1;\n const res = [];\n for (const n of data) {\n anumber(n);\n if (n >= max)\n throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);\n carry = (carry << from) | n;\n if (pos + from > 32)\n throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);\n pos += from;\n for (; pos >= to; pos -= to)\n res.push(((carry >> (pos - to)) & mask) >>> 0);\n const pow = powers[pos];\n if (pow === undefined)\n throw new Error('invalid carry');\n carry &= pow - 1; // clean carry, otherwise it will cause overflow\n }\n carry = (carry << (to - pos)) & mask;\n if (!padding && pos >= from)\n throw new Error('Excess padding');\n if (!padding && carry > 0)\n throw new Error(`Non-zero padding: ${carry}`);\n if (padding && pos > 0)\n res.push(carry >>> 0);\n return res;\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction radix(num) {\n anumber(num);\n const _256 = 2 ** 8;\n return {\n encode: (bytes) => {\n if (!isBytes(bytes))\n throw new Error('radix.encode input should be Uint8Array');\n return convertRadix(Array.from(bytes), _256, num);\n },\n decode: (digits) => {\n anumArr('radix.decode', digits);\n return Uint8Array.from(convertRadix(digits, num, _256));\n },\n };\n}\n/**\n * If both bases are power of same number (like `2**8 <-> 2**64`),\n * there is a linear algorithm. For now we have implementation for power-of-two bases only.\n * @__NO_SIDE_EFFECTS__\n */\nfunction radix2(bits, revPadding = false) {\n anumber(bits);\n if (bits <= 0 || bits > 32)\n throw new Error('radix2: bits should be in (0..32]');\n if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)\n throw new Error('radix2: carry overflow');\n return {\n encode: (bytes) => {\n if (!isBytes(bytes))\n throw new Error('radix2.encode input should be Uint8Array');\n return convertRadix2(Array.from(bytes), 8, bits, !revPadding);\n },\n decode: (digits) => {\n anumArr('radix2.decode', digits);\n return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));\n },\n };\n}\nfunction unsafeWrapper(fn) {\n afn(fn);\n return function (...args) {\n try {\n return fn.apply(null, args);\n }\n catch (e) { }\n };\n}\nfunction checksum(len, fn) {\n anumber(len);\n afn(fn);\n return {\n encode(data) {\n if (!isBytes(data))\n throw new Error('checksum.encode: input should be Uint8Array');\n const sum = fn(data).slice(0, len);\n const res = new Uint8Array(data.length + len);\n res.set(data);\n res.set(sum, data.length);\n return res;\n },\n decode(data) {\n if (!isBytes(data))\n throw new Error('checksum.decode: input should be Uint8Array');\n const payload = data.slice(0, -len);\n const oldChecksum = data.slice(-len);\n const newChecksum = fn(payload).slice(0, len);\n for (let i = 0; i < len; i++)\n if (newChecksum[i] !== oldChecksum[i])\n throw new Error('Invalid checksum');\n return payload;\n },\n };\n}\n// prettier-ignore\nexport const utils = {\n alphabet, chain, checksum, convertRadix, convertRadix2, radix, radix2, join, padding,\n};\n// RFC 4648 aka RFC 3548\n// ---------------------\n/**\n * base16 encoding from RFC 4648.\n * @example\n * ```js\n * base16.encode(Uint8Array.from([0x12, 0xab]));\n * // => '12AB'\n * ```\n */\nexport const base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));\n/**\n * base32 encoding from RFC 4648. Has padding.\n * Use `base32nopad` for unpadded version.\n * Also check out `base32hex`, `base32hexnopad`, `base32crockford`.\n * @example\n * ```js\n * base32.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'CKVQ===='\n * base32.decode('CKVQ====');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));\n/**\n * base32 encoding from RFC 4648. No padding.\n * Use `base32` for padded version.\n * Also check out `base32hex`, `base32hexnopad`, `base32crockford`.\n * @example\n * ```js\n * base32nopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'CKVQ'\n * base32nopad.decode('CKVQ');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32nopad = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), join(''));\n/**\n * base32 encoding from RFC 4648. Padded. Compared to ordinary `base32`, slightly different alphabet.\n * Use `base32hexnopad` for unpadded version.\n * @example\n * ```js\n * base32hex.encode(Uint8Array.from([0x12, 0xab]));\n * // => '2ALG===='\n * base32hex.decode('2ALG====');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32hex = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));\n/**\n * base32 encoding from RFC 4648. No padding. Compared to ordinary `base32`, slightly different alphabet.\n * Use `base32hex` for padded version.\n * @example\n * ```js\n * base32hexnopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => '2ALG'\n * base32hexnopad.decode('2ALG');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32hexnopad = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), join(''));\n/**\n * base32 encoding from RFC 4648. Doug Crockford's version.\n * https://www.crockford.com/base32.html\n * @example\n * ```js\n * base32crockford.encode(Uint8Array.from([0x12, 0xab]));\n * // => '2ANG'\n * base32crockford.decode('2ANG');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32crockford = chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));\n// Built-in base64 conversion https://caniuse.com/mdn-javascript_builtins_uint8array_frombase64\n// prettier-ignore\nconst hasBase64Builtin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toBase64 === 'function' &&\n typeof Uint8Array.fromBase64 === 'function')();\nconst decodeBase64Builtin = (s, isUrl) => {\n astr('base64', s);\n const re = isUrl ? /^[A-Za-z0-9=_-]+$/ : /^[A-Za-z0-9=+/]+$/;\n const alphabet = isUrl ? 'base64url' : 'base64';\n if (s.length > 0 && !re.test(s))\n throw new Error('invalid base64');\n return Uint8Array.fromBase64(s, { alphabet, lastChunkHandling: 'strict' });\n};\n/**\n * base64 from RFC 4648. Padded.\n * Use `base64nopad` for unpadded version.\n * Also check out `base64url`, `base64urlnopad`.\n * Falls back to built-in function, when available.\n * @example\n * ```js\n * base64.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs='\n * base64.decode('Eqs=');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\n// prettier-ignore\nexport const base64 = hasBase64Builtin ? {\n encode(b) { abytes(b); return b.toBase64(); },\n decode(s) { return decodeBase64Builtin(s, false); },\n} : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));\n/**\n * base64 from RFC 4648. No padding.\n * Use `base64` for padded version.\n * @example\n * ```js\n * base64nopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs'\n * base64nopad.decode('Eqs');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base64nopad = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), join(''));\n/**\n * base64 from RFC 4648, using URL-safe alphabet. Padded.\n * Use `base64urlnopad` for unpadded version.\n * Falls back to built-in function, when available.\n * @example\n * ```js\n * base64url.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs='\n * base64url.decode('Eqs=');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\n// prettier-ignore\nexport const base64url = hasBase64Builtin ? {\n encode(b) { abytes(b); return b.toBase64({ alphabet: 'base64url' }); },\n decode(s) { return decodeBase64Builtin(s, true); },\n} : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));\n/**\n * base64 from RFC 4648, using URL-safe alphabet. No padding.\n * Use `base64url` for padded version.\n * @example\n * ```js\n * base64urlnopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs'\n * base64urlnopad.decode('Eqs');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base64urlnopad = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), join(''));\n// base58 code\n// -----------\nconst genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => chain(radix(58), alphabet(abc), join(''));\n/**\n * base58: base64 without ambigous characters +, /, 0, O, I, l.\n * Quadratic (O(n^2)) - so, can't be used on large inputs.\n * @example\n * ```js\n * base58.decode('01abcdef');\n * // => '3UhJW'\n * ```\n */\nexport const base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');\n/**\n * base58: flickr version. Check out `base58`.\n */\nexport const base58flickr = genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');\n/**\n * base58: XRP version. Check out `base58`.\n */\nexport const base58xrp = genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');\n// Data len (index) -> encoded block len\nconst XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];\n/**\n * base58: XMR version. Check out `base58`.\n * Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.\n * Block encoding significantly reduces quadratic complexity of base58.\n */\nexport const base58xmr = {\n encode(data) {\n let res = '';\n for (let i = 0; i < data.length; i += 8) {\n const block = data.subarray(i, i + 8);\n res += base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');\n }\n return res;\n },\n decode(str) {\n let res = [];\n for (let i = 0; i < str.length; i += 11) {\n const slice = str.slice(i, i + 11);\n const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);\n const block = base58.decode(slice);\n for (let j = 0; j < block.length - blockLen; j++) {\n if (block[j] !== 0)\n throw new Error('base58xmr: wrong padding');\n }\n res = res.concat(Array.from(block.slice(block.length - blockLen)));\n }\n return Uint8Array.from(res);\n },\n};\n/**\n * Method, which creates base58check encoder.\n * Requires function, calculating sha256.\n */\nexport const createBase58check = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), base58);\n/**\n * Use `createBase58check` instead.\n * @deprecated\n */\nexport const base58check = createBase58check;\nconst BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));\nconst POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];\nfunction bech32Polymod(pre) {\n const b = pre >> 25;\n let chk = (pre & 0x1ffffff) << 5;\n for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {\n if (((b >> i) & 1) === 1)\n chk ^= POLYMOD_GENERATORS[i];\n }\n return chk;\n}\nfunction bechChecksum(prefix, words, encodingConst = 1) {\n const len = prefix.length;\n let chk = 1;\n for (let i = 0; i < len; i++) {\n const c = prefix.charCodeAt(i);\n if (c < 33 || c > 126)\n throw new Error(`Invalid prefix (${prefix})`);\n chk = bech32Polymod(chk) ^ (c >> 5);\n }\n chk = bech32Polymod(chk);\n for (let i = 0; i < len; i++)\n chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);\n for (let v of words)\n chk = bech32Polymod(chk) ^ v;\n for (let i = 0; i < 6; i++)\n chk = bech32Polymod(chk);\n chk ^= encodingConst;\n return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]], 30, 5, false));\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction genBech32(encoding) {\n const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;\n const _words = radix2(5);\n const fromWords = _words.decode;\n const toWords = _words.encode;\n const fromWordsUnsafe = unsafeWrapper(fromWords);\n function encode(prefix, words, limit = 90) {\n astr('bech32.encode prefix', prefix);\n if (isBytes(words))\n words = Array.from(words);\n anumArr('bech32.encode', words);\n const plen = prefix.length;\n if (plen === 0)\n throw new TypeError(`Invalid prefix length ${plen}`);\n const actualLength = plen + 7 + words.length;\n if (limit !== false && actualLength > limit)\n throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);\n const lowered = prefix.toLowerCase();\n const sum = bechChecksum(lowered, words, ENCODING_CONST);\n return `${lowered}1${BECH_ALPHABET.encode(words)}${sum}`;\n }\n function decode(str, limit = 90) {\n astr('bech32.decode input', str);\n const slen = str.length;\n if (slen < 8 || (limit !== false && slen > limit))\n throw new TypeError(`invalid string length: ${slen} (${str}). Expected (8..${limit})`);\n // don't allow mixed case\n const lowered = str.toLowerCase();\n if (str !== lowered && str !== str.toUpperCase())\n throw new Error(`String must be lowercase or uppercase`);\n const sepIndex = lowered.lastIndexOf('1');\n if (sepIndex === 0 || sepIndex === -1)\n throw new Error(`Letter \"1\" must be present between prefix and data only`);\n const prefix = lowered.slice(0, sepIndex);\n const data = lowered.slice(sepIndex + 1);\n if (data.length < 6)\n throw new Error('Data must be at least 6 characters long');\n const words = BECH_ALPHABET.decode(data).slice(0, -6);\n const sum = bechChecksum(prefix, words, ENCODING_CONST);\n if (!data.endsWith(sum))\n throw new Error(`Invalid checksum in ${str}: expected \"${sum}\"`);\n return { prefix, words };\n }\n const decodeUnsafe = unsafeWrapper(decode);\n function decodeToBytes(str) {\n const { prefix, words } = decode(str, false);\n return { prefix, words, bytes: fromWords(words) };\n }\n function encodeFromBytes(prefix, bytes) {\n return encode(prefix, toWords(bytes));\n }\n return {\n encode,\n decode,\n encodeFromBytes,\n decodeToBytes,\n decodeUnsafe,\n fromWords,\n fromWordsUnsafe,\n toWords,\n };\n}\n/**\n * bech32 from BIP 173. Operates on words.\n * For high-level, check out scure-btc-signer:\n * https://github.com/paulmillr/scure-btc-signer.\n */\nexport const bech32 = genBech32('bech32');\n/**\n * bech32m from BIP 350. Operates on words.\n * It was to mitigate `bech32` weaknesses.\n * For high-level, check out scure-btc-signer:\n * https://github.com/paulmillr/scure-btc-signer.\n */\nexport const bech32m = genBech32('bech32m');\n/**\n * UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.\n * @example\n * ```js\n * const b = utf8.decode(\"hey\"); // => new Uint8Array([ 104, 101, 121 ])\n * const str = utf8.encode(b); // \"hey\"\n * ```\n */\nexport const utf8 = {\n encode: (data) => new TextDecoder().decode(data),\n decode: (str) => new TextEncoder().encode(str),\n};\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\n// prettier-ignore\nconst hasHexBuiltin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toHex === 'function' &&\n typeof Uint8Array.fromHex === 'function')();\n// prettier-ignore\nconst hexBuiltin = {\n encode(data) { abytes(data); return data.toHex(); },\n decode(s) { astr('hex', s); return Uint8Array.fromHex(s); },\n};\n/**\n * hex string decoder. Uses built-in function, when available.\n * @example\n * ```js\n * const b = hex.decode(\"0102ff\"); // => new Uint8Array([ 1, 2, 255 ])\n * const str = hex.encode(b); // \"0102ff\"\n * ```\n */\nexport const hex = hasHexBuiltin\n ? hexBuiltin\n : chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {\n if (typeof s !== 'string' || s.length % 2 !== 0)\n throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);\n return s.toLowerCase();\n }));\n// prettier-ignore\nconst CODERS = {\n utf8, hex, base16, base32, base64, base64url, base58, base58xmr\n};\nconst coderTypeError = 'Invalid encoding type. Available types: utf8, hex, base16, base32, base64, base64url, base58, base58xmr';\n/** @deprecated */\nexport const bytesToString = (type, bytes) => {\n if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))\n throw new TypeError(coderTypeError);\n if (!isBytes(bytes))\n throw new TypeError('bytesToString() expects Uint8Array');\n return CODERS[type].encode(bytes);\n};\n/** @deprecated */\nexport const str = bytesToString; // as in python, but for bytes only\n/** @deprecated */\nexport const stringToBytes = (type, str) => {\n if (!CODERS.hasOwnProperty(type))\n throw new TypeError(coderTypeError);\n if (typeof str !== 'string')\n throw new TypeError('stringToBytes() expects string');\n return CODERS[type].decode(str);\n};\n/** @deprecated */\nexport const bytes = stringToBytes;\n//# sourceMappingURL=index.js.map",
|
|
7
|
-
"const hexes = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, \"0\"));\n\nexport function bytesToHex(bytes: Uint8Array): string {\n let hex = \"\";\n for (const b of bytes) {\n hex += hexes[b];\n }\n return hex;\n}\n\nexport function hexToBytes(hex: string): Uint8Array {\n hex = without0x(hex);\n if (hex.length % 2) hex = `0${hex}`;\n\n const array = new Uint8Array(hex.length / 2);\n for (let i = 0; i < array.length; i++) {\n const j = i * 2;\n const byte = Number.parseInt(hex.slice(j, j + 2), 16);\n if (Number.isNaN(byte) || byte < 0) throw new Error(\"Invalid byte sequence\");\n array[i] = byte;\n }\n return array;\n}\n\nexport function with0x(value: string): string {\n return /^0x/i.test(value) ? value : `0x${value}`;\n}\n\nexport function without0x(value: string): string {\n return /^0x/i.test(value) ? value.slice(2) : value;\n}\n\nexport function utf8ToBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\nexport function bytesToUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\nexport function asciiToBytes(str: string): Uint8Array {\n const bytes = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n bytes[i] = str.charCodeAt(i) & 0xff;\n }\n return bytes;\n}\n\nexport function bytesToAscii(bytes: Uint8Array): string {\n return String.fromCharCode(...bytes);\n}\n\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n if (arrays.length === 1) return arrays[0]!;\n const length = arrays.reduce((a, arr) => a + arr.length, 0);\n const result = new Uint8Array(length);\n let pad = 0;\n for (const arr of arrays) {\n result.set(arr, pad);\n pad += arr.length;\n }\n return result;\n}\n\nexport type IntegerType = number | string | bigint | Uint8Array;\n\nexport function intToBigInt(value: IntegerType): bigint {\n if (typeof value === \"bigint\") return value;\n if (typeof value === \"string\") return BigInt(value);\n if (typeof value === \"number\") {\n if (!Number.isInteger(value))\n throw new RangeError(\"Values of type 'number' must be an integer.\");\n if (value > Number.MAX_SAFE_INTEGER)\n throw new RangeError(\n `Values of type 'number' must be <= ${Number.MAX_SAFE_INTEGER}. Use BigInt instead.`\n );\n return BigInt(value);\n }\n if (value instanceof Uint8Array) return BigInt(`0x${bytesToHex(value)}`);\n throw new TypeError(\"Must be a number, bigint, string, or Uint8Array.\");\n}\n\nexport function intToBytes(value: IntegerType, byteLength: number): Uint8Array {\n return bigIntToBytes(intToBigInt(value), byteLength);\n}\n\nexport function bigIntToBytes(value: bigint, length: number = 16): Uint8Array {\n const hex = value.toString(16).padStart(length * 2, \"0\");\n return hexToBytes(hex);\n}\n\nexport function intToHex(integer: IntegerType, byteLength = 8): string {\n const value = typeof integer === \"bigint\" ? integer : intToBigInt(integer);\n return value.toString(16).padStart(byteLength * 2, \"0\");\n}\n\nexport function toTwos(value: bigint, width: bigint): bigint {\n const limit = BigInt(1) << (width - BigInt(1));\n if (value < -limit || value > limit - BigInt(1)) {\n throw new Error(`Unable to represent integer in width: ${width}`);\n }\n if (value >= BigInt(0)) return value;\n return value + (BigInt(1) << width);\n}\n\nexport function fromTwos(value: bigint, width: bigint): bigint {\n if (value & (BigInt(1) << (width - BigInt(1)))) {\n return value - (BigInt(1) << width);\n }\n return value;\n}\n\nexport function bytesToTwosBigInt(bytes: Uint8Array): bigint {\n return fromTwos(BigInt(`0x${
|
|
7
|
+
"const hexes = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, \"0\"));\n\nexport function bytesToHex(bytes: Uint8Array): string {\n let hex = \"\";\n for (const b of bytes) {\n hex += hexes[b];\n }\n return hex;\n}\n\nexport function hexToBytes(hex: string): Uint8Array {\n hex = without0x(hex);\n if (hex.length % 2) hex = `0${hex}`;\n\n const array = new Uint8Array(hex.length / 2);\n for (let i = 0; i < array.length; i++) {\n const j = i * 2;\n const byte = Number.parseInt(hex.slice(j, j + 2), 16);\n if (Number.isNaN(byte) || byte < 0) throw new Error(\"Invalid byte sequence\");\n array[i] = byte;\n }\n return array;\n}\n\nexport function with0x(value: string): string {\n return /^0x/i.test(value) ? value : `0x${value}`;\n}\n\nexport function without0x(value: string): string {\n return /^0x/i.test(value) ? value.slice(2) : value;\n}\n\nexport function utf8ToBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\nexport function bytesToUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\nexport function asciiToBytes(str: string): Uint8Array {\n const bytes = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n bytes[i] = str.charCodeAt(i) & 0xff;\n }\n return bytes;\n}\n\nexport function bytesToAscii(bytes: Uint8Array): string {\n return String.fromCharCode(...bytes);\n}\n\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n if (arrays.length === 1) return arrays[0]!;\n const length = arrays.reduce((a, arr) => a + arr.length, 0);\n const result = new Uint8Array(length);\n let pad = 0;\n for (const arr of arrays) {\n result.set(arr, pad);\n pad += arr.length;\n }\n return result;\n}\n\nexport type IntegerType = number | string | bigint | Uint8Array;\n\nexport function intToBigInt(value: IntegerType): bigint {\n if (typeof value === \"bigint\") return value;\n if (typeof value === \"string\") return BigInt(value);\n if (typeof value === \"number\") {\n if (!Number.isInteger(value))\n throw new RangeError(\"Values of type 'number' must be an integer.\");\n if (value > Number.MAX_SAFE_INTEGER)\n throw new RangeError(\n `Values of type 'number' must be <= ${Number.MAX_SAFE_INTEGER}. Use BigInt instead.`\n );\n return BigInt(value);\n }\n if (value instanceof Uint8Array) return BigInt(`0x${bytesToHex(value)}`);\n throw new TypeError(\"Must be a number, bigint, string, or Uint8Array.\");\n}\n\nexport function intToBytes(value: IntegerType, byteLength: number): Uint8Array {\n return bigIntToBytes(intToBigInt(value), byteLength);\n}\n\nexport function bigIntToBytes(value: bigint, length: number = 16): Uint8Array {\n const hex = value.toString(16).padStart(length * 2, \"0\");\n return hexToBytes(hex);\n}\n\nexport function intToHex(integer: IntegerType, byteLength = 8): string {\n const value = typeof integer === \"bigint\" ? integer : intToBigInt(integer);\n return value.toString(16).padStart(byteLength * 2, \"0\");\n}\n\nexport function toTwos(value: bigint, width: bigint): bigint {\n const limit = BigInt(1) << (width - BigInt(1));\n if (value < -limit || value > limit - BigInt(1)) {\n throw new Error(`Unable to represent integer in width: ${width}`);\n }\n if (value >= BigInt(0)) return value;\n return value + (BigInt(1) << width);\n}\n\nexport function fromTwos(value: bigint, width: bigint): bigint {\n if (value & (BigInt(1) << (width - BigInt(1)))) {\n return value - (BigInt(1) << width);\n }\n return value;\n}\n\nexport function bytesToTwosBigInt(bytes: Uint8Array): bigint {\n if (bytes.length === 0) return 0n;\n const hex = bytesToHex(bytes);\n if (hex.length === 0) return 0n;\n return fromTwos(BigInt(`0x${hex}`), BigInt(bytes.byteLength * 8));\n}\n\nexport function writeUInt32BE(value: number): Uint8Array {\n const buf = new Uint8Array(4);\n buf[0] = (value >>> 24) & 0xff;\n buf[1] = (value >>> 16) & 0xff;\n buf[2] = (value >>> 8) & 0xff;\n buf[3] = value & 0xff;\n return buf;\n}\n\nexport function readUInt32BE(bytes: Uint8Array, offset = 0): number {\n return (\n ((bytes[offset]! << 24) |\n (bytes[offset + 1]! << 16) |\n (bytes[offset + 2]! << 8) |\n bytes[offset + 3]!) >>>\n 0\n );\n}\n\nexport function writeUInt16BE(value: number): Uint8Array {\n const buf = new Uint8Array(2);\n buf[0] = (value >>> 8) & 0xff;\n buf[1] = value & 0xff;\n return buf;\n}\n\nexport function readUInt16BE(bytes: Uint8Array, offset = 0): number {\n return ((bytes[offset]! << 8) | bytes[offset + 1]!) >>> 0;\n}\n\nexport function writeUInt8(value: number): Uint8Array {\n return new Uint8Array([value & 0xff]);\n}\n",
|
|
8
8
|
"/** WalletConnect v2 relay client (wss://relay.walletconnect.com) */\n\nimport type { WcRelayMessage } from \"./types.ts\";\nimport {\n encryptType0,\n encodeBase64,\n createRelayAuthJwt,\n} from \"./crypto.ts\";\n\nconst DEFAULT_RELAY = \"wss://relay.walletconnect.com\";\nconst DEFAULT_TTL = 300; // 5 minutes\n\ntype PendingRpc = {\n resolve: (v: unknown) => void;\n reject: (e: Error) => void;\n};\n\ntype SubscriptionHandler = (message: WcRelayMessage) => void;\n\nexport class WcRelay {\n private ws: WebSocket | null = null;\n private url: string;\n private projectId: string;\n private nextId = Date.now() * 1000 + Math.floor(Math.random() * 1000);\n private pending = new Map<number, PendingRpc>();\n private subscriptions = new Map<string, SubscriptionHandler>();\n /** Map subscription ID (from server) → topic */\n private subIdToTopic = new Map<string, string>();\n private destroyed = false;\n private reconnecting = false;\n private reconnectAttempt = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private connectPromise: Promise<void> | null = null;\n private connectReject: ((e: Error) => void) | null = null;\n\n constructor(projectId: string, relayUrl?: string) {\n this.projectId = projectId;\n this.url = relayUrl ?? DEFAULT_RELAY;\n }\n\n // -- Connection --\n\n async connect(): Promise<void> {\n if (this.ws?.readyState === WebSocket.OPEN) return;\n if (this.connectPromise) return this.connectPromise;\n\n this.connectPromise = new Promise<void>((resolve, reject) => {\n this.connectReject = reject;\n const { jwt } = createRelayAuthJwt(this.url);\n const wsUrl = `${this.url}/?auth=${jwt}&projectId=${this.projectId}`;\n this.ws = new WebSocket(wsUrl);\n\n this.ws.addEventListener(\n \"open\",\n () => {\n this.reconnectAttempt = 0;\n this.reconnecting = false;\n this.connectPromise = null;\n this.connectReject = null;\n resolve();\n },\n { once: true },\n );\n\n this.ws.addEventListener(\n \"error\",\n (e) => {\n this.connectPromise = null;\n this.connectReject = null;\n reject(new Error(`WC relay connection failed: ${e}`));\n },\n { once: true },\n );\n\n this.ws.addEventListener(\"message\", (event) => {\n this.handleMessage(\n typeof event.data === \"string\"\n ? event.data\n : new TextDecoder().decode(event.data as ArrayBuffer),\n );\n });\n\n this.ws.addEventListener(\"close\", () => {\n this.connectPromise = null;\n if (!this.destroyed) this.handleDisconnect();\n });\n });\n\n return this.connectPromise;\n }\n\n // -- Publish/Subscribe --\n\n async subscribe(\n topic: string,\n handler: SubscriptionHandler,\n ): Promise<string> {\n await this.connect();\n this.subscriptions.set(topic, handler);\n const subId = (await this.rpc(\"irn_subscribe\", { topic })) as string;\n this.subIdToTopic.set(subId, topic);\n return subId;\n }\n\n async publish(\n topic: string,\n message: string,\n tag: number,\n ttl: number = DEFAULT_TTL,\n ): Promise<void> {\n await this.connect();\n await this.rpc(\"irn_publish\", {\n topic,\n message,\n ttl,\n tag,\n prompt: false,\n });\n }\n\n /** Encrypt + publish a type-0 envelope */\n async publishEncrypted(\n topic: string,\n symKey: Uint8Array,\n payload: unknown,\n tag: number,\n ttl: number = DEFAULT_TTL,\n ): Promise<void> {\n const plaintext = JSON.stringify(payload);\n const envelope = encryptType0(symKey, plaintext);\n await this.publish(topic, encodeBase64(envelope), tag, ttl);\n }\n\n // -- Internal --\n\n private rpc(method: string, params: Record<string, unknown>): Promise<unknown> {\n return new Promise((resolve, reject) => {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n return reject(new Error(\"WC relay not connected\"));\n }\n const id = this.nextId++;\n this.pending.set(id, { resolve, reject });\n this.ws.send(JSON.stringify({ id, jsonrpc: \"2.0\", method, params }));\n });\n }\n\n private handleMessage(raw: string) {\n let msg: any;\n try {\n msg = JSON.parse(raw);\n } catch {\n return;\n }\n\n // RPC response\n if (\"id\" in msg && msg.id != null && this.pending.has(msg.id)) {\n const p = this.pending.get(msg.id)!;\n this.pending.delete(msg.id);\n if (msg.error) {\n p.reject(new Error(`WC relay error: ${msg.error.message}`));\n } else {\n p.resolve(msg.result);\n }\n return;\n }\n\n // Server push (irn_subscription)\n if (msg.method === \"irn_subscription\" && msg.params) {\n const { id: subId, data } = msg.params;\n const topic = data?.topic ?? this.subIdToTopic.get(subId);\n const handler = topic ? this.subscriptions.get(topic) : undefined;\n if (handler && data) {\n handler({\n topic: data.topic,\n message: data.message,\n publishedAt: data.publishedAt ?? Date.now(),\n tag: data.tag ?? 0,\n });\n }\n // Acknowledge\n if (msg.id != null) {\n this.ws?.send(\n JSON.stringify({ id: msg.id, jsonrpc: \"2.0\", result: true }),\n );\n }\n }\n }\n\n private handleDisconnect() {\n this.ws = null;\n for (const [, p] of this.pending) {\n p.reject(new Error(\"WC relay disconnected\"));\n }\n this.pending.clear();\n\n if (this.subscriptions.size > 0 && this.reconnectAttempt < 5) {\n this.scheduleReconnect();\n }\n }\n\n private scheduleReconnect() {\n if (this.destroyed || this.reconnecting) return;\n this.reconnecting = true;\n const delay = 1000 * 2 ** this.reconnectAttempt;\n this.reconnectAttempt++;\n\n this.reconnectTimer = setTimeout(async () => {\n this.reconnecting = false;\n try {\n await this.connect();\n // Re-subscribe all topics\n for (const [topic] of this.subscriptions) {\n const subId = (await this.rpc(\"irn_subscribe\", { topic })) as string;\n this.subIdToTopic.set(subId, topic);\n }\n } catch {\n if (!this.destroyed && this.subscriptions.size > 0) {\n this.handleDisconnect();\n }\n }\n }, delay);\n }\n\n destroy(): void {\n this.destroyed = true;\n if (this.reconnectTimer) clearTimeout(this.reconnectTimer);\n if (this.connectReject) {\n this.connectReject(new Error(\"WC relay destroyed\"));\n this.connectReject = null;\n this.connectPromise = null;\n }\n for (const [, p] of this.pending) {\n p.reject(new Error(\"WC relay destroyed\"));\n }\n this.pending.clear();\n this.subscriptions.clear();\n this.subIdToTopic.clear();\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n }\n}\n",
|
|
9
9
|
"/** WalletConnect v2 session state machine (pairing → proposal → settlement) */\n\nimport type {\n WcProviderConfig,\n WcPairResult,\n WcSessionSettled,\n WcSessionData,\n WcJsonRpc,\n WcProposal,\n} from \"./types.ts\";\nimport {\n generateKeyPair,\n generateSymKey,\n deriveSymKey,\n symKeyToTopic,\n decryptType0,\n decryptType1,\n decodeBase64,\n bytesToHex,\n hexToBytes,\n} from \"./crypto.ts\";\nimport { WcRelay } from \"./relay.ts\";\n\nconst STORAGE_KEY = \"@secondlayer/wc:session\";\nconst SESSION_EXPIRY = 7 * 24 * 60 * 60; // 7 days in seconds\n\nconst STACKS_METHODS = [\n \"stx_getAddresses\",\n \"stx_transferStx\",\n \"stx_callContract\",\n \"stx_deployContract\",\n \"stx_signMessage\",\n \"stx_signTransaction\",\n];\n\nconst STACKS_EVENTS = [\"chainChanged\", \"accountsChanged\"];\n\ndeclare const localStorage:\n | {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n }\n | undefined;\n\nfunction getStorage() {\n return typeof localStorage !== \"undefined\" ? localStorage : undefined;\n}\n\nexport class WcSession {\n private relay: WcRelay;\n private config: WcProviderConfig;\n private chains: string[];\n\n // Pairing state\n private pairingSymKey: Uint8Array | null = null;\n private pairingTopic: string | null = null;\n private selfKeyPair: { privateKey: Uint8Array; publicKey: Uint8Array } | null = null;\n\n // Session state\n private sessionData: WcSessionData | null = null;\n private sessionSymKey: Uint8Array | null = null;\n private pending = new Map<\n number,\n { resolve: (v: unknown) => void; reject: (e: Error) => void }\n >();\n private nextId = Date.now();\n\n constructor(config: WcProviderConfig) {\n this.config = config;\n this.chains = config.chains ?? [\"stacks:1\"];\n this.relay = new WcRelay(config.projectId, config.relayUrl);\n }\n\n /** Try restoring a persisted session. Returns true if valid session found. */\n restore(): boolean {\n try {\n const raw = getStorage()?.getItem(STORAGE_KEY);\n if (!raw) return false;\n const data = JSON.parse(raw) as WcSessionData;\n if (data.expiry < Date.now() / 1000) {\n getStorage()?.removeItem(STORAGE_KEY);\n return false;\n }\n this.sessionData = data;\n this.sessionSymKey = hexToBytes(data.symKey);\n // Subscribe to session topic for incoming requests (fire-and-forget)\n this.subscribeSession().catch(() => {});\n return true;\n } catch {\n return false;\n }\n }\n\n /** Initiate pairing. Returns URI for QR code + approval promise. */\n async pair(): Promise<WcPairResult> {\n this.pairingSymKey = generateSymKey();\n this.pairingTopic = symKeyToTopic(this.pairingSymKey);\n this.selfKeyPair = generateKeyPair();\n\n const symKeyHex = bytesToHex(this.pairingSymKey);\n const uri = `wc:${this.pairingTopic}@2?relay-protocol=irn&symKey=${symKeyHex}`;\n\n const approval = new Promise<WcSessionSettled>((resolve, reject) => {\n this.relay\n .subscribe(this.pairingTopic!, (msg) => {\n try {\n this.handlePairingMessage(msg.message, resolve, reject);\n } catch (err) {\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n })\n .catch(reject);\n });\n\n return { uri, approval };\n }\n\n /** Send a JSON-RPC request over the session. */\n async request(method: string, params?: unknown): Promise<unknown> {\n if (!this.sessionData || !this.sessionSymKey) {\n throw new Error(\"No active WC session\");\n }\n\n const id = this.nextId++;\n const payload = {\n id,\n jsonrpc: \"2.0\" as const,\n method: \"wc_sessionRequest\",\n params: {\n request: { method, params },\n chainId: this.chains[0],\n },\n };\n\n return new Promise((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n this.relay\n .publishEncrypted(\n this.sessionData!.topic,\n this.sessionSymKey!,\n payload,\n 1108, // tag for session request\n SESSION_EXPIRY,\n )\n .catch((err) => {\n this.pending.delete(id);\n reject(err);\n });\n });\n }\n\n disconnect(): void {\n if (this.sessionData && this.sessionSymKey) {\n const id = this.nextId++;\n const payload = {\n id,\n jsonrpc: \"2.0\",\n method: \"wc_sessionDelete\",\n params: { code: 6000, message: \"User disconnected\" },\n };\n // Best-effort notify peer\n this.relay\n .publishEncrypted(\n this.sessionData.topic,\n this.sessionSymKey,\n payload,\n 1112,\n )\n .catch(() => {});\n }\n this.sessionData = null;\n this.sessionSymKey = null;\n this.pending.clear();\n getStorage()?.removeItem(STORAGE_KEY);\n this.relay.destroy();\n }\n\n get session(): WcSessionData | null {\n return this.sessionData;\n }\n\n // -- Internal --\n\n private handlePairingMessage(\n message: string,\n resolve: (v: WcSessionSettled) => void,\n reject: (e: Error) => void,\n ) {\n const envelope = decodeBase64(message);\n let plaintext: string;\n\n // Could be type 0 (symmetric) or type 1 (asymmetric)\n if (envelope[0] === 0x01 && this.selfKeyPair) {\n plaintext = decryptType1(this.selfKeyPair.privateKey, envelope);\n } else if (this.pairingSymKey) {\n plaintext = decryptType0(this.pairingSymKey, envelope);\n } else {\n return;\n }\n\n let rpc: WcJsonRpc;\n try {\n rpc = JSON.parse(plaintext) as WcJsonRpc;\n } catch {\n return;\n }\n\n if (rpc.method === \"wc_sessionPropose\") {\n this.handleProposal(rpc as WcJsonRpc<WcProposal>, resolve, reject).catch(reject);\n }\n }\n\n private async handleProposal(\n rpc: WcJsonRpc<WcProposal>,\n resolve: (v: WcSessionSettled) => void,\n reject: (e: Error) => void,\n ) {\n try {\n const proposal = rpc.params;\n const peerPublicKey = hexToBytes(proposal.proposer.publicKey);\n\n // Generate session key pair + derive session symmetric key\n const sessionKp = generateKeyPair();\n const sessionSymKey = deriveSymKey(sessionKp.privateKey, peerPublicKey);\n const sessionTopic = symKeyToTopic(sessionSymKey);\n\n const expiry = Math.floor(Date.now() / 1000) + SESSION_EXPIRY;\n\n const settled: WcSessionSettled = {\n relay: { protocol: \"irn\" },\n namespaces: {\n stacks: {\n chains: this.chains,\n methods: STACKS_METHODS,\n events: STACKS_EVENTS,\n accounts: this.chains.map((c) => `${c}:placeholder`),\n },\n },\n controller: {\n publicKey: bytesToHex(sessionKp.publicKey),\n metadata: this.config.metadata,\n },\n expiry,\n };\n\n // Approve the proposal on the pairing topic\n const approvePayload = {\n id: rpc.id,\n jsonrpc: \"2.0\",\n result: {\n relay: { protocol: \"irn\" },\n responderPublicKey: bytesToHex(sessionKp.publicKey),\n },\n };\n\n await this.relay.publishEncrypted(\n this.pairingTopic!,\n this.pairingSymKey!,\n approvePayload,\n 1101, // tag for session propose response\n );\n\n // Subscribe to session topic\n this.sessionSymKey = sessionSymKey;\n this.sessionData = {\n topic: sessionTopic,\n symKey: bytesToHex(sessionSymKey),\n peerMeta: proposal.proposer.metadata,\n expiry,\n accounts: [],\n controllerPublicKey: proposal.proposer.publicKey,\n };\n\n await this.subscribeSession();\n\n // Send session settle on the new session topic\n const settlePayload = {\n id: this.nextId++,\n jsonrpc: \"2.0\",\n method: \"wc_sessionSettle\",\n params: settled,\n };\n\n await this.relay.publishEncrypted(\n sessionTopic,\n sessionSymKey,\n settlePayload,\n 1104, // tag for session settle\n );\n\n // Persist\n getStorage()?.setItem(STORAGE_KEY, JSON.stringify(this.sessionData));\n\n resolve(settled);\n } catch (err) {\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n private async subscribeSession() {\n if (!this.sessionData || !this.sessionSymKey) return;\n\n const symKey = this.sessionSymKey;\n await this.relay.subscribe(this.sessionData.topic, (msg) => {\n try {\n const envelope = decodeBase64(msg.message);\n const plaintext = decryptType0(symKey, envelope);\n const rpc = JSON.parse(plaintext);\n\n // Response to our request\n if (\"id\" in rpc && this.pending.has(rpc.id)) {\n const p = this.pending.get(rpc.id)!;\n this.pending.delete(rpc.id);\n if (rpc.error) {\n p.reject(new Error(rpc.error.message ?? \"WC request failed\"));\n } else {\n p.resolve(rpc.result);\n }\n }\n\n // Session delete from peer\n if (rpc.method === \"wc_sessionDelete\") {\n this.sessionData = null;\n this.sessionSymKey = null;\n this.pending.clear();\n getStorage()?.removeItem(STORAGE_KEY);\n }\n } catch {\n // ignore malformed messages\n }\n });\n }\n}\n",
|
|
10
10
|
"/** WalletProvider adapter for WalletConnect v2 */\n\nimport type { WalletProvider } from \"../types.ts\";\nimport type { WcProviderConfig, WcPairResult, WcSessionData } from \"./types.ts\";\nimport { WcSession } from \"./session.ts\";\n\nexport class WalletConnectProvider implements WalletProvider {\n private session: WcSession;\n\n constructor(config: WcProviderConfig) {\n this.session = new WcSession(config);\n }\n\n /** Try restoring a persisted session. Returns true if valid. */\n restore(): boolean {\n return this.session.restore();\n }\n\n /** Initiate pairing. Returns URI for QR + approval promise. */\n async pair(): Promise<WcPairResult> {\n return this.session.pair();\n }\n\n async request(method: string, params?: any): Promise<any> {\n return this.session.request(method, params);\n }\n\n disconnect(): void {\n this.session.disconnect();\n }\n\n get sessionData(): WcSessionData | null {\n return this.session.session;\n }\n}\n",
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"/** WalletConnect v2 envelope encryption (Type 0 + Type 1) + relay JWT auth */\n\nimport { ed25519, x25519 } from \"@noble/curves/ed25519.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { hkdf } from \"@noble/hashes/hkdf.js\";\nimport { randomBytes } from \"@noble/hashes/utils.js\";\nimport { gcm } from \"@noble/ciphers/aes.js\";\nimport { base58, base64urlnopad } from \"@scure/base\";\nimport { bytesToHex, hexToBytes } from \"../../utils/encoding.ts\";\n\nconst IV_LENGTH = 12;\nconst KEY_LENGTH = 32;\nconst TYPE_0 = 0x00;\nconst TYPE_1 = 0x01;\n\n// -- Key generation --\n\nexport function generateKeyPair() {\n const privateKey = randomBytes(KEY_LENGTH);\n const publicKey = x25519.getPublicKey(privateKey);\n return { privateKey, publicKey };\n}\n\nexport function generateSymKey(): Uint8Array {\n return randomBytes(KEY_LENGTH);\n}\n\n/** Derive symmetric key from X25519 shared secret via HKDF */\nexport function deriveSymKey(\n selfPrivate: Uint8Array,\n peerPublic: Uint8Array,\n): Uint8Array {\n const shared = x25519.getSharedSecret(selfPrivate, peerPublic);\n return hkdf(sha256, shared, undefined, undefined, KEY_LENGTH);\n}\n\n/** Topic = first 32 bytes of SHA-256(symKey) as hex */\nexport function symKeyToTopic(symKey: Uint8Array): string {\n return bytesToHex(sha256(symKey));\n}\n\n// -- Base64 helpers (browser-safe) --\n\nexport function encodeBase64(data: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < data.length; i++) binary += String.fromCharCode(data[i]!);\n return btoa(binary);\n}\n\nexport function decodeBase64(str: string): Uint8Array {\n const binary = atob(str);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n}\n\n// -- Type 0 envelope (symmetric, pairing) --\n// Layout: [0x00][12-byte IV][ciphertext + 16-byte tag]\n\nexport function encryptType0(\n symKey: Uint8Array,\n plaintext: string,\n): Uint8Array {\n const iv = randomBytes(IV_LENGTH);\n const data = new TextEncoder().encode(plaintext);\n const cipher = gcm(symKey, iv);\n const sealed = cipher.encrypt(data);\n const envelope = new Uint8Array(1 + IV_LENGTH + sealed.length);\n envelope[0] = TYPE_0;\n envelope.set(iv, 1);\n envelope.set(sealed, 1 + IV_LENGTH);\n return envelope;\n}\n\nexport function decryptType0(\n symKey: Uint8Array,\n envelope: Uint8Array,\n): string {\n if (envelope[0] !== TYPE_0) throw new Error(\"Not a type-0 envelope\");\n const iv = envelope.subarray(1, 1 + IV_LENGTH);\n const sealed = envelope.subarray(1 + IV_LENGTH);\n const cipher = gcm(symKey, iv);\n const plain = cipher.decrypt(sealed);\n return new TextDecoder().decode(plain);\n}\n\n// -- Type 1 envelope (asymmetric, session proposal) --\n// Layout: [0x01][32-byte sender pubkey][12-byte IV][ciphertext + 16-byte tag]\n\nexport function encryptType1(\n senderPrivate: Uint8Array,\n receiverPublic: Uint8Array,\n plaintext: string,\n): Uint8Array {\n const senderPublic = x25519.getPublicKey(senderPrivate);\n const symKey = deriveSymKey(senderPrivate, receiverPublic);\n const iv = randomBytes(IV_LENGTH);\n const data = new TextEncoder().encode(plaintext);\n const cipher = gcm(symKey, iv);\n const sealed = cipher.encrypt(data);\n const envelope = new Uint8Array(1 + KEY_LENGTH + IV_LENGTH + sealed.length);\n envelope[0] = TYPE_1;\n envelope.set(senderPublic, 1);\n envelope.set(iv, 1 + KEY_LENGTH);\n envelope.set(sealed, 1 + KEY_LENGTH + IV_LENGTH);\n return envelope;\n}\n\nexport function decryptType1(\n receiverPrivate: Uint8Array,\n envelope: Uint8Array,\n): string {\n if (envelope[0] !== TYPE_1) throw new Error(\"Not a type-1 envelope\");\n const senderPublic = envelope.subarray(1, 1 + KEY_LENGTH);\n const iv = envelope.subarray(1 + KEY_LENGTH, 1 + KEY_LENGTH + IV_LENGTH);\n const sealed = envelope.subarray(1 + KEY_LENGTH + IV_LENGTH);\n const symKey = deriveSymKey(receiverPrivate, senderPublic);\n const cipher = gcm(symKey, iv);\n const plain = cipher.decrypt(sealed);\n return new TextDecoder().decode(plain);\n}\n\n// -- Unified decrypt --\n\nexport function decrypt(\n keyOrPrivate: Uint8Array,\n envelope: Uint8Array,\n): string {\n return envelope[0] === TYPE_1\n ? decryptType1(keyOrPrivate, envelope)\n : decryptType0(keyOrPrivate, envelope);\n}\n\n// -- Relay JWT auth (Ed25519 + did:key) --\n\n/** Ed25519 multicodec varint prefix */\nconst ED25519_MULTICODEC = new Uint8Array([0xed, 0x01]);\n\nfunction encodeDidKey(publicKey: Uint8Array): string {\n const prefixed = new Uint8Array(ED25519_MULTICODEC.length + publicKey.length);\n prefixed.set(ED25519_MULTICODEC);\n prefixed.set(publicKey, ED25519_MULTICODEC.length);\n return `did:key:z${base58.encode(prefixed)}`;\n}\n\nfunction base64urlEncode(data: Uint8Array | string): string {\n const bytes =\n typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n return base64urlnopad.encode(bytes);\n}\n\n/** Generate a signed JWT for WC relay authentication */\nexport function createRelayAuthJwt(\n relayUrl: string,\n): { jwt: string; clientId: string } {\n const privateKey = ed25519.utils.randomSecretKey();\n const publicKey = ed25519.getPublicKey(privateKey);\n const clientId = encodeDidKey(publicKey);\n\n const now = Math.floor(Date.now() / 1000);\n const header = base64urlEncode(JSON.stringify({ alg: \"EdDSA\", typ: \"JWT\" }));\n const payload = base64urlEncode(\n JSON.stringify({\n iss: clientId,\n sub: bytesToHex(randomBytes(32)),\n aud: relayUrl,\n iat: now,\n exp: now + 86400, // 24 hours\n act: \"client_auth\",\n }),\n );\n\n const message = new TextEncoder().encode(`${header}.${payload}`);\n const signature = base64urlEncode(ed25519.sign(message, privateKey));\n\n return { jwt: `${header}.${payload}.${signature}`, clientId };\n}\n\nexport { bytesToHex, hexToBytes };\n",
|
|
6
6
|
"/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */\nfunction isBytes(a) {\n return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');\n}\n/** Asserts something is Uint8Array. */\nfunction abytes(b) {\n if (!isBytes(b))\n throw new Error('Uint8Array expected');\n}\nfunction isArrayOf(isString, arr) {\n if (!Array.isArray(arr))\n return false;\n if (arr.length === 0)\n return true;\n if (isString) {\n return arr.every((item) => typeof item === 'string');\n }\n else {\n return arr.every((item) => Number.isSafeInteger(item));\n }\n}\nfunction afn(input) {\n if (typeof input !== 'function')\n throw new Error('function expected');\n return true;\n}\nfunction astr(label, input) {\n if (typeof input !== 'string')\n throw new Error(`${label}: string expected`);\n return true;\n}\nfunction anumber(n) {\n if (!Number.isSafeInteger(n))\n throw new Error(`invalid integer: ${n}`);\n}\nfunction aArr(input) {\n if (!Array.isArray(input))\n throw new Error('array expected');\n}\nfunction astrArr(label, input) {\n if (!isArrayOf(true, input))\n throw new Error(`${label}: array of strings expected`);\n}\nfunction anumArr(label, input) {\n if (!isArrayOf(false, input))\n throw new Error(`${label}: array of numbers expected`);\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction chain(...args) {\n const id = (a) => a;\n // Wrap call in closure so JIT can inline calls\n const wrap = (a, b) => (c) => a(b(c));\n // Construct chain of args[-1].encode(args[-2].encode([...]))\n const encode = args.map((x) => x.encode).reduceRight(wrap, id);\n // Construct chain of args[0].decode(args[1].decode(...))\n const decode = args.map((x) => x.decode).reduce(wrap, id);\n return { encode, decode };\n}\n/**\n * Encodes integer radix representation to array of strings using alphabet and back.\n * Could also be array of strings.\n * @__NO_SIDE_EFFECTS__\n */\nfunction alphabet(letters) {\n // mapping 1 to \"b\"\n const lettersA = typeof letters === 'string' ? letters.split('') : letters;\n const len = lettersA.length;\n astrArr('alphabet', lettersA);\n // mapping \"b\" to 1\n const indexes = new Map(lettersA.map((l, i) => [l, i]));\n return {\n encode: (digits) => {\n aArr(digits);\n return digits.map((i) => {\n if (!Number.isSafeInteger(i) || i < 0 || i >= len)\n throw new Error(`alphabet.encode: digit index outside alphabet \"${i}\". Allowed: ${letters}`);\n return lettersA[i];\n });\n },\n decode: (input) => {\n aArr(input);\n return input.map((letter) => {\n astr('alphabet.decode', letter);\n const i = indexes.get(letter);\n if (i === undefined)\n throw new Error(`Unknown letter: \"${letter}\". Allowed: ${letters}`);\n return i;\n });\n },\n };\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction join(separator = '') {\n astr('join', separator);\n return {\n encode: (from) => {\n astrArr('join.decode', from);\n return from.join(separator);\n },\n decode: (to) => {\n astr('join.decode', to);\n return to.split(separator);\n },\n };\n}\n/**\n * Pad strings array so it has integer number of bits\n * @__NO_SIDE_EFFECTS__\n */\nfunction padding(bits, chr = '=') {\n anumber(bits);\n astr('padding', chr);\n return {\n encode(data) {\n astrArr('padding.encode', data);\n while ((data.length * bits) % 8)\n data.push(chr);\n return data;\n },\n decode(input) {\n astrArr('padding.decode', input);\n let end = input.length;\n if ((end * bits) % 8)\n throw new Error('padding: invalid, string should have whole number of bytes');\n for (; end > 0 && input[end - 1] === chr; end--) {\n const last = end - 1;\n const byte = last * bits;\n if (byte % 8 === 0)\n throw new Error('padding: invalid, string has too much padding');\n }\n return input.slice(0, end);\n },\n };\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction normalize(fn) {\n afn(fn);\n return { encode: (from) => from, decode: (to) => fn(to) };\n}\n/**\n * Slow: O(n^2) time complexity\n */\nfunction convertRadix(data, from, to) {\n // base 1 is impossible\n if (from < 2)\n throw new Error(`convertRadix: invalid from=${from}, base cannot be less than 2`);\n if (to < 2)\n throw new Error(`convertRadix: invalid to=${to}, base cannot be less than 2`);\n aArr(data);\n if (!data.length)\n return [];\n let pos = 0;\n const res = [];\n const digits = Array.from(data, (d) => {\n anumber(d);\n if (d < 0 || d >= from)\n throw new Error(`invalid integer: ${d}`);\n return d;\n });\n const dlen = digits.length;\n while (true) {\n let carry = 0;\n let done = true;\n for (let i = pos; i < dlen; i++) {\n const digit = digits[i];\n const fromCarry = from * carry;\n const digitBase = fromCarry + digit;\n if (!Number.isSafeInteger(digitBase) ||\n fromCarry / from !== carry ||\n digitBase - digit !== fromCarry) {\n throw new Error('convertRadix: carry overflow');\n }\n const div = digitBase / to;\n carry = digitBase % to;\n const rounded = Math.floor(div);\n digits[i] = rounded;\n if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)\n throw new Error('convertRadix: carry overflow');\n if (!done)\n continue;\n else if (!rounded)\n pos = i;\n else\n done = false;\n }\n res.push(carry);\n if (done)\n break;\n }\n for (let i = 0; i < data.length - 1 && data[i] === 0; i++)\n res.push(0);\n return res.reverse();\n}\nconst gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));\nconst radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));\nconst powers = /* @__PURE__ */ (() => {\n let res = [];\n for (let i = 0; i < 40; i++)\n res.push(2 ** i);\n return res;\n})();\n/**\n * Implemented with numbers, because BigInt is 5x slower\n */\nfunction convertRadix2(data, from, to, padding) {\n aArr(data);\n if (from <= 0 || from > 32)\n throw new Error(`convertRadix2: wrong from=${from}`);\n if (to <= 0 || to > 32)\n throw new Error(`convertRadix2: wrong to=${to}`);\n if (radix2carry(from, to) > 32) {\n throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);\n }\n let carry = 0;\n let pos = 0; // bitwise position in current element\n const max = powers[from];\n const mask = powers[to] - 1;\n const res = [];\n for (const n of data) {\n anumber(n);\n if (n >= max)\n throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);\n carry = (carry << from) | n;\n if (pos + from > 32)\n throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);\n pos += from;\n for (; pos >= to; pos -= to)\n res.push(((carry >> (pos - to)) & mask) >>> 0);\n const pow = powers[pos];\n if (pow === undefined)\n throw new Error('invalid carry');\n carry &= pow - 1; // clean carry, otherwise it will cause overflow\n }\n carry = (carry << (to - pos)) & mask;\n if (!padding && pos >= from)\n throw new Error('Excess padding');\n if (!padding && carry > 0)\n throw new Error(`Non-zero padding: ${carry}`);\n if (padding && pos > 0)\n res.push(carry >>> 0);\n return res;\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction radix(num) {\n anumber(num);\n const _256 = 2 ** 8;\n return {\n encode: (bytes) => {\n if (!isBytes(bytes))\n throw new Error('radix.encode input should be Uint8Array');\n return convertRadix(Array.from(bytes), _256, num);\n },\n decode: (digits) => {\n anumArr('radix.decode', digits);\n return Uint8Array.from(convertRadix(digits, num, _256));\n },\n };\n}\n/**\n * If both bases are power of same number (like `2**8 <-> 2**64`),\n * there is a linear algorithm. For now we have implementation for power-of-two bases only.\n * @__NO_SIDE_EFFECTS__\n */\nfunction radix2(bits, revPadding = false) {\n anumber(bits);\n if (bits <= 0 || bits > 32)\n throw new Error('radix2: bits should be in (0..32]');\n if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)\n throw new Error('radix2: carry overflow');\n return {\n encode: (bytes) => {\n if (!isBytes(bytes))\n throw new Error('radix2.encode input should be Uint8Array');\n return convertRadix2(Array.from(bytes), 8, bits, !revPadding);\n },\n decode: (digits) => {\n anumArr('radix2.decode', digits);\n return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));\n },\n };\n}\nfunction unsafeWrapper(fn) {\n afn(fn);\n return function (...args) {\n try {\n return fn.apply(null, args);\n }\n catch (e) { }\n };\n}\nfunction checksum(len, fn) {\n anumber(len);\n afn(fn);\n return {\n encode(data) {\n if (!isBytes(data))\n throw new Error('checksum.encode: input should be Uint8Array');\n const sum = fn(data).slice(0, len);\n const res = new Uint8Array(data.length + len);\n res.set(data);\n res.set(sum, data.length);\n return res;\n },\n decode(data) {\n if (!isBytes(data))\n throw new Error('checksum.decode: input should be Uint8Array');\n const payload = data.slice(0, -len);\n const oldChecksum = data.slice(-len);\n const newChecksum = fn(payload).slice(0, len);\n for (let i = 0; i < len; i++)\n if (newChecksum[i] !== oldChecksum[i])\n throw new Error('Invalid checksum');\n return payload;\n },\n };\n}\n// prettier-ignore\nexport const utils = {\n alphabet, chain, checksum, convertRadix, convertRadix2, radix, radix2, join, padding,\n};\n// RFC 4648 aka RFC 3548\n// ---------------------\n/**\n * base16 encoding from RFC 4648.\n * @example\n * ```js\n * base16.encode(Uint8Array.from([0x12, 0xab]));\n * // => '12AB'\n * ```\n */\nexport const base16 = chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));\n/**\n * base32 encoding from RFC 4648. Has padding.\n * Use `base32nopad` for unpadded version.\n * Also check out `base32hex`, `base32hexnopad`, `base32crockford`.\n * @example\n * ```js\n * base32.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'CKVQ===='\n * base32.decode('CKVQ====');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32 = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));\n/**\n * base32 encoding from RFC 4648. No padding.\n * Use `base32` for padded version.\n * Also check out `base32hex`, `base32hexnopad`, `base32crockford`.\n * @example\n * ```js\n * base32nopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'CKVQ'\n * base32nopad.decode('CKVQ');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32nopad = chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), join(''));\n/**\n * base32 encoding from RFC 4648. Padded. Compared to ordinary `base32`, slightly different alphabet.\n * Use `base32hexnopad` for unpadded version.\n * @example\n * ```js\n * base32hex.encode(Uint8Array.from([0x12, 0xab]));\n * // => '2ALG===='\n * base32hex.decode('2ALG====');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32hex = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));\n/**\n * base32 encoding from RFC 4648. No padding. Compared to ordinary `base32`, slightly different alphabet.\n * Use `base32hex` for padded version.\n * @example\n * ```js\n * base32hexnopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => '2ALG'\n * base32hexnopad.decode('2ALG');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32hexnopad = chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), join(''));\n/**\n * base32 encoding from RFC 4648. Doug Crockford's version.\n * https://www.crockford.com/base32.html\n * @example\n * ```js\n * base32crockford.encode(Uint8Array.from([0x12, 0xab]));\n * // => '2ANG'\n * base32crockford.decode('2ANG');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base32crockford = chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));\n// Built-in base64 conversion https://caniuse.com/mdn-javascript_builtins_uint8array_frombase64\n// prettier-ignore\nconst hasBase64Builtin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toBase64 === 'function' &&\n typeof Uint8Array.fromBase64 === 'function')();\nconst decodeBase64Builtin = (s, isUrl) => {\n astr('base64', s);\n const re = isUrl ? /^[A-Za-z0-9=_-]+$/ : /^[A-Za-z0-9=+/]+$/;\n const alphabet = isUrl ? 'base64url' : 'base64';\n if (s.length > 0 && !re.test(s))\n throw new Error('invalid base64');\n return Uint8Array.fromBase64(s, { alphabet, lastChunkHandling: 'strict' });\n};\n/**\n * base64 from RFC 4648. Padded.\n * Use `base64nopad` for unpadded version.\n * Also check out `base64url`, `base64urlnopad`.\n * Falls back to built-in function, when available.\n * @example\n * ```js\n * base64.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs='\n * base64.decode('Eqs=');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\n// prettier-ignore\nexport const base64 = hasBase64Builtin ? {\n encode(b) { abytes(b); return b.toBase64(); },\n decode(s) { return decodeBase64Builtin(s, false); },\n} : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));\n/**\n * base64 from RFC 4648. No padding.\n * Use `base64` for padded version.\n * @example\n * ```js\n * base64nopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs'\n * base64nopad.decode('Eqs');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base64nopad = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), join(''));\n/**\n * base64 from RFC 4648, using URL-safe alphabet. Padded.\n * Use `base64urlnopad` for unpadded version.\n * Falls back to built-in function, when available.\n * @example\n * ```js\n * base64url.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs='\n * base64url.decode('Eqs=');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\n// prettier-ignore\nexport const base64url = hasBase64Builtin ? {\n encode(b) { abytes(b); return b.toBase64({ alphabet: 'base64url' }); },\n decode(s) { return decodeBase64Builtin(s, true); },\n} : chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));\n/**\n * base64 from RFC 4648, using URL-safe alphabet. No padding.\n * Use `base64url` for padded version.\n * @example\n * ```js\n * base64urlnopad.encode(Uint8Array.from([0x12, 0xab]));\n * // => 'Eqs'\n * base64urlnopad.decode('Eqs');\n * // => Uint8Array.from([0x12, 0xab])\n * ```\n */\nexport const base64urlnopad = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), join(''));\n// base58 code\n// -----------\nconst genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => chain(radix(58), alphabet(abc), join(''));\n/**\n * base58: base64 without ambigous characters +, /, 0, O, I, l.\n * Quadratic (O(n^2)) - so, can't be used on large inputs.\n * @example\n * ```js\n * base58.decode('01abcdef');\n * // => '3UhJW'\n * ```\n */\nexport const base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');\n/**\n * base58: flickr version. Check out `base58`.\n */\nexport const base58flickr = genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');\n/**\n * base58: XRP version. Check out `base58`.\n */\nexport const base58xrp = genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');\n// Data len (index) -> encoded block len\nconst XMR_BLOCK_LEN = [0, 2, 3, 5, 6, 7, 9, 10, 11];\n/**\n * base58: XMR version. Check out `base58`.\n * Done in 8-byte blocks (which equals 11 chars in decoding). Last (non-full) block padded with '1' to size in XMR_BLOCK_LEN.\n * Block encoding significantly reduces quadratic complexity of base58.\n */\nexport const base58xmr = {\n encode(data) {\n let res = '';\n for (let i = 0; i < data.length; i += 8) {\n const block = data.subarray(i, i + 8);\n res += base58.encode(block).padStart(XMR_BLOCK_LEN[block.length], '1');\n }\n return res;\n },\n decode(str) {\n let res = [];\n for (let i = 0; i < str.length; i += 11) {\n const slice = str.slice(i, i + 11);\n const blockLen = XMR_BLOCK_LEN.indexOf(slice.length);\n const block = base58.decode(slice);\n for (let j = 0; j < block.length - blockLen; j++) {\n if (block[j] !== 0)\n throw new Error('base58xmr: wrong padding');\n }\n res = res.concat(Array.from(block.slice(block.length - blockLen)));\n }\n return Uint8Array.from(res);\n },\n};\n/**\n * Method, which creates base58check encoder.\n * Requires function, calculating sha256.\n */\nexport const createBase58check = (sha256) => chain(checksum(4, (data) => sha256(sha256(data))), base58);\n/**\n * Use `createBase58check` instead.\n * @deprecated\n */\nexport const base58check = createBase58check;\nconst BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));\nconst POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];\nfunction bech32Polymod(pre) {\n const b = pre >> 25;\n let chk = (pre & 0x1ffffff) << 5;\n for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {\n if (((b >> i) & 1) === 1)\n chk ^= POLYMOD_GENERATORS[i];\n }\n return chk;\n}\nfunction bechChecksum(prefix, words, encodingConst = 1) {\n const len = prefix.length;\n let chk = 1;\n for (let i = 0; i < len; i++) {\n const c = prefix.charCodeAt(i);\n if (c < 33 || c > 126)\n throw new Error(`Invalid prefix (${prefix})`);\n chk = bech32Polymod(chk) ^ (c >> 5);\n }\n chk = bech32Polymod(chk);\n for (let i = 0; i < len; i++)\n chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);\n for (let v of words)\n chk = bech32Polymod(chk) ^ v;\n for (let i = 0; i < 6; i++)\n chk = bech32Polymod(chk);\n chk ^= encodingConst;\n return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]], 30, 5, false));\n}\n/**\n * @__NO_SIDE_EFFECTS__\n */\nfunction genBech32(encoding) {\n const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;\n const _words = radix2(5);\n const fromWords = _words.decode;\n const toWords = _words.encode;\n const fromWordsUnsafe = unsafeWrapper(fromWords);\n function encode(prefix, words, limit = 90) {\n astr('bech32.encode prefix', prefix);\n if (isBytes(words))\n words = Array.from(words);\n anumArr('bech32.encode', words);\n const plen = prefix.length;\n if (plen === 0)\n throw new TypeError(`Invalid prefix length ${plen}`);\n const actualLength = plen + 7 + words.length;\n if (limit !== false && actualLength > limit)\n throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);\n const lowered = prefix.toLowerCase();\n const sum = bechChecksum(lowered, words, ENCODING_CONST);\n return `${lowered}1${BECH_ALPHABET.encode(words)}${sum}`;\n }\n function decode(str, limit = 90) {\n astr('bech32.decode input', str);\n const slen = str.length;\n if (slen < 8 || (limit !== false && slen > limit))\n throw new TypeError(`invalid string length: ${slen} (${str}). Expected (8..${limit})`);\n // don't allow mixed case\n const lowered = str.toLowerCase();\n if (str !== lowered && str !== str.toUpperCase())\n throw new Error(`String must be lowercase or uppercase`);\n const sepIndex = lowered.lastIndexOf('1');\n if (sepIndex === 0 || sepIndex === -1)\n throw new Error(`Letter \"1\" must be present between prefix and data only`);\n const prefix = lowered.slice(0, sepIndex);\n const data = lowered.slice(sepIndex + 1);\n if (data.length < 6)\n throw new Error('Data must be at least 6 characters long');\n const words = BECH_ALPHABET.decode(data).slice(0, -6);\n const sum = bechChecksum(prefix, words, ENCODING_CONST);\n if (!data.endsWith(sum))\n throw new Error(`Invalid checksum in ${str}: expected \"${sum}\"`);\n return { prefix, words };\n }\n const decodeUnsafe = unsafeWrapper(decode);\n function decodeToBytes(str) {\n const { prefix, words } = decode(str, false);\n return { prefix, words, bytes: fromWords(words) };\n }\n function encodeFromBytes(prefix, bytes) {\n return encode(prefix, toWords(bytes));\n }\n return {\n encode,\n decode,\n encodeFromBytes,\n decodeToBytes,\n decodeUnsafe,\n fromWords,\n fromWordsUnsafe,\n toWords,\n };\n}\n/**\n * bech32 from BIP 173. Operates on words.\n * For high-level, check out scure-btc-signer:\n * https://github.com/paulmillr/scure-btc-signer.\n */\nexport const bech32 = genBech32('bech32');\n/**\n * bech32m from BIP 350. Operates on words.\n * It was to mitigate `bech32` weaknesses.\n * For high-level, check out scure-btc-signer:\n * https://github.com/paulmillr/scure-btc-signer.\n */\nexport const bech32m = genBech32('bech32m');\n/**\n * UTF-8-to-byte decoder. Uses built-in TextDecoder / TextEncoder.\n * @example\n * ```js\n * const b = utf8.decode(\"hey\"); // => new Uint8Array([ 104, 101, 121 ])\n * const str = utf8.encode(b); // \"hey\"\n * ```\n */\nexport const utf8 = {\n encode: (data) => new TextDecoder().decode(data),\n decode: (str) => new TextEncoder().encode(str),\n};\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\n// prettier-ignore\nconst hasHexBuiltin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toHex === 'function' &&\n typeof Uint8Array.fromHex === 'function')();\n// prettier-ignore\nconst hexBuiltin = {\n encode(data) { abytes(data); return data.toHex(); },\n decode(s) { astr('hex', s); return Uint8Array.fromHex(s); },\n};\n/**\n * hex string decoder. Uses built-in function, when available.\n * @example\n * ```js\n * const b = hex.decode(\"0102ff\"); // => new Uint8Array([ 1, 2, 255 ])\n * const str = hex.encode(b); // \"0102ff\"\n * ```\n */\nexport const hex = hasHexBuiltin\n ? hexBuiltin\n : chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize((s) => {\n if (typeof s !== 'string' || s.length % 2 !== 0)\n throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);\n return s.toLowerCase();\n }));\n// prettier-ignore\nconst CODERS = {\n utf8, hex, base16, base32, base64, base64url, base58, base58xmr\n};\nconst coderTypeError = 'Invalid encoding type. Available types: utf8, hex, base16, base32, base64, base64url, base58, base58xmr';\n/** @deprecated */\nexport const bytesToString = (type, bytes) => {\n if (typeof type !== 'string' || !CODERS.hasOwnProperty(type))\n throw new TypeError(coderTypeError);\n if (!isBytes(bytes))\n throw new TypeError('bytesToString() expects Uint8Array');\n return CODERS[type].encode(bytes);\n};\n/** @deprecated */\nexport const str = bytesToString; // as in python, but for bytes only\n/** @deprecated */\nexport const stringToBytes = (type, str) => {\n if (!CODERS.hasOwnProperty(type))\n throw new TypeError(coderTypeError);\n if (typeof str !== 'string')\n throw new TypeError('stringToBytes() expects string');\n return CODERS[type].decode(str);\n};\n/** @deprecated */\nexport const bytes = stringToBytes;\n//# sourceMappingURL=index.js.map",
|
|
7
|
-
"const hexes = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, \"0\"));\n\nexport function bytesToHex(bytes: Uint8Array): string {\n let hex = \"\";\n for (const b of bytes) {\n hex += hexes[b];\n }\n return hex;\n}\n\nexport function hexToBytes(hex: string): Uint8Array {\n hex = without0x(hex);\n if (hex.length % 2) hex = `0${hex}`;\n\n const array = new Uint8Array(hex.length / 2);\n for (let i = 0; i < array.length; i++) {\n const j = i * 2;\n const byte = Number.parseInt(hex.slice(j, j + 2), 16);\n if (Number.isNaN(byte) || byte < 0) throw new Error(\"Invalid byte sequence\");\n array[i] = byte;\n }\n return array;\n}\n\nexport function with0x(value: string): string {\n return /^0x/i.test(value) ? value : `0x${value}`;\n}\n\nexport function without0x(value: string): string {\n return /^0x/i.test(value) ? value.slice(2) : value;\n}\n\nexport function utf8ToBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\nexport function bytesToUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\nexport function asciiToBytes(str: string): Uint8Array {\n const bytes = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n bytes[i] = str.charCodeAt(i) & 0xff;\n }\n return bytes;\n}\n\nexport function bytesToAscii(bytes: Uint8Array): string {\n return String.fromCharCode(...bytes);\n}\n\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n if (arrays.length === 1) return arrays[0]!;\n const length = arrays.reduce((a, arr) => a + arr.length, 0);\n const result = new Uint8Array(length);\n let pad = 0;\n for (const arr of arrays) {\n result.set(arr, pad);\n pad += arr.length;\n }\n return result;\n}\n\nexport type IntegerType = number | string | bigint | Uint8Array;\n\nexport function intToBigInt(value: IntegerType): bigint {\n if (typeof value === \"bigint\") return value;\n if (typeof value === \"string\") return BigInt(value);\n if (typeof value === \"number\") {\n if (!Number.isInteger(value))\n throw new RangeError(\"Values of type 'number' must be an integer.\");\n if (value > Number.MAX_SAFE_INTEGER)\n throw new RangeError(\n `Values of type 'number' must be <= ${Number.MAX_SAFE_INTEGER}. Use BigInt instead.`\n );\n return BigInt(value);\n }\n if (value instanceof Uint8Array) return BigInt(`0x${bytesToHex(value)}`);\n throw new TypeError(\"Must be a number, bigint, string, or Uint8Array.\");\n}\n\nexport function intToBytes(value: IntegerType, byteLength: number): Uint8Array {\n return bigIntToBytes(intToBigInt(value), byteLength);\n}\n\nexport function bigIntToBytes(value: bigint, length: number = 16): Uint8Array {\n const hex = value.toString(16).padStart(length * 2, \"0\");\n return hexToBytes(hex);\n}\n\nexport function intToHex(integer: IntegerType, byteLength = 8): string {\n const value = typeof integer === \"bigint\" ? integer : intToBigInt(integer);\n return value.toString(16).padStart(byteLength * 2, \"0\");\n}\n\nexport function toTwos(value: bigint, width: bigint): bigint {\n const limit = BigInt(1) << (width - BigInt(1));\n if (value < -limit || value > limit - BigInt(1)) {\n throw new Error(`Unable to represent integer in width: ${width}`);\n }\n if (value >= BigInt(0)) return value;\n return value + (BigInt(1) << width);\n}\n\nexport function fromTwos(value: bigint, width: bigint): bigint {\n if (value & (BigInt(1) << (width - BigInt(1)))) {\n return value - (BigInt(1) << width);\n }\n return value;\n}\n\nexport function bytesToTwosBigInt(bytes: Uint8Array): bigint {\n return fromTwos(BigInt(`0x${
|
|
7
|
+
"const hexes = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, \"0\"));\n\nexport function bytesToHex(bytes: Uint8Array): string {\n let hex = \"\";\n for (const b of bytes) {\n hex += hexes[b];\n }\n return hex;\n}\n\nexport function hexToBytes(hex: string): Uint8Array {\n hex = without0x(hex);\n if (hex.length % 2) hex = `0${hex}`;\n\n const array = new Uint8Array(hex.length / 2);\n for (let i = 0; i < array.length; i++) {\n const j = i * 2;\n const byte = Number.parseInt(hex.slice(j, j + 2), 16);\n if (Number.isNaN(byte) || byte < 0) throw new Error(\"Invalid byte sequence\");\n array[i] = byte;\n }\n return array;\n}\n\nexport function with0x(value: string): string {\n return /^0x/i.test(value) ? value : `0x${value}`;\n}\n\nexport function without0x(value: string): string {\n return /^0x/i.test(value) ? value.slice(2) : value;\n}\n\nexport function utf8ToBytes(str: string): Uint8Array {\n return new TextEncoder().encode(str);\n}\n\nexport function bytesToUtf8(bytes: Uint8Array): string {\n return new TextDecoder().decode(bytes);\n}\n\nexport function asciiToBytes(str: string): Uint8Array {\n const bytes = new Uint8Array(str.length);\n for (let i = 0; i < str.length; i++) {\n bytes[i] = str.charCodeAt(i) & 0xff;\n }\n return bytes;\n}\n\nexport function bytesToAscii(bytes: Uint8Array): string {\n return String.fromCharCode(...bytes);\n}\n\nexport function concatBytes(...arrays: Uint8Array[]): Uint8Array {\n if (arrays.length === 1) return arrays[0]!;\n const length = arrays.reduce((a, arr) => a + arr.length, 0);\n const result = new Uint8Array(length);\n let pad = 0;\n for (const arr of arrays) {\n result.set(arr, pad);\n pad += arr.length;\n }\n return result;\n}\n\nexport type IntegerType = number | string | bigint | Uint8Array;\n\nexport function intToBigInt(value: IntegerType): bigint {\n if (typeof value === \"bigint\") return value;\n if (typeof value === \"string\") return BigInt(value);\n if (typeof value === \"number\") {\n if (!Number.isInteger(value))\n throw new RangeError(\"Values of type 'number' must be an integer.\");\n if (value > Number.MAX_SAFE_INTEGER)\n throw new RangeError(\n `Values of type 'number' must be <= ${Number.MAX_SAFE_INTEGER}. Use BigInt instead.`\n );\n return BigInt(value);\n }\n if (value instanceof Uint8Array) return BigInt(`0x${bytesToHex(value)}`);\n throw new TypeError(\"Must be a number, bigint, string, or Uint8Array.\");\n}\n\nexport function intToBytes(value: IntegerType, byteLength: number): Uint8Array {\n return bigIntToBytes(intToBigInt(value), byteLength);\n}\n\nexport function bigIntToBytes(value: bigint, length: number = 16): Uint8Array {\n const hex = value.toString(16).padStart(length * 2, \"0\");\n return hexToBytes(hex);\n}\n\nexport function intToHex(integer: IntegerType, byteLength = 8): string {\n const value = typeof integer === \"bigint\" ? integer : intToBigInt(integer);\n return value.toString(16).padStart(byteLength * 2, \"0\");\n}\n\nexport function toTwos(value: bigint, width: bigint): bigint {\n const limit = BigInt(1) << (width - BigInt(1));\n if (value < -limit || value > limit - BigInt(1)) {\n throw new Error(`Unable to represent integer in width: ${width}`);\n }\n if (value >= BigInt(0)) return value;\n return value + (BigInt(1) << width);\n}\n\nexport function fromTwos(value: bigint, width: bigint): bigint {\n if (value & (BigInt(1) << (width - BigInt(1)))) {\n return value - (BigInt(1) << width);\n }\n return value;\n}\n\nexport function bytesToTwosBigInt(bytes: Uint8Array): bigint {\n if (bytes.length === 0) return 0n;\n const hex = bytesToHex(bytes);\n if (hex.length === 0) return 0n;\n return fromTwos(BigInt(`0x${hex}`), BigInt(bytes.byteLength * 8));\n}\n\nexport function writeUInt32BE(value: number): Uint8Array {\n const buf = new Uint8Array(4);\n buf[0] = (value >>> 24) & 0xff;\n buf[1] = (value >>> 16) & 0xff;\n buf[2] = (value >>> 8) & 0xff;\n buf[3] = value & 0xff;\n return buf;\n}\n\nexport function readUInt32BE(bytes: Uint8Array, offset = 0): number {\n return (\n ((bytes[offset]! << 24) |\n (bytes[offset + 1]! << 16) |\n (bytes[offset + 2]! << 8) |\n bytes[offset + 3]!) >>>\n 0\n );\n}\n\nexport function writeUInt16BE(value: number): Uint8Array {\n const buf = new Uint8Array(2);\n buf[0] = (value >>> 8) & 0xff;\n buf[1] = value & 0xff;\n return buf;\n}\n\nexport function readUInt16BE(bytes: Uint8Array, offset = 0): number {\n return ((bytes[offset]! << 8) | bytes[offset + 1]!) >>> 0;\n}\n\nexport function writeUInt8(value: number): Uint8Array {\n return new Uint8Array([value & 0xff]);\n}\n",
|
|
8
8
|
"/** WalletConnect v2 relay client (wss://relay.walletconnect.com) */\n\nimport type { WcRelayMessage } from \"./types.ts\";\nimport {\n encryptType0,\n encodeBase64,\n createRelayAuthJwt,\n} from \"./crypto.ts\";\n\nconst DEFAULT_RELAY = \"wss://relay.walletconnect.com\";\nconst DEFAULT_TTL = 300; // 5 minutes\n\ntype PendingRpc = {\n resolve: (v: unknown) => void;\n reject: (e: Error) => void;\n};\n\ntype SubscriptionHandler = (message: WcRelayMessage) => void;\n\nexport class WcRelay {\n private ws: WebSocket | null = null;\n private url: string;\n private projectId: string;\n private nextId = Date.now() * 1000 + Math.floor(Math.random() * 1000);\n private pending = new Map<number, PendingRpc>();\n private subscriptions = new Map<string, SubscriptionHandler>();\n /** Map subscription ID (from server) → topic */\n private subIdToTopic = new Map<string, string>();\n private destroyed = false;\n private reconnecting = false;\n private reconnectAttempt = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n private connectPromise: Promise<void> | null = null;\n private connectReject: ((e: Error) => void) | null = null;\n\n constructor(projectId: string, relayUrl?: string) {\n this.projectId = projectId;\n this.url = relayUrl ?? DEFAULT_RELAY;\n }\n\n // -- Connection --\n\n async connect(): Promise<void> {\n if (this.ws?.readyState === WebSocket.OPEN) return;\n if (this.connectPromise) return this.connectPromise;\n\n this.connectPromise = new Promise<void>((resolve, reject) => {\n this.connectReject = reject;\n const { jwt } = createRelayAuthJwt(this.url);\n const wsUrl = `${this.url}/?auth=${jwt}&projectId=${this.projectId}`;\n this.ws = new WebSocket(wsUrl);\n\n this.ws.addEventListener(\n \"open\",\n () => {\n this.reconnectAttempt = 0;\n this.reconnecting = false;\n this.connectPromise = null;\n this.connectReject = null;\n resolve();\n },\n { once: true },\n );\n\n this.ws.addEventListener(\n \"error\",\n (e) => {\n this.connectPromise = null;\n this.connectReject = null;\n reject(new Error(`WC relay connection failed: ${e}`));\n },\n { once: true },\n );\n\n this.ws.addEventListener(\"message\", (event) => {\n this.handleMessage(\n typeof event.data === \"string\"\n ? event.data\n : new TextDecoder().decode(event.data as ArrayBuffer),\n );\n });\n\n this.ws.addEventListener(\"close\", () => {\n this.connectPromise = null;\n if (!this.destroyed) this.handleDisconnect();\n });\n });\n\n return this.connectPromise;\n }\n\n // -- Publish/Subscribe --\n\n async subscribe(\n topic: string,\n handler: SubscriptionHandler,\n ): Promise<string> {\n await this.connect();\n this.subscriptions.set(topic, handler);\n const subId = (await this.rpc(\"irn_subscribe\", { topic })) as string;\n this.subIdToTopic.set(subId, topic);\n return subId;\n }\n\n async publish(\n topic: string,\n message: string,\n tag: number,\n ttl: number = DEFAULT_TTL,\n ): Promise<void> {\n await this.connect();\n await this.rpc(\"irn_publish\", {\n topic,\n message,\n ttl,\n tag,\n prompt: false,\n });\n }\n\n /** Encrypt + publish a type-0 envelope */\n async publishEncrypted(\n topic: string,\n symKey: Uint8Array,\n payload: unknown,\n tag: number,\n ttl: number = DEFAULT_TTL,\n ): Promise<void> {\n const plaintext = JSON.stringify(payload);\n const envelope = encryptType0(symKey, plaintext);\n await this.publish(topic, encodeBase64(envelope), tag, ttl);\n }\n\n // -- Internal --\n\n private rpc(method: string, params: Record<string, unknown>): Promise<unknown> {\n return new Promise((resolve, reject) => {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n return reject(new Error(\"WC relay not connected\"));\n }\n const id = this.nextId++;\n this.pending.set(id, { resolve, reject });\n this.ws.send(JSON.stringify({ id, jsonrpc: \"2.0\", method, params }));\n });\n }\n\n private handleMessage(raw: string) {\n let msg: any;\n try {\n msg = JSON.parse(raw);\n } catch {\n return;\n }\n\n // RPC response\n if (\"id\" in msg && msg.id != null && this.pending.has(msg.id)) {\n const p = this.pending.get(msg.id)!;\n this.pending.delete(msg.id);\n if (msg.error) {\n p.reject(new Error(`WC relay error: ${msg.error.message}`));\n } else {\n p.resolve(msg.result);\n }\n return;\n }\n\n // Server push (irn_subscription)\n if (msg.method === \"irn_subscription\" && msg.params) {\n const { id: subId, data } = msg.params;\n const topic = data?.topic ?? this.subIdToTopic.get(subId);\n const handler = topic ? this.subscriptions.get(topic) : undefined;\n if (handler && data) {\n handler({\n topic: data.topic,\n message: data.message,\n publishedAt: data.publishedAt ?? Date.now(),\n tag: data.tag ?? 0,\n });\n }\n // Acknowledge\n if (msg.id != null) {\n this.ws?.send(\n JSON.stringify({ id: msg.id, jsonrpc: \"2.0\", result: true }),\n );\n }\n }\n }\n\n private handleDisconnect() {\n this.ws = null;\n for (const [, p] of this.pending) {\n p.reject(new Error(\"WC relay disconnected\"));\n }\n this.pending.clear();\n\n if (this.subscriptions.size > 0 && this.reconnectAttempt < 5) {\n this.scheduleReconnect();\n }\n }\n\n private scheduleReconnect() {\n if (this.destroyed || this.reconnecting) return;\n this.reconnecting = true;\n const delay = 1000 * 2 ** this.reconnectAttempt;\n this.reconnectAttempt++;\n\n this.reconnectTimer = setTimeout(async () => {\n this.reconnecting = false;\n try {\n await this.connect();\n // Re-subscribe all topics\n for (const [topic] of this.subscriptions) {\n const subId = (await this.rpc(\"irn_subscribe\", { topic })) as string;\n this.subIdToTopic.set(subId, topic);\n }\n } catch {\n if (!this.destroyed && this.subscriptions.size > 0) {\n this.handleDisconnect();\n }\n }\n }, delay);\n }\n\n destroy(): void {\n this.destroyed = true;\n if (this.reconnectTimer) clearTimeout(this.reconnectTimer);\n if (this.connectReject) {\n this.connectReject(new Error(\"WC relay destroyed\"));\n this.connectReject = null;\n this.connectPromise = null;\n }\n for (const [, p] of this.pending) {\n p.reject(new Error(\"WC relay destroyed\"));\n }\n this.pending.clear();\n this.subscriptions.clear();\n this.subIdToTopic.clear();\n if (this.ws) {\n this.ws.close();\n this.ws = null;\n }\n }\n}\n",
|
|
9
9
|
"/** WalletConnect v2 session state machine (pairing → proposal → settlement) */\n\nimport type {\n WcProviderConfig,\n WcPairResult,\n WcSessionSettled,\n WcSessionData,\n WcJsonRpc,\n WcProposal,\n} from \"./types.ts\";\nimport {\n generateKeyPair,\n generateSymKey,\n deriveSymKey,\n symKeyToTopic,\n decryptType0,\n decryptType1,\n decodeBase64,\n bytesToHex,\n hexToBytes,\n} from \"./crypto.ts\";\nimport { WcRelay } from \"./relay.ts\";\n\nconst STORAGE_KEY = \"@secondlayer/wc:session\";\nconst SESSION_EXPIRY = 7 * 24 * 60 * 60; // 7 days in seconds\n\nconst STACKS_METHODS = [\n \"stx_getAddresses\",\n \"stx_transferStx\",\n \"stx_callContract\",\n \"stx_deployContract\",\n \"stx_signMessage\",\n \"stx_signTransaction\",\n];\n\nconst STACKS_EVENTS = [\"chainChanged\", \"accountsChanged\"];\n\ndeclare const localStorage:\n | {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n }\n | undefined;\n\nfunction getStorage() {\n return typeof localStorage !== \"undefined\" ? localStorage : undefined;\n}\n\nexport class WcSession {\n private relay: WcRelay;\n private config: WcProviderConfig;\n private chains: string[];\n\n // Pairing state\n private pairingSymKey: Uint8Array | null = null;\n private pairingTopic: string | null = null;\n private selfKeyPair: { privateKey: Uint8Array; publicKey: Uint8Array } | null = null;\n\n // Session state\n private sessionData: WcSessionData | null = null;\n private sessionSymKey: Uint8Array | null = null;\n private pending = new Map<\n number,\n { resolve: (v: unknown) => void; reject: (e: Error) => void }\n >();\n private nextId = Date.now();\n\n constructor(config: WcProviderConfig) {\n this.config = config;\n this.chains = config.chains ?? [\"stacks:1\"];\n this.relay = new WcRelay(config.projectId, config.relayUrl);\n }\n\n /** Try restoring a persisted session. Returns true if valid session found. */\n restore(): boolean {\n try {\n const raw = getStorage()?.getItem(STORAGE_KEY);\n if (!raw) return false;\n const data = JSON.parse(raw) as WcSessionData;\n if (data.expiry < Date.now() / 1000) {\n getStorage()?.removeItem(STORAGE_KEY);\n return false;\n }\n this.sessionData = data;\n this.sessionSymKey = hexToBytes(data.symKey);\n // Subscribe to session topic for incoming requests (fire-and-forget)\n this.subscribeSession().catch(() => {});\n return true;\n } catch {\n return false;\n }\n }\n\n /** Initiate pairing. Returns URI for QR code + approval promise. */\n async pair(): Promise<WcPairResult> {\n this.pairingSymKey = generateSymKey();\n this.pairingTopic = symKeyToTopic(this.pairingSymKey);\n this.selfKeyPair = generateKeyPair();\n\n const symKeyHex = bytesToHex(this.pairingSymKey);\n const uri = `wc:${this.pairingTopic}@2?relay-protocol=irn&symKey=${symKeyHex}`;\n\n const approval = new Promise<WcSessionSettled>((resolve, reject) => {\n this.relay\n .subscribe(this.pairingTopic!, (msg) => {\n try {\n this.handlePairingMessage(msg.message, resolve, reject);\n } catch (err) {\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n })\n .catch(reject);\n });\n\n return { uri, approval };\n }\n\n /** Send a JSON-RPC request over the session. */\n async request(method: string, params?: unknown): Promise<unknown> {\n if (!this.sessionData || !this.sessionSymKey) {\n throw new Error(\"No active WC session\");\n }\n\n const id = this.nextId++;\n const payload = {\n id,\n jsonrpc: \"2.0\" as const,\n method: \"wc_sessionRequest\",\n params: {\n request: { method, params },\n chainId: this.chains[0],\n },\n };\n\n return new Promise((resolve, reject) => {\n this.pending.set(id, { resolve, reject });\n this.relay\n .publishEncrypted(\n this.sessionData!.topic,\n this.sessionSymKey!,\n payload,\n 1108, // tag for session request\n SESSION_EXPIRY,\n )\n .catch((err) => {\n this.pending.delete(id);\n reject(err);\n });\n });\n }\n\n disconnect(): void {\n if (this.sessionData && this.sessionSymKey) {\n const id = this.nextId++;\n const payload = {\n id,\n jsonrpc: \"2.0\",\n method: \"wc_sessionDelete\",\n params: { code: 6000, message: \"User disconnected\" },\n };\n // Best-effort notify peer\n this.relay\n .publishEncrypted(\n this.sessionData.topic,\n this.sessionSymKey,\n payload,\n 1112,\n )\n .catch(() => {});\n }\n this.sessionData = null;\n this.sessionSymKey = null;\n this.pending.clear();\n getStorage()?.removeItem(STORAGE_KEY);\n this.relay.destroy();\n }\n\n get session(): WcSessionData | null {\n return this.sessionData;\n }\n\n // -- Internal --\n\n private handlePairingMessage(\n message: string,\n resolve: (v: WcSessionSettled) => void,\n reject: (e: Error) => void,\n ) {\n const envelope = decodeBase64(message);\n let plaintext: string;\n\n // Could be type 0 (symmetric) or type 1 (asymmetric)\n if (envelope[0] === 0x01 && this.selfKeyPair) {\n plaintext = decryptType1(this.selfKeyPair.privateKey, envelope);\n } else if (this.pairingSymKey) {\n plaintext = decryptType0(this.pairingSymKey, envelope);\n } else {\n return;\n }\n\n let rpc: WcJsonRpc;\n try {\n rpc = JSON.parse(plaintext) as WcJsonRpc;\n } catch {\n return;\n }\n\n if (rpc.method === \"wc_sessionPropose\") {\n this.handleProposal(rpc as WcJsonRpc<WcProposal>, resolve, reject).catch(reject);\n }\n }\n\n private async handleProposal(\n rpc: WcJsonRpc<WcProposal>,\n resolve: (v: WcSessionSettled) => void,\n reject: (e: Error) => void,\n ) {\n try {\n const proposal = rpc.params;\n const peerPublicKey = hexToBytes(proposal.proposer.publicKey);\n\n // Generate session key pair + derive session symmetric key\n const sessionKp = generateKeyPair();\n const sessionSymKey = deriveSymKey(sessionKp.privateKey, peerPublicKey);\n const sessionTopic = symKeyToTopic(sessionSymKey);\n\n const expiry = Math.floor(Date.now() / 1000) + SESSION_EXPIRY;\n\n const settled: WcSessionSettled = {\n relay: { protocol: \"irn\" },\n namespaces: {\n stacks: {\n chains: this.chains,\n methods: STACKS_METHODS,\n events: STACKS_EVENTS,\n accounts: this.chains.map((c) => `${c}:placeholder`),\n },\n },\n controller: {\n publicKey: bytesToHex(sessionKp.publicKey),\n metadata: this.config.metadata,\n },\n expiry,\n };\n\n // Approve the proposal on the pairing topic\n const approvePayload = {\n id: rpc.id,\n jsonrpc: \"2.0\",\n result: {\n relay: { protocol: \"irn\" },\n responderPublicKey: bytesToHex(sessionKp.publicKey),\n },\n };\n\n await this.relay.publishEncrypted(\n this.pairingTopic!,\n this.pairingSymKey!,\n approvePayload,\n 1101, // tag for session propose response\n );\n\n // Subscribe to session topic\n this.sessionSymKey = sessionSymKey;\n this.sessionData = {\n topic: sessionTopic,\n symKey: bytesToHex(sessionSymKey),\n peerMeta: proposal.proposer.metadata,\n expiry,\n accounts: [],\n controllerPublicKey: proposal.proposer.publicKey,\n };\n\n await this.subscribeSession();\n\n // Send session settle on the new session topic\n const settlePayload = {\n id: this.nextId++,\n jsonrpc: \"2.0\",\n method: \"wc_sessionSettle\",\n params: settled,\n };\n\n await this.relay.publishEncrypted(\n sessionTopic,\n sessionSymKey,\n settlePayload,\n 1104, // tag for session settle\n );\n\n // Persist\n getStorage()?.setItem(STORAGE_KEY, JSON.stringify(this.sessionData));\n\n resolve(settled);\n } catch (err) {\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n }\n\n private async subscribeSession() {\n if (!this.sessionData || !this.sessionSymKey) return;\n\n const symKey = this.sessionSymKey;\n await this.relay.subscribe(this.sessionData.topic, (msg) => {\n try {\n const envelope = decodeBase64(msg.message);\n const plaintext = decryptType0(symKey, envelope);\n const rpc = JSON.parse(plaintext);\n\n // Response to our request\n if (\"id\" in rpc && this.pending.has(rpc.id)) {\n const p = this.pending.get(rpc.id)!;\n this.pending.delete(rpc.id);\n if (rpc.error) {\n p.reject(new Error(rpc.error.message ?? \"WC request failed\"));\n } else {\n p.resolve(rpc.result);\n }\n }\n\n // Session delete from peer\n if (rpc.method === \"wc_sessionDelete\") {\n this.sessionData = null;\n this.sessionSymKey = null;\n this.pending.clear();\n getStorage()?.removeItem(STORAGE_KEY);\n }\n } catch {\n // ignore malformed messages\n }\n });\n }\n}\n",
|
|
10
10
|
"/** WalletProvider adapter for WalletConnect v2 */\n\nimport type { WalletProvider } from \"../types.ts\";\nimport type { WcProviderConfig, WcPairResult, WcSessionData } from \"./types.ts\";\nimport { WcSession } from \"./session.ts\";\n\nexport class WalletConnectProvider implements WalletProvider {\n private session: WcSession;\n\n constructor(config: WcProviderConfig) {\n this.session = new WcSession(config);\n }\n\n /** Try restoring a persisted session. Returns true if valid. */\n restore(): boolean {\n return this.session.restore();\n }\n\n /** Initiate pairing. Returns URI for QR + approval promise. */\n async pair(): Promise<WcPairResult> {\n return this.session.pair();\n }\n\n async request(method: string, params?: any): Promise<any> {\n return this.session.request(method, params);\n }\n\n disconnect(): void {\n this.session.disconnect();\n }\n\n get sessionData(): WcSessionData | null {\n return this.session.session;\n }\n}\n",
|
package/dist/src/index.d.cts
CHANGED
|
@@ -243,6 +243,8 @@ declare const ClarityVersion: {
|
|
|
243
243
|
readonly Clarity1: 1
|
|
244
244
|
readonly Clarity2: 2
|
|
245
245
|
readonly Clarity3: 3
|
|
246
|
+
readonly Clarity4: 4
|
|
247
|
+
readonly Clarity5: 5
|
|
246
248
|
};
|
|
247
249
|
type ClarityVersion = (typeof ClarityVersion)[keyof typeof ClarityVersion];
|
|
248
250
|
declare const AnchorMode: {
|
|
@@ -273,6 +275,11 @@ type PubKeyEncoding = (typeof PubKeyEncoding)[keyof typeof PubKeyEncoding];
|
|
|
273
275
|
declare const TenureChangeCause: {
|
|
274
276
|
readonly BlockFound: 0x00
|
|
275
277
|
readonly Extended: 0x01
|
|
278
|
+
readonly ExtendedRuntime: 0x02
|
|
279
|
+
readonly ExtendedReadCount: 0x03
|
|
280
|
+
readonly ExtendedReadLength: 0x04
|
|
281
|
+
readonly ExtendedWriteCount: 0x05
|
|
282
|
+
readonly ExtendedWriteLength: 0x06
|
|
276
283
|
};
|
|
277
284
|
type TenureChangeCause = (typeof TenureChangeCause)[keyof typeof TenureChangeCause];
|
|
278
285
|
type TokenTransferPayload = {
|
package/dist/src/index.d.ts
CHANGED
|
@@ -243,6 +243,8 @@ declare const ClarityVersion: {
|
|
|
243
243
|
readonly Clarity1: 1
|
|
244
244
|
readonly Clarity2: 2
|
|
245
245
|
readonly Clarity3: 3
|
|
246
|
+
readonly Clarity4: 4
|
|
247
|
+
readonly Clarity5: 5
|
|
246
248
|
};
|
|
247
249
|
type ClarityVersion = (typeof ClarityVersion)[keyof typeof ClarityVersion];
|
|
248
250
|
declare const AnchorMode: {
|
|
@@ -273,6 +275,11 @@ type PubKeyEncoding = (typeof PubKeyEncoding)[keyof typeof PubKeyEncoding];
|
|
|
273
275
|
declare const TenureChangeCause: {
|
|
274
276
|
readonly BlockFound: 0x00
|
|
275
277
|
readonly Extended: 0x01
|
|
278
|
+
readonly ExtendedRuntime: 0x02
|
|
279
|
+
readonly ExtendedReadCount: 0x03
|
|
280
|
+
readonly ExtendedReadLength: 0x04
|
|
281
|
+
readonly ExtendedWriteCount: 0x05
|
|
282
|
+
readonly ExtendedWriteLength: 0x06
|
|
276
283
|
};
|
|
277
284
|
type TenureChangeCause = (typeof TenureChangeCause)[keyof typeof TenureChangeCause];
|
|
278
285
|
type TokenTransferPayload = {
|
package/dist/src/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
simulateTransaction,
|
|
23
23
|
sponsorTransaction,
|
|
24
24
|
transferStx
|
|
25
|
-
} from "../shared/stacks-
|
|
25
|
+
} from "../shared/stacks-k9p8m3wf.js";
|
|
26
26
|
import {
|
|
27
27
|
callContract,
|
|
28
28
|
estimateFee,
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
getNonce,
|
|
31
31
|
readContract,
|
|
32
32
|
sendTransaction
|
|
33
|
-
} from "../shared/stacks-
|
|
33
|
+
} from "../shared/stacks-96gaxfcf.js";
|
|
34
34
|
import {
|
|
35
35
|
WebSocketError,
|
|
36
36
|
watchAddress,
|
|
@@ -41,15 +41,15 @@ import {
|
|
|
41
41
|
watchTransaction
|
|
42
42
|
} from "../shared/stacks-y3dh7hv1.js";
|
|
43
43
|
import"../shared/stacks-709tra19.js";
|
|
44
|
-
import"../shared/stacks-
|
|
44
|
+
import"../shared/stacks-6m1z4j07.js";
|
|
45
45
|
import {
|
|
46
46
|
buildContractCall,
|
|
47
47
|
buildContractDeploy,
|
|
48
48
|
buildTokenTransfer,
|
|
49
49
|
finalizeMultiSig,
|
|
50
50
|
makeMultiSigAddress
|
|
51
|
-
} from "../shared/stacks-
|
|
52
|
-
import"../shared/stacks-
|
|
51
|
+
} from "../shared/stacks-xp9n3r0t.js";
|
|
52
|
+
import"../shared/stacks-rg1g0fja.js";
|
|
53
53
|
import {
|
|
54
54
|
formatStx,
|
|
55
55
|
parseStx
|
|
@@ -60,14 +60,14 @@ import {
|
|
|
60
60
|
TESTNET_ZERO_ADDRESS,
|
|
61
61
|
ZERO_ADDRESS
|
|
62
62
|
} from "../shared/stacks-v9jqcpd4.js";
|
|
63
|
-
import"../shared/stacks-
|
|
63
|
+
import"../shared/stacks-rwfgts3s.js";
|
|
64
64
|
import {
|
|
65
65
|
getContractAddress,
|
|
66
66
|
isAddressEqual,
|
|
67
67
|
isValidAddress,
|
|
68
68
|
parseContractId
|
|
69
|
-
} from "../shared/stacks-
|
|
70
|
-
import"../shared/stacks-
|
|
69
|
+
} from "../shared/stacks-s10yb9gz.js";
|
|
70
|
+
import"../shared/stacks-s7z5q8be.js";
|
|
71
71
|
|
|
72
72
|
// src/clients/createClient.ts
|
|
73
73
|
var BASE_KEYS = new Set(["chain", "account", "transport", "request", "extend"]);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Pc
|
|
3
|
-
} from "../../shared/stacks-
|
|
4
|
-
import"../../shared/stacks-
|
|
5
|
-
import"../../shared/stacks-
|
|
3
|
+
} from "../../shared/stacks-je937aas.js";
|
|
4
|
+
import"../../shared/stacks-s10yb9gz.js";
|
|
5
|
+
import"../../shared/stacks-s7z5q8be.js";
|
|
6
6
|
export {
|
|
7
7
|
Pc
|
|
8
8
|
};
|
package/dist/src/pox/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getContract
|
|
3
|
-
} from "../../shared/stacks-
|
|
4
|
-
import"../../shared/stacks-
|
|
3
|
+
} from "../../shared/stacks-q79dx28x.js";
|
|
4
|
+
import"../../shared/stacks-96gaxfcf.js";
|
|
5
5
|
import"../../shared/stacks-709tra19.js";
|
|
6
|
-
import"../../shared/stacks-
|
|
6
|
+
import"../../shared/stacks-p93g814f.js";
|
|
7
7
|
import {
|
|
8
8
|
Pc
|
|
9
|
-
} from "../../shared/stacks-
|
|
10
|
-
import"../../shared/stacks-
|
|
11
|
-
import"../../shared/stacks-
|
|
9
|
+
} from "../../shared/stacks-je937aas.js";
|
|
10
|
+
import"../../shared/stacks-xp9n3r0t.js";
|
|
11
|
+
import"../../shared/stacks-rg1g0fja.js";
|
|
12
12
|
import"../../shared/stacks-v9jqcpd4.js";
|
|
13
|
-
import"../../shared/stacks-
|
|
14
|
-
import"../../shared/stacks-
|
|
13
|
+
import"../../shared/stacks-rwfgts3s.js";
|
|
14
|
+
import"../../shared/stacks-s10yb9gz.js";
|
|
15
15
|
import {
|
|
16
16
|
hexToBytes
|
|
17
|
-
} from "../../shared/stacks-
|
|
17
|
+
} from "../../shared/stacks-s7z5q8be.js";
|
|
18
18
|
|
|
19
19
|
// src/pox/abi.ts
|
|
20
20
|
var poxAddressTuple = {
|
|
@@ -3,19 +3,19 @@ import {
|
|
|
3
3
|
} from "../../shared/stacks-k58k970n.js";
|
|
4
4
|
import {
|
|
5
5
|
getContract
|
|
6
|
-
} from "../../shared/stacks-
|
|
7
|
-
import"../../shared/stacks-
|
|
6
|
+
} from "../../shared/stacks-q79dx28x.js";
|
|
7
|
+
import"../../shared/stacks-96gaxfcf.js";
|
|
8
8
|
import"../../shared/stacks-709tra19.js";
|
|
9
|
-
import"../../shared/stacks-
|
|
9
|
+
import"../../shared/stacks-p93g814f.js";
|
|
10
10
|
import {
|
|
11
11
|
Pc
|
|
12
|
-
} from "../../shared/stacks-
|
|
13
|
-
import"../../shared/stacks-
|
|
14
|
-
import"../../shared/stacks-
|
|
12
|
+
} from "../../shared/stacks-je937aas.js";
|
|
13
|
+
import"../../shared/stacks-xp9n3r0t.js";
|
|
14
|
+
import"../../shared/stacks-rg1g0fja.js";
|
|
15
15
|
import"../../shared/stacks-v9jqcpd4.js";
|
|
16
|
-
import"../../shared/stacks-
|
|
17
|
-
import"../../shared/stacks-
|
|
18
|
-
import"../../shared/stacks-
|
|
16
|
+
import"../../shared/stacks-rwfgts3s.js";
|
|
17
|
+
import"../../shared/stacks-s10yb9gz.js";
|
|
18
|
+
import"../../shared/stacks-s7z5q8be.js";
|
|
19
19
|
|
|
20
20
|
// src/stackingdao/abi.ts
|
|
21
21
|
var withdrawTuple = {
|