Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ node_modules
*.d.ts.map
/test/build
/test/compiled
/.regtest/
/.bitcoin-core/
/logs/
.btcdl
.regtest
58 changes: 58 additions & 0 deletions examples/batch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as btc from '@scure/btc-signer';
import { hex, utf8 } from '@scure/base';
import { OutOrdinalReveal, p2tr_ord_reveal, type Inscription, parseWitness } from '../src/index.ts';

const NETWORK = btc.utils.TEST_NETWORK; // or btc.NETWORK for mainnet
const customScripts = [OutOrdinalReveal];

// Demo key (do not use in production)
const privKey = hex.decode('0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a');
const pubKey = btc.utils.pubSchnorr(privKey);

const insA: Inscription = {
tags: { contentType: 'text/plain;charset=utf-8' },
body: utf8.decode('First inscription in batch'),
};
const insB: Inscription = {
tags: { contentType: 'application/json' },
body: utf8.decode(JSON.stringify({ name: 'second', kind: 'json' })),
};
const insC: Inscription = {
tags: { contentType: 'text/markdown;charset=utf-8' },
body: utf8.decode('# Third inscription\nSome markdown text.'),
};

const inscriptions: Inscription[] = [insA, insB, insC];

const revealPayment = btc.p2tr(
undefined,
p2tr_ord_reveal(pubKey, inscriptions),
NETWORK,
false,
customScripts
);
console.log('Reveal address:', revealPayment.address);

// After funding the address above with enough sats to cover fees, build the reveal tx
const tx = new btc.Transaction({ customScripts });
const FUNDING_TXID = '75ddabb27b8845f5247975c8a5ba7c6f336c4570708ebe230caf6db5217ae858';
const FUNDING_INDEX = 0;
const FUNDING_AMOUNT = 4000n; // higher since there are multiple inscriptions
const FEE = 1200n; // adjust per tx.vsize * feerate

tx.addInput({
...revealPayment,
txid: FUNDING_TXID,
index: FUNDING_INDEX,
witnessUtxo: { script: revealPayment.script, amount: FUNDING_AMOUNT },
});
const changeAddr = revealPayment.address;
tx.addOutputAddress(changeAddr, FUNDING_AMOUNT - FEE, NETWORK);
tx.sign(privKey, undefined, new Uint8Array(32));
tx.finalize();

const txHex = hex.encode(tx.extract());
console.log('Reveal tx hex:', txHex);

const parsed = parseWitness(tx.inputs[0].finalScriptWitness);
console.log('Parsed inscriptions:', parsed);
57 changes: 57 additions & 0 deletions examples/compressed-json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import * as btc from '@scure/btc-signer';
import { hex, utf8 } from '@scure/base';
import { OutOrdinalReveal, p2tr_ord_reveal, type Inscription, parseWitness } from '../src/index.ts';
import { brotliCompressSync, constants as zlibc } from 'node:zlib';

const NETWORK = btc.utils.TEST_NETWORK; // or btc.NETWORK for mainnet
const customScripts = [OutOrdinalReveal];

// Demo key (do not use in production)
const privKey = hex.decode('0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a');
const pubKey = btc.utils.pubSchnorr(privKey);

const json = JSON.stringify({ example: 'brotli compressed json', count: 3, ok: true });
const compressed = brotliCompressSync(utf8.decode(json), {
params: {
[zlibc.BROTLI_PARAM_MODE]: zlibc.BROTLI_MODE_TEXT,
[zlibc.BROTLI_PARAM_QUALITY]: zlibc.BROTLI_MAX_QUALITY,
[zlibc.BROTLI_PARAM_SIZE_HINT]: json.length,
},
});

const inscription: Inscription = {
tags: { contentType: 'application/json', contentEncoding: 'br' },
body: compressed,
};

const revealPayment = btc.p2tr(
undefined,
p2tr_ord_reveal(pubKey, [inscription]),
NETWORK,
false,
customScripts
);
console.log('Reveal address:', revealPayment.address);

const tx = new btc.Transaction({ customScripts });
const FUNDING_TXID = '0000000000000000000000000000000000000000000000000000000000000000';
const FUNDING_INDEX = 0;
const FUNDING_AMOUNT = 3500n;
const FEE = 800n;

tx.addInput({
...revealPayment,
txid: FUNDING_TXID,
index: FUNDING_INDEX,
witnessUtxo: { script: revealPayment.script, amount: FUNDING_AMOUNT },
});
const changeAddr = revealPayment.address;
tx.addOutputAddress(changeAddr, FUNDING_AMOUNT - FEE, NETWORK);
tx.sign(privKey, undefined, new Uint8Array(32));
tx.finalize();

const txHex = hex.encode(tx.extract());
console.log('Reveal tx hex:', txHex);

const parsed = parseWitness(tx.inputs[0].finalScriptWitness);
console.log('Parsed inscriptions:', parsed);
49 changes: 49 additions & 0 deletions examples/html.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as btc from '@scure/btc-signer';
import { hex, utf8 } from '@scure/base';
import { OutOrdinalReveal, p2tr_ord_reveal, type Inscription, parseWitness } from '../src/index.ts';

const NETWORK = btc.utils.TEST_NETWORK; // or btc.NETWORK for mainnet
const customScripts = [OutOrdinalReveal];

// Demo key (do not use in production)
const privKey = hex.decode('0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a');
const pubKey = btc.utils.pubSchnorr(privKey);

const html = `<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Micro Ordinals HTML</title><style>body{font-family:sans-serif;padding:16px}</style></head><body><h1>Hello from HTML inscription</h1><p>This is a basic HTML example.</p></body></html>`;

const inscription: Inscription = {
tags: { contentType: 'text/html;charset=utf-8' },
body: utf8.decode(html),
};

const revealPayment = btc.p2tr(
undefined,
p2tr_ord_reveal(pubKey, [inscription]),
NETWORK,
false,
customScripts
);
console.log('Reveal address:', revealPayment.address);

const tx = new btc.Transaction({ customScripts });
const FUNDING_TXID = '0000000000000000000000000000000000000000000000000000000000000000';
const FUNDING_INDEX = 0;
const FUNDING_AMOUNT = 3000n;
const FEE = 700n;

tx.addInput({
...revealPayment,
txid: FUNDING_TXID,
index: FUNDING_INDEX,
witnessUtxo: { script: revealPayment.script, amount: FUNDING_AMOUNT },
});
const changeAddr = revealPayment.address;
tx.addOutputAddress(changeAddr, FUNDING_AMOUNT - FEE, NETWORK);
tx.sign(privKey, undefined, new Uint8Array(32));
tx.finalize();

const txHex = hex.encode(tx.extract());
console.log('Reveal tx hex:', txHex);

const parsed = parseWitness(tx.inputs[0].finalScriptWitness);
console.log('Parsed inscriptions:', parsed);
53 changes: 53 additions & 0 deletions examples/parent-child.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as btc from '@scure/btc-signer';
import { hex, utf8 } from '@scure/base';
import { OutOrdinalReveal, p2tr_ord_reveal, type Inscription, parseWitness } from '../src/index.ts';

const NETWORK = btc.utils.TEST_NETWORK; // or btc.NETWORK for mainnet
const customScripts = [OutOrdinalReveal];

// Demo key (do not use in production)
const privKey = hex.decode('0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a');
const pubKey = btc.utils.pubSchnorr(privKey);

// Provide a parent inscription id via env: e.g., 0123..abci0
const PARENT_ID = process.env.PARENT_ID || undefined;

const child: Inscription = {
tags: {
contentType: 'text/plain;charset=utf-8',
...(PARENT_ID ? { parent: PARENT_ID } : {}),
},
body: utf8.decode('This inscription declares a parent reference.'),
};

const revealPayment = btc.p2tr(
undefined,
p2tr_ord_reveal(pubKey, [child]),
NETWORK,
false,
customScripts
);
console.log('Reveal address:', revealPayment.address);

const tx = new btc.Transaction({ customScripts });
const FUNDING_TXID = '0000000000000000000000000000000000000000000000000000000000000000';
const FUNDING_INDEX = 0;
const FUNDING_AMOUNT = 3000n;
const FEE = 700n;

tx.addInput({
...revealPayment,
txid: FUNDING_TXID,
index: FUNDING_INDEX,
witnessUtxo: { script: revealPayment.script, amount: FUNDING_AMOUNT },
});
const changeAddr = revealPayment.address;
tx.addOutputAddress(changeAddr, FUNDING_AMOUNT - FEE, NETWORK);
tx.sign(privKey, undefined, new Uint8Array(32));
tx.finalize();

const txHex = hex.encode(tx.extract());
console.log('Reveal tx hex:', txHex);

const parsed = parseWitness(tx.inputs[0].finalScriptWitness);
console.log('Parsed inscriptions:', parsed);
50 changes: 50 additions & 0 deletions examples/rune.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import * as btc from '@scure/btc-signer';
import { hex, utf8 } from '@scure/base';
import { OutOrdinalReveal, p2tr_ord_reveal, type Inscription, parseWitness } from '../src/index.ts';

const NETWORK = btc.utils.TEST_NETWORK; // or btc.NETWORK for mainnet
const customScripts = [OutOrdinalReveal];

// Demo key (do not use in production)
const privKey = hex.decode('0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a');
const pubKey = btc.utils.pubSchnorr(privKey);

// Example rune number (U128). Use a BigInt.
const RUNE = 12345678901234567890n;

const inscription: Inscription = {
tags: { contentType: 'text/plain;charset=utf-8', rune: RUNE },
body: utf8.decode('Inscription associated with a rune value.'),
};

const revealPayment = btc.p2tr(
undefined,
p2tr_ord_reveal(pubKey, [inscription]),
NETWORK,
false,
customScripts
);
console.log('Reveal address:', revealPayment.address);

const tx = new btc.Transaction({ customScripts });
const FUNDING_TXID = '0000000000000000000000000000000000000000000000000000000000000000';
const FUNDING_INDEX = 0;
const FUNDING_AMOUNT = 3000n;
const FEE = 700n;

tx.addInput({
...revealPayment,
txid: FUNDING_TXID,
index: FUNDING_INDEX,
witnessUtxo: { script: revealPayment.script, amount: FUNDING_AMOUNT },
});
const changeAddr = revealPayment.address;
tx.addOutputAddress(changeAddr, FUNDING_AMOUNT - FEE, NETWORK);
tx.sign(privKey, undefined, new Uint8Array(32));
tx.finalize();

const txHex = hex.encode(tx.extract());
console.log('Reveal tx hex:', txHex);

const parsed = parseWitness(tx.inputs[0].finalScriptWitness);
console.log('Parsed inscriptions:', parsed);
51 changes: 51 additions & 0 deletions examples/simple.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import * as btc from '@scure/btc-signer';
import { hex, utf8 } from '@scure/base';
import { OutOrdinalReveal, p2tr_ord_reveal, type Inscription, parseWitness } from '../src/index.ts';

const NETWORK = btc.utils.TEST_NETWORK; // or btc.NETWORK for mainnet
const customScripts = [OutOrdinalReveal];

// Demo key (do not use in production)
const privKey = hex.decode('0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a');
const pubKey = btc.utils.pubSchnorr(privKey);

const inscription: Inscription = {
tags: { contentType: 'text/plain;charset=utf-8' },
body: utf8.decode('Hello, Ordinals!'),
};

// Address where you must first send funds before revealing inscription
const revealPayment = btc.p2tr(
undefined,
p2tr_ord_reveal(pubKey, [inscription]),
NETWORK,
false,
customScripts
);
console.log('Reveal address:', revealPayment.address);

// After funding the address above with enough sats to cover fees, build the reveal tx
const tx = new btc.Transaction({ customScripts });
// Replace the following three values with your funding UTXO details
const FUNDING_TXID = '75ddabb27b8845f5247975c8a5ba7c6f336c4570708ebe230caf6db5217ae858';
const FUNDING_INDEX = 0;
const FUNDING_AMOUNT = 2000n; // sats
const FEE = 500n; // sats (ensure >= tx.vsize * feerate)

tx.addInput({
...revealPayment,
txid: FUNDING_TXID,
index: FUNDING_INDEX,
witnessUtxo: { script: revealPayment.script, amount: FUNDING_AMOUNT },
});
const changeAddr = revealPayment.address;
tx.addOutputAddress(changeAddr, FUNDING_AMOUNT - FEE, NETWORK);
tx.sign(privKey, undefined, new Uint8Array(32));
tx.finalize();

const txHex = hex.encode(tx.extract());
console.log('Reveal tx hex:', txHex);

// Optional: parse inscriptions from witness to verify
const parsed = parseWitness(tx.inputs[0].finalScriptWitness);
console.log('Parsed inscriptions:', parsed);
Loading