diff --git a/src/adapters/wallet.js b/src/adapters/wallet.js index fa6c861..c567d17 100644 --- a/src/adapters/wallet.js +++ b/src/adapters/wallet.js @@ -3,14 +3,15 @@ import { schnorr, secp256k1 } from '@noble/curves/secp256k1'; import { bytesToHex } from '@noble/curves/abstract/utils'; export const NETWORK = 'super-testnet-local-v0'; + export class TestWallet { constructor(secret) { if (!/^[0-9a-f]{64}$/.test(secret) || !secp256k1.utils.isValidPrivateKey(secret)) { throw new Error('Invalid test wallet key. Load a Super Testnet v0 backup.'); } + this.kind = 'test-wallet'; this.secret = secret; this.pubkey = bytesToHex(schnorr.getPublicKey(secret)); - // Untweaked key-path output, as in testnet_generator. Never a mainnet address. this.address = Address.p2tr.fromPubKey(this.pubkey, 'regtest'); this.script = ['OP_1', this.pubkey]; } @@ -21,8 +22,40 @@ export class TestWallet { } return new TestWallet(backup.secret); } - backup() { return { kind: 'test-wallet', version: 1, network: NETWORK, secret: this.secret }; } + backup() { return { kind:'test-wallet', version:1, network:NETWORK, secret:this.secret }; } sign(tx, extension, inputIndex = 0) { return Signer.taproot.sign(this.secret, tx, inputIndex, extension ? { extension } : {}).hex; } } + +export class ExtensionWallet { + constructor(account, provider = null) { + if (account?.network !== NETWORK || !/^[0-9a-f]{64}$/.test(account?.pubkey ?? '')) { + throw new Error('Inscriboor returned an incompatible Super Testnet account.'); + } + const address = Address.p2tr.fromPubKey(account.pubkey, 'regtest'); + if (account.address !== address) throw new Error('Inscriboor account address does not match its public key.'); + this.kind = 'extension-wallet'; + this.pubkey = account.pubkey; + this.address = address; + this.script = ['OP_1', this.pubkey]; + this.provider = provider; + } + static load(backup) { + if (backup?.kind !== 'extension-wallet' || backup?.version !== 1 || backup?.network !== NETWORK) { + throw new Error('Unsupported Inscriboor wallet descriptor.'); + } + return new ExtensionWallet(backup); + } + attach(provider) { this.provider = provider; return this; } + backup() { return { kind:'extension-wallet', version:1, network:NETWORK, pubkey:this.pubkey, address:this.address }; } + async signInscription(params) { + if (!this.provider?.request) throw new Error('Reconnect the Inscriboor extension before signing.'); + return this.provider.request({ method:'ord_signInscription', params }); + } +} + +export function loadWalletBackup(backup) { + if (backup?.kind === 'extension-wallet') return ExtensionWallet.load(backup); + return TestWallet.load(backup); +}