Script Parsing
The MNEE SDK provides methods to parse inscription data and cosigner information from Bitcoin scripts.
Parse Inscription
The parseInscription
method extracts inscription data from a Bitcoin script. This is useful for analyzing on-chain data and understanding transaction metadata.
Usage
import { Script } from '@bsv/sdk';
const script = Script.fromHex('...');
const inscription = mnee.parseInscription(script);
console.log('Inscription:', inscription);
Response
Returns an Inscription
object or undefined
if no inscription is found:
{
file?: {
hash: string;
size: number;
type: string;
content: number[];
};
fields?: {
[key: string]: any;
};
parent?: string;
}
Parse Cosigner Scripts
The parseCosignerScripts
method extracts cosigner public keys and addresses from an array of scripts.
Usage
import { Script } from '@bsv/sdk';
const scripts = [
Script.fromHex('...'),
Script.fromHex('...')
];
const cosigners = mnee.parseCosignerScripts(scripts);
console.log('Cosigner addresses:', cosigners);
Response
Returns an array of ParsedCosigner
objects:
[
{
cosigner: "03d47c2e48c59b3f58b96c9e616d0a84c6e02725e47beefcb5b5a8fbe21a3c5e3a",
address: "17cgGUmStWwcYgHg3kxmzXSp6JUbj8XA3u"
}
]
Common Use Cases
Extract Inscription Data
async function analyzeInscription(txid) {
// Get transaction details
const parsed = await mnee.parseTx(txid, { includeRaw: true });
// Check each output for inscriptions
for (const output of parsed.raw.outputs) {
const script = Script.fromHex(output.scriptPubKey);
const inscription = mnee.parseInscription(script);
if (inscription) {
console.log('Found inscription:', inscription);
if (inscription.file) {
console.log(`File type: ${inscription.file.type}`);
console.log(`File size: ${inscription.file.size} bytes`);
console.log(`File hash: ${inscription.file.hash}`);
}
if (inscription.fields) {
console.log('Custom fields:', inscription.fields);
}
}
}
}
Verify Cosigner Authorization
async function verifyCosigner(rawTxHex) {
const tx = Transaction.fromHex(rawTxHex);
const scripts = tx.outputs.map(output => output.script);
const cosigners = mnee.parseCosignerScripts(scripts);
// Get expected cosigner from config
const config = await mnee.config();
const expectedCosigner = config.approver;
// Verify cosigner
const authorized = cosigners.some(
c => c.cosigner === expectedCosigner
);
if (!authorized) {
throw new Error('Transaction not authorized by cosigner');
}
return cosigners;
}
Extract Metadata from Transactions
async function extractMetadata(txid) {
const parsed = await mnee.parseTx(txid, { includeRaw: true });
const metadata = {
inscriptions: [],
cosigners: [],
customData: {}
};
// Process outputs
for (let i = 0; i < parsed.raw.outputs.length; i++) {
const output = parsed.raw.outputs[i];
const script = Script.fromHex(output.scriptPubKey);
// Check for inscription
const inscription = mnee.parseInscription(script);
if (inscription) {
metadata.inscriptions.push({
outputIndex: i,
inscription
});
}
// Check for cosigner
const cosigners = mnee.parseCosignerScripts([script]);
if (cosigners.length > 0) {
metadata.cosigners.push({
outputIndex: i,
cosigner: cosigners[0]
});
}
}
return metadata;
}
Analyze File Inscriptions
function analyzeFileInscription(inscription) {
if (!inscription?.file) {
return null;
}
const analysis = {
type: inscription.file.type,
size: inscription.file.size,
hash: inscription.file.hash,
humanSize: formatBytes(inscription.file.size),
isImage: inscription.file.type.startsWith('image/'),
isText: inscription.file.type.startsWith('text/'),
isJson: inscription.file.type === 'application/json'
};
// Extract content if it's text
if (analysis.isText || analysis.isJson) {
try {
const text = Buffer.from(inscription.file.content).toString('utf8');
analysis.content = analysis.isJson ? JSON.parse(text) : text;
} catch (e) {
analysis.contentError = e.message;
}
}
return analysis;
}
function formatBytes(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
Find Transactions with Specific Inscriptions
async function findInscriptionsByType(addresses, fileType) {
const matches = [];
for (const address of addresses) {
const history = await mnee.recentTxHistory(address, undefined, 100);
for (const tx of history.history) {
const parsed = await mnee.parseTx(tx.txid, { includeRaw: true });
for (const output of parsed.raw.outputs) {
const script = Script.fromHex(output.scriptPubKey);
const inscription = mnee.parseInscription(script);
if (inscription?.file?.type === fileType) {
matches.push({
txid: tx.txid,
address: output.address,
inscription
});
}
}
}
}
return matches;
}
Build Custom Scripts
// Example: Create a script with custom data
function createCustomScript(data) {
const script = new Script();
// Add OP_RETURN for data storage
script.writeOpCode(OpCode.OP_RETURN);
// Add custom data
const dataBuffer = Buffer.from(JSON.stringify(data));
script.writeBin(dataBuffer);
return script;
}
// Verify custom data
function parseCustomScript(script) {
const chunks = script.chunks;
if (chunks[0]?.opCode === OpCode.OP_RETURN && chunks[1]?.buf) {
try {
const data = JSON.parse(chunks[1].buf.toString('utf8'));
return data;
} catch (e) {
return null;
}
}
return null;
}
Important Notes
Not all scripts contain inscriptions or cosigner data
The
parseInscription
method returnsundefined
if no inscription is foundCosigner scripts are typically found in MNEE transaction outputs
File content in inscriptions is stored as a byte array
Always handle the case where parsing returns no data
Script Types
MNEE transactions may contain various script types:
Standard P2PKH: Regular Bitcoin addresses
Inscription Scripts: Contain embedded data/files
Cosigner Scripts: Include cosigner authorization
Multi-signature Scripts: Require multiple signatures
See Also
Parse Transaction - Get full transaction details
Validate Transaction - Verify transaction validity
Configuration - Get expected cosigner information
Last updated