|
| 1 | +import { SilentPaymentsNamespace } from "./wasm/wasm_utxo.js"; |
| 2 | + |
| 3 | +export interface SilentPaymentAddressComponents { |
| 4 | + scanKey: Uint8Array; // 33-byte compressed |
| 5 | + spendKey: Uint8Array; // 33-byte compressed |
| 6 | +} |
| 7 | + |
| 8 | +export interface DerivedOutput { |
| 9 | + script: Uint8Array; // P2TR scriptPubKey |
| 10 | + pubkey: Uint8Array; // 32-byte x-only |
| 11 | + tweak: Uint8Array; // 32-byte t_k |
| 12 | +} |
| 13 | + |
| 14 | +export interface ScanMatch { |
| 15 | + outputIndex: number; |
| 16 | + tweak: Uint8Array; // 32-byte t_k |
| 17 | + k: number; |
| 18 | + label: number | null; |
| 19 | + labelTweak: Uint8Array | null; // 32-byte label tweak (if label matched) |
| 20 | +} |
| 21 | + |
| 22 | +export interface PrivkeyInput { |
| 23 | + key: Uint8Array; // 32-byte private key |
| 24 | + isTaproot: boolean; |
| 25 | +} |
| 26 | + |
| 27 | +export interface Outpoint { |
| 28 | + txid: Uint8Array; // 32-byte txid (LE) |
| 29 | + vout: number; |
| 30 | +} |
| 31 | + |
| 32 | +export interface InputData { |
| 33 | + privkeys: PrivkeyInput[]; |
| 34 | + outpoints: Outpoint[]; |
| 35 | +} |
| 36 | + |
| 37 | +export interface PubkeyInput { |
| 38 | + pubkey: Uint8Array; // 33-byte compressed pubkey |
| 39 | +} |
| 40 | + |
| 41 | +export interface TaprootOutputData { |
| 42 | + pubkey: Uint8Array; // 32-byte x-only pubkey |
| 43 | +} |
| 44 | + |
| 45 | +export interface TxData { |
| 46 | + inputs: PubkeyInput[]; |
| 47 | + outpoints: Outpoint[]; |
| 48 | + outputs: TaprootOutputData[]; |
| 49 | +} |
| 50 | + |
| 51 | +/** |
| 52 | + * Decode a silent payment address (sp1q.../tsp1q...) into its component keys. |
| 53 | + */ |
| 54 | +export function decodeAddress(address: string): SilentPaymentAddressComponents { |
| 55 | + return SilentPaymentsNamespace.decode_address(address) as SilentPaymentAddressComponents; |
| 56 | +} |
| 57 | + |
| 58 | +/** |
| 59 | + * Encode a silent payment address from component keys. |
| 60 | + * |
| 61 | + * @param scanKey 33-byte compressed scan public key |
| 62 | + * @param spendKey 33-byte compressed spend public key |
| 63 | + * @param network coin name ("btc", "tbtc", etc.) |
| 64 | + */ |
| 65 | +export function encodeAddress(scanKey: Uint8Array, spendKey: Uint8Array, network: string): string { |
| 66 | + return SilentPaymentsNamespace.encode_address(scanKey, spendKey, network); |
| 67 | +} |
| 68 | + |
| 69 | +/** |
| 70 | + * Derive output scripts for sending to silent payment recipients. |
| 71 | + * |
| 72 | + * @param inputData private keys and outpoints from the transaction inputs |
| 73 | + * @param recipients array of SP address strings (sp1q.../tsp1q...) |
| 74 | + * @returns array of derived P2TR outputs with scripts, pubkeys, and tweaks |
| 75 | + */ |
| 76 | +export function deriveOutputs(inputData: InputData, recipients: string[]): DerivedOutput[] { |
| 77 | + return SilentPaymentsNamespace.derive_outputs(inputData, recipients) as DerivedOutput[]; |
| 78 | +} |
| 79 | + |
| 80 | +/** |
| 81 | + * Scan a transaction for silent payment outputs addressed to this receiver. |
| 82 | + * |
| 83 | + * @param scanKey 32-byte b_scan private key |
| 84 | + * @param spendPubkey 33-byte B_spend public key |
| 85 | + * @param txData transaction data (input pubkeys, outpoints, taproot outputs) |
| 86 | + * @param labels optional array of label indices to check |
| 87 | + * @returns array of matched outputs with tweaks |
| 88 | + */ |
| 89 | +export function scanTransaction( |
| 90 | + scanKey: Uint8Array, |
| 91 | + spendPubkey: Uint8Array, |
| 92 | + txData: TxData, |
| 93 | + labels?: number[] | null, |
| 94 | +): ScanMatch[] { |
| 95 | + return SilentPaymentsNamespace.scan_transaction( |
| 96 | + scanKey, |
| 97 | + spendPubkey, |
| 98 | + txData, |
| 99 | + labels ?? null, |
| 100 | + ) as ScanMatch[]; |
| 101 | +} |
| 102 | + |
| 103 | +/** |
| 104 | + * Derive the private key for spending a matched silent payment output. |
| 105 | + * |
| 106 | + * @param spendKey 32-byte b_spend private key |
| 107 | + * @param tweak 32-byte t_k from scanTransaction |
| 108 | + * @returns 32-byte derived private key p_k |
| 109 | + */ |
| 110 | +export function deriveSpendKey(spendKey: Uint8Array, tweak: Uint8Array): Uint8Array { |
| 111 | + return SilentPaymentsNamespace.derive_spend_key(spendKey, tweak); |
| 112 | +} |
| 113 | + |
| 114 | +/** |
| 115 | + * Create a labeled silent payment address. |
| 116 | + * |
| 117 | + * @param scanKey 32-byte b_scan private key |
| 118 | + * @param spendPubkey 33-byte B_spend public key |
| 119 | + * @param labelIndex the label index m |
| 120 | + * @param network coin name ("btc", "tbtc", etc.) |
| 121 | + * @returns the labeled sp1q.../tsp1q... address string |
| 122 | + */ |
| 123 | +export function createLabeledAddress( |
| 124 | + scanKey: Uint8Array, |
| 125 | + spendPubkey: Uint8Array, |
| 126 | + labelIndex: number, |
| 127 | + network: string, |
| 128 | +): string { |
| 129 | + return SilentPaymentsNamespace.create_labeled_address(scanKey, spendPubkey, labelIndex, network); |
| 130 | +} |
0 commit comments