diff --git a/src/adapters/extension-inscription.js b/src/adapters/extension-inscription.js new file mode 100644 index 0000000..4f09afd --- /dev/null +++ b/src/adapters/extension-inscription.js @@ -0,0 +1,70 @@ +import { Script, Tap, Tx } from '@cmdcode/tapscript'; +import { getVin, getVout } from '../upstream/primitives.js'; +import { InscriptionAdapter, envelope, POSTAGE, FEE } from './inscription.js'; +import { NETWORK } from './wallet.js'; + +const signingTx = tx => ({ + hex: Tx.encode(tx).hex, + prevouts: tx.vin.map(input => ({ + value: Number(input.prevout.value), + scriptPubKey: input.prevout.scriptPubKey, + })), +}); + +export async function inscribeWithProvider(chain, wallet, value, parentId = null, metadata = undefined, options = {}) { + const adapter = new InscriptionAdapter(chain, wallet); + const { coin, parent, reinscribe, ...payload } = adapter.prepare(value, parentId, metadata, options); + const carried = parent ?? reinscribe; + const carriedItem = reinscribe?.inscriptions.find(item => item.id === options.reinscribe); + const pointer = carriedItem ? chain.satLocation(carriedItem.sat).offset : options.pointer ?? (parent ? parent.value : undefined); + const script = envelope(wallet.pubkey, payload, parentId, metadata, { ...options, pointer }); + const leaf = Tap.encodeScript(script); + const [tapkey, control] = Tap.getPubKey(wallet.pubkey, { target: leaf }); + + const commit = Tx.create({ + vin: [getVin(coin.txid, coin.vout, coin.value, coin.scriptPubKey)], + vout: [ + getVout(POSTAGE + FEE, ['OP_1', tapkey]), + getVout(coin.value - POSTAGE - 2 * FEE, wallet.script), + ], + }); + const commitId = Tx.util.getTxid(commit); + const reveal = Tx.create({ + vin: [ + ...(carried ? [getVin(carried.txid, carried.vout, carried.value, carried.scriptPubKey)] : []), + getVin(commitId, 0, POSTAGE + FEE, ['OP_1', tapkey]), + ], + vout: [ + ...(carried ? [getVout(carried.value, wallet.script)] : []), + getVout(POSTAGE, wallet.script), + ], + }); + const revealInput = carried ? 1 : 0; + const signatures = await wallet.signInscription({ + network: NETWORK, + commit: signingTx(commit), + reveal: { ...signingTx(reveal), scriptInput: revealInput, leaf }, + intent: { + contentType: payload.contentType, + size: payload.bytes.length, + metadata: metadata !== undefined, + metaprotocol: options.metaprotocol ?? null, + parent: parentId, + delegate: options.delegate ?? null, + pointer: pointer ?? 'automatic', + reinscribe: options.reinscribe ?? null, + postage: POSTAGE, + fees: FEE * 2, + }, + }); + + commit.vin[0].witness = [signatures.commit]; + reveal.vin[revealInput].witness = [signatures.revealScript, Script.encode(script, false).hex, control]; + if (carried) { + if (!signatures.revealKey) throw new Error('Inscriboor did not return the carried-input signature.'); + reveal.vin[0].witness = [signatures.revealKey]; + } + + chain.submitPackage([Tx.encode(commit).hex, Tx.encode(reveal).hex]); + return `${Tx.util.getTxid(reveal)}i0`; +}