@muirglacier/jellyfish-transaction
Version:
A collection of TypeScript + JavaScript tools and libraries for DeFi Blockchain developers to build decentralized finance for Bitcoin
268 lines • 9.42 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CWitnessScript = exports.CWitness = exports.CTransactionSegWit = exports.CScript = exports.CVoutV4 = exports.CVoutV2 = exports.CVin = exports.CTransaction = void 0;
const smart_buffer_1 = require("smart-buffer");
const jellyfish_buffer_1 = require("@muirglacier/jellyfish-buffer");
const script_1 = require("./script");
const jellyfish_crypto_1 = require("@muirglacier/jellyfish-crypto");
/**
* USE CTransaction AT YOUR OWN RISK.
* The TransactionBuilder has safety logic built-in to prevent overspent, CTransaction is its raw counter part.
*
* Composable Transaction, C stands for Composable.
* Immutable by design, it implements the Transaction interface for convenience.
* Bi-directional fromBuffer, toBuffer deep composer.
*/
class CTransaction extends jellyfish_buffer_1.ComposableBuffer {
get version() {
return this.data.version;
}
get vin() {
return this.data.vin;
}
get vout() {
return this.data.vout;
}
get lockTime() {
return this.data.lockTime;
}
composers(tx) {
return [
jellyfish_buffer_1.ComposableBuffer.uInt32(() => tx.version, v => tx.version = v),
jellyfish_buffer_1.ComposableBuffer.varUIntArray(() => tx.vin, v => tx.vin = v, v => new CVin(v)),
jellyfish_buffer_1.ComposableBuffer.varUIntArray(() => tx.vout, v => tx.vout = v, v => {
if (tx.version < 4) {
return new CVoutV2(v);
}
return new CVoutV4(v);
}),
jellyfish_buffer_1.ComposableBuffer.uInt32(() => tx.lockTime, v => tx.lockTime = v)
];
}
/**
* TransactionId is the double SHA256 of transaction buffer.
* TxId are usually presented in BE order, this method return TxId in BE order.
*
* @return string transaction id
*/
get txId() {
const buffer = new smart_buffer_1.SmartBuffer();
this.toBuffer(buffer);
const hash = jellyfish_crypto_1.dSHA256(buffer.toBuffer());
return hash.reverse().toString('hex');
}
}
exports.CTransaction = CTransaction;
/**
* Composable Vin, C stands for Composable.
* Immutable by design, it implements the Vin interface for convenience.
* Bi-directional fromBuffer, toBuffer deep composer.
*/
class CVin extends jellyfish_buffer_1.ComposableBuffer {
/**
* 32 bytes, 64 in hex
*/
get txid() {
return this.data.txid;
}
get index() {
return this.data.index;
}
get script() {
return this.data.script;
}
get sequence() {
return this.data.sequence;
}
composers(vin) {
return [
// defid returns txid in BE order hence we need to reverse it
jellyfish_buffer_1.ComposableBuffer.hexBEBufferLE(32, () => vin.txid, v => vin.txid = v),
jellyfish_buffer_1.ComposableBuffer.uInt32(() => vin.index, v => vin.index = v),
jellyfish_buffer_1.ComposableBuffer.single(() => vin.script, v => vin.script = v, v => new CScript(v)),
jellyfish_buffer_1.ComposableBuffer.uInt32(() => vin.sequence, v => vin.sequence = v)
];
}
}
exports.CVin = CVin;
/**
* Composable Vout, C stands for Composable.
* Immutable by design, it implements the Vout interface for convenience.
* Bi-directional fromBuffer, toBuffer deep composer.
*
* This is Transaction V2 buffer composition
*/
class CVoutV2 extends jellyfish_buffer_1.ComposableBuffer {
get value() {
return this.data.value;
}
get script() {
return this.data.script;
}
get tokenId() {
return 0x00;
}
composers(vout) {
return [
jellyfish_buffer_1.ComposableBuffer.satoshiAsBigNumber(() => vout.value, v => vout.value = v),
jellyfish_buffer_1.ComposableBuffer.single(() => vout.script, v => vout.script = v, v => new CScript(v))
];
}
}
exports.CVoutV2 = CVoutV2;
/**
* Composable Vout, C stands for Composable.
* Immutable by design, it implements the Vout interface for convenience.
* Bi-directional fromBuffer, toBuffer deep composer.
*
* This is Transaction V4 buffer composition
*/
class CVoutV4 extends jellyfish_buffer_1.ComposableBuffer {
get value() {
return this.data.value;
}
get script() {
return this.data.script;
}
get tokenId() {
return this.data.tokenId;
}
composers(vout) {
return [
jellyfish_buffer_1.ComposableBuffer.satoshiAsBigNumber(() => vout.value, v => vout.value = v),
jellyfish_buffer_1.ComposableBuffer.single(() => vout.script, v => vout.script = v, v => new CScript(v)),
jellyfish_buffer_1.ComposableBuffer.varUInt(() => vout.tokenId, v => vout.tokenId = v)
];
}
}
exports.CVoutV4 = CVoutV4;
/**
* Composable Script, C stands for Composable.
* Immutable by design, it implements the Script interface for convenience.
* Bi-directional fromBuffer, toBuffer deep composer.
*
* This wraps the OPCode built in composer.
*/
class CScript extends jellyfish_buffer_1.ComposableBuffer {
get stack() {
return this.data.stack;
}
composers(script) {
return [
{
fromBuffer: (buffer) => {
script.stack = script_1.OP_CODES.fromBuffer(buffer);
},
toBuffer: (buffer) => {
script_1.OP_CODES.toBuffer(script.stack, buffer);
}
}
];
}
}
exports.CScript = CScript;
/**
* USE CTransactionSegWit AT YOUR OWN RISK.
* The TransactionBuilder has safety logic built-in to prevent overspent, CTransactionSegWit is its raw counter part.
*
* Composable TransactionSegWit, C stands for Composable.
* Immutable by design, it implements the TransactionSegWit interface for convenience.
* Bi-directional fromBuffer, toBuffer deep composer.
*
* @see https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki
* @see https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki
* @see https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki
*/
class CTransactionSegWit extends jellyfish_buffer_1.ComposableBuffer {
get version() {
return this.data.version;
}
get marker() {
return this.data.marker;
}
get flag() {
return this.data.flag;
}
get vin() {
return this.data.vin;
}
get vout() {
return this.data.vout;
}
get witness() {
return this.data.witness;
}
get lockTime() {
return this.data.lockTime;
}
composers(tx) {
return [
jellyfish_buffer_1.ComposableBuffer.uInt32(() => tx.version, v => tx.version = v),
jellyfish_buffer_1.ComposableBuffer.uInt8(() => tx.marker, v => tx.marker = v),
jellyfish_buffer_1.ComposableBuffer.uInt8(() => tx.flag, v => tx.flag = v),
jellyfish_buffer_1.ComposableBuffer.varUIntArray(() => tx.vin, v => tx.vin = v, v => new CVin(v)),
jellyfish_buffer_1.ComposableBuffer.varUIntArray(() => tx.vout, v => tx.vout = v, v => {
if (tx.version < 4) {
return new CVoutV2(v);
}
return new CVoutV4(v);
}),
jellyfish_buffer_1.ComposableBuffer.array(() => tx.witness, v => tx.witness = v, v => new CWitness(v), () => tx.vin.length),
jellyfish_buffer_1.ComposableBuffer.uInt32(() => tx.lockTime, v => tx.lockTime = v)
];
}
/**
* TransactionId is the double SHA256 of transaction buffer.
* TxId are usually presented in BE order, this method return TxId in BE order.
*
* @return string transaction id
*/
get txId() {
return new CTransaction(this).txId;
}
}
exports.CTransactionSegWit = CTransactionSegWit;
/**
* Composable Witness, C stands for Composable.
* Immutable by design, it implements the Witness interface for convenience.
* Bi-directional fromBuffer, toBuffer deep composer.
*/
class CWitness extends jellyfish_buffer_1.ComposableBuffer {
get scripts() {
return this.data.scripts;
}
composers(wit) {
return [
jellyfish_buffer_1.ComposableBuffer.varUIntArray(() => wit.scripts, v => wit.scripts = v, v => new CWitnessScript(v))
];
}
}
exports.CWitness = CWitness;
/**
* Composable WitnessScript, C stands for Composable.
* Immutable by design, it implements the WitnessScript interface for convenience.
* Bi-directional fromBuffer, toBuffer deep composer.
*
* This just wraps the WitnessScript with (n = VarUInt, + n Bytes).
*/
class CWitnessScript extends jellyfish_buffer_1.ComposableBuffer {
get hex() {
return this.data.hex;
}
composers(script) {
return [
{
fromBuffer: (buffer) => {
const len = jellyfish_buffer_1.readVarUInt(buffer);
script.hex = buffer.readString(len, 'hex');
},
toBuffer: (buffer) => {
jellyfish_buffer_1.writeVarUInt(script.hex.length / 2, buffer);
buffer.writeString(script.hex, 'hex');
}
}
];
}
}
exports.CWitnessScript = CWitnessScript;
//# sourceMappingURL=tx_composer.js.map