Add Inscriboor extension wallet adapter

This commit is contained in:
matcha committed 2026-10-05 04:43:31 +00:00
1 parent bcc9f0f1cd
commit 276a945f83
1 file changed
+35 -2
+35 -2
View File
@@ -3,14 +3,15 @@ import { schnorr, secp256k1 } from '@noble/curves/secp256k1';
import { bytesToHex } from '@noble/curves/abstract/utils'; import { bytesToHex } from '@noble/curves/abstract/utils';
export const NETWORK = 'super-testnet-local-v0'; export const NETWORK = 'super-testnet-local-v0';
export class TestWallet { export class TestWallet {
constructor(secret) { constructor(secret) {
if (!/^[0-9a-f]{64}$/.test(secret) || !secp256k1.utils.isValidPrivateKey(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.'); throw new Error('Invalid test wallet key. Load a Super Testnet v0 backup.');
} }
this.kind = 'test-wallet';
this.secret = secret; this.secret = secret;
this.pubkey = bytesToHex(schnorr.getPublicKey(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.address = Address.p2tr.fromPubKey(this.pubkey, 'regtest');
this.script = ['OP_1', this.pubkey]; this.script = ['OP_1', this.pubkey];
} }
@@ -21,8 +22,40 @@ export class TestWallet {
} }
return new TestWallet(backup.secret); 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) { sign(tx, extension, inputIndex = 0) {
return Signer.taproot.sign(this.secret, tx, inputIndex, extension ? { extension } : {}).hex; 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);
}