UNPKG

@btc-vision/transaction

Version:

OPNet transaction library allows you to create and sign transactions for the OPNet network.

70 lines (69 loc) 2.79 kB
import { networks, toXOnly } from '@btc-vision/bitcoin'; import { BinaryWriter } from '../buffer/BinaryWriter.js'; import { Features } from './Features.js'; import { Address } from '../keypair/Address.js'; import { Compressor } from '../bytecode/Compressor.js'; export class Generator { constructor(senderPubKey, contractSaltPubKey, network = networks.bitcoin) { this.network = networks.bitcoin; this.senderPubKey = senderPubKey; this.contractSaltPubKey = contractSaltPubKey; this.network = network; this.xSenderPubKey = toXOnly(senderPubKey); } buildHeader(features) { let flags = 0; for (const feature of features) { flags |= feature; } const bytesU24 = Buffer.alloc(3); bytesU24.writeUIntBE(flags, 0, 3); return Buffer.from([this.senderPubKey[0], ...bytesU24]); } getHeader(maxPriority, features = []) { const writer = new BinaryWriter(12); writer.writeBytes(this.buildHeader(features)); writer.writeU64(maxPriority); return Buffer.from(writer.getBuffer()); } splitBufferIntoChunks(buffer, chunkSize = Generator.DATA_CHUNK_SIZE) { const chunks = []; for (let i = 0; i < buffer.length; i += chunkSize) { const dataLength = Math.min(chunkSize, buffer.length - i); const buf2 = Buffer.alloc(dataLength); for (let j = 0; j < dataLength; j++) { buf2.writeUInt8(buffer[i + j], j); } chunks.push([buf2]); } return chunks; } encodeFeature(feature) { switch (feature.opcode) { case Features.ACCESS_LIST: return this.splitBufferIntoChunks(this.encodeAccessListFeature(feature)); default: throw new Error(`Unknown feature type: ${feature.opcode}`); } } encodeAccessListFeature(feature) { const writer = new BinaryWriter(); writer.writeU16(Object.keys(feature.data).length); for (const contract in feature.data) { const parsedContract = Address.fromString(contract); const data = feature.data[contract]; writer.writeAddress(parsedContract); writer.writeU32(data.length); for (const pointer of data) { const pointerBuffer = Buffer.from(pointer, 'base64'); if (pointerBuffer.length !== 32) { throw new Error(`Invalid pointer length: ${pointerBuffer.length}`); } writer.writeBytes(pointerBuffer); } } return Compressor.compress(Buffer.from(writer.getBuffer())); } } Generator.DATA_CHUNK_SIZE = 512; Generator.MAGIC = Buffer.from('op', 'utf-8');