diff --git a/package-lock.json b/package-lock.json index 2105962..a6db1a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -329,6 +329,11 @@ "safe-buffer": "^5.1.2" } }, + "buffer-reverse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-reverse/-/buffer-reverse-1.0.1.tgz", + "integrity": "sha1-SSg8jvpvkBvAH6MwTQYCeXGuL2A=" + }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", diff --git a/package.json b/package.json index a3f06c4..e0a5782 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "bip66": "^1.1.0", "bitcoin-ops": "^1.4.0", "bs58check": "^2.0.0", + "buffer-reverse": "^1.0.1", "create-hash": "^1.1.0", "create-hmac": "^1.1.3", "merkle-lib": "^2.0.10", diff --git a/src/transaction.js b/src/transaction.js index c4e6506..9239d24 100644 --- a/src/transaction.js +++ b/src/transaction.js @@ -1,11 +1,13 @@ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); +const bip174_1 = require('bip174'); const bufferutils = require('./bufferutils'); const bufferutils_1 = require('./bufferutils'); const bcrypto = require('./crypto'); const bscript = require('./script'); const script_1 = require('./script'); const types = require('./types'); +const reverse = require('buffer-reverse'); const typeforce = require('typeforce'); const varuint = require('varuint-bitcoin'); function varSliceSize(someScript) { @@ -378,6 +380,28 @@ class Transaction { toHex() { return this.toBuffer(undefined, undefined).toString('hex'); } + toPsbt() { + const outputs = this.outs.map(output => ({ + script: output.script.toString('hex'), + tokens: output.value, + })); + const utxos = this.ins.map(input => ({ + id: reverse(input.hash).toString('hex'), + vout: input.index, + sequence: input.sequence, + })); + const timelock = this.locktime; + const { version } = this; + const { psbt } = bip174_1.createPsbt({ + outputs, + utxos, + timelock, + version, + }); + // TODO: Add signature data to PSBT + // TODO: Merge with imported PSBT if exists so we don't lose data + return psbt; + } setInputScript(index, scriptSig) { typeforce(types.tuple(types.Number, types.Buffer), arguments); this.ins[index].script = scriptSig; diff --git a/ts_src/transaction.ts b/ts_src/transaction.ts index 218d004..358532d 100644 --- a/ts_src/transaction.ts +++ b/ts_src/transaction.ts @@ -1,3 +1,4 @@ +import { createPsbt } from 'bip174'; import * as bufferutils from './bufferutils'; import { reverseBuffer } from './bufferutils'; import * as bcrypto from './crypto'; @@ -5,6 +6,7 @@ import * as bscript from './script'; import { OPS as opcodes } from './script'; import * as types from './types'; +const reverse = require('buffer-reverse'); const typeforce = require('typeforce'); const varuint = require('varuint-bitcoin'); @@ -501,6 +503,35 @@ export class Transaction { return this.toBuffer(undefined, undefined).toString('hex'); } + toPsbt(): string { + const outputs = this.outs.map(output => ({ + script: output.script.toString('hex'), + tokens: (output as Output).value, + })); + + const utxos = this.ins.map(input => ({ + id: reverse(input.hash).toString('hex'), + vout: input.index, + sequence: input.sequence, + })); + + const timelock = this.locktime; + const { version } = this; + + const { psbt } = createPsbt({ + outputs, + utxos, + timelock, + version, + }); + + // TODO: Add signature data to PSBT + + // TODO: Merge with imported PSBT if exists so we don't lose data + + return psbt; + } + setInputScript(index: number, scriptSig: Buffer): void { typeforce(types.tuple(types.Number, types.Buffer), arguments); diff --git a/types/transaction.d.ts b/types/transaction.d.ts index 9bdba19..d5bdd9f 100644 --- a/types/transaction.d.ts +++ b/types/transaction.d.ts @@ -52,6 +52,7 @@ export declare class Transaction { getId(): string; toBuffer(buffer?: Buffer, initialOffset?: number): Buffer; toHex(): string; + toPsbt(): string; setInputScript(index: number, scriptSig: Buffer): void; setWitness(index: number, witness: Buffer[]): void; private __byteLength;