From 816c80599611582e9ab69906f58358bc63137093 Mon Sep 17 00:00:00 2001 From: SpiderMan <2153968377@qq.com> Date: Wed, 4 Sep 2024 15:37:15 +0800 Subject: [PATCH 1/2] feature: converge payment related methods --- ts_src/payments/index.ts | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/ts_src/payments/index.ts b/ts_src/payments/index.ts index bd1ac0d84..c00019c99 100644 --- a/ts_src/payments/index.ts +++ b/ts_src/payments/index.ts @@ -52,5 +52,26 @@ export type StackFunction = () => Stack; export { embed, p2ms, p2pk, p2pkh, p2sh, p2wpkh, p2wsh, p2tr }; -// TODO -// witness commitment +/** + * Checks if a given payment factory can generate a payment script from a given script. + * @param payment The payment factory to check. + * @returns A function that takes a script and returns a boolean indicating whether the payment factory can generate a payment script from the script. + */ +function isPaymentFactory(payment: any): (script: Buffer) => boolean { + return (script: Buffer): boolean => { + try { + payment({ output: script }); + return true; + } catch (err) { + return false; + } + }; +} + +export const isP2MS = isPaymentFactory(p2ms); +export const isP2PK = isPaymentFactory(p2pk); +export const isP2PKH = isPaymentFactory(p2pkh); +export const isP2WPKH = isPaymentFactory(p2wpkh); +export const isP2WSHScript = isPaymentFactory(p2wsh); +export const isP2SHScript = isPaymentFactory(p2sh); +export const isP2TR = isPaymentFactory(p2tr); From ebdb5ce0c8680353bbf2c217d01ba96317d765ee Mon Sep 17 00:00:00 2001 From: SpiderMan <2153968377@qq.com> Date: Wed, 4 Sep 2024 15:44:53 +0800 Subject: [PATCH 2/2] feature: update the reference of payment method judgment --- src/payments/index.d.ts | 7 +++++++ src/payments/index.js | 33 ++++++++++++++++++++++++++++++--- src/psbt.js | 26 ++++++++++++-------------- src/psbt/bip371.js | 9 +++++---- src/psbt/psbtutils.d.ts | 7 ------- src/psbt/psbtutils.js | 30 ------------------------------ ts_src/psbt.ts | 4 +++- ts_src/psbt/bip371.ts | 2 +- ts_src/psbt/psbtutils.ts | 25 ------------------------- 9 files changed, 58 insertions(+), 85 deletions(-) diff --git a/src/payments/index.d.ts b/src/payments/index.d.ts index 8eafc319e..50ab36226 100644 --- a/src/payments/index.d.ts +++ b/src/payments/index.d.ts @@ -46,3 +46,10 @@ export type StackElement = Buffer | number; export type Stack = StackElement[]; export type StackFunction = () => Stack; export { embed, p2ms, p2pk, p2pkh, p2sh, p2wpkh, p2wsh, p2tr }; +export declare const isP2MS: (script: Buffer) => boolean; +export declare const isP2PK: (script: Buffer) => boolean; +export declare const isP2PKH: (script: Buffer) => boolean; +export declare const isP2WPKH: (script: Buffer) => boolean; +export declare const isP2WSHScript: (script: Buffer) => boolean; +export declare const isP2SHScript: (script: Buffer) => boolean; +export declare const isP2TR: (script: Buffer) => boolean; diff --git a/src/payments/index.js b/src/payments/index.js index f820ddeee..abe54a4b1 100644 --- a/src/payments/index.js +++ b/src/payments/index.js @@ -1,6 +1,13 @@ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); -exports.p2tr = +exports.isP2TR = + exports.isP2SHScript = + exports.isP2WSHScript = + exports.isP2WPKH = + exports.isP2PKH = + exports.isP2PK = + exports.isP2MS = + exports.p2tr = exports.p2wsh = exports.p2wpkh = exports.p2sh = @@ -65,5 +72,25 @@ Object.defineProperty(exports, 'p2tr', { return p2tr_1.p2tr; }, }); -// TODO -// witness commitment +/** + * Checks if a given payment factory can generate a payment script from a given script. + * @param payment The payment factory to check. + * @returns A function that takes a script and returns a boolean indicating whether the payment factory can generate a payment script from the script. + */ +function isPaymentFactory(payment) { + return script => { + try { + payment({ output: script }); + return true; + } catch (err) { + return false; + } + }; +} +exports.isP2MS = isPaymentFactory(p2ms_1.p2ms); +exports.isP2PK = isPaymentFactory(p2pk_1.p2pk); +exports.isP2PKH = isPaymentFactory(p2pkh_1.p2pkh); +exports.isP2WPKH = isPaymentFactory(p2wpkh_1.p2wpkh); +exports.isP2WSHScript = isPaymentFactory(p2wsh_1.p2wsh); +exports.isP2SHScript = isPaymentFactory(p2sh_1.p2sh); +exports.isP2TR = isPaymentFactory(p2tr_1.p2tr); diff --git a/src/psbt.js b/src/psbt.js index b071f374f..1be78b7fe 100644 --- a/src/psbt.js +++ b/src/psbt.js @@ -13,6 +13,7 @@ const bscript = require('./script'); const transaction_1 = require('./transaction'); const bip371_1 = require('./psbt/bip371'); const psbtutils_1 = require('./psbt/psbtutils'); +const index_1 = require('./payments/index'); /** * These are the default arguments for a Psbt instance. */ @@ -1242,7 +1243,7 @@ function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) { prevout.value, sighashType, ); - } else if ((0, psbtutils_1.isP2WPKH)(meaningfulScript)) { + } else if ((0, index_1.isP2WPKH)(meaningfulScript)) { // P2WPKH uses the P2PKH template for prevoutScript when signing const signingScript = payments.p2pkh({ hash: meaningfulScript.slice(2), @@ -1304,7 +1305,7 @@ function getAllTaprootHashesForSig(inputIndex, input, inputs, cache) { } function getPrevoutTaprootKey(inputIndex, input, cache) { const { script } = getScriptAndAmountFromUtxo(inputIndex, input, cache); - return (0, psbtutils_1.isP2TR)(script) ? script.subarray(2, 34) : null; + return (0, index_1.isP2TR)(script) ? script.subarray(2, 34) : null; } function trimTaprootSig(signature) { return signature.length === 64 ? signature : signature.subarray(0, 64); @@ -1438,7 +1439,7 @@ function getScriptFromInput(inputIndex, input, cache) { res.script = input.witnessUtxo.script; } } - if (input.witnessScript || (0, psbtutils_1.isP2WPKH)(res.script)) { + if (input.witnessScript || (0, index_1.isP2WPKH)(res.script)) { res.isSegwit = true; } return res; @@ -1679,10 +1680,10 @@ function getMeaningfulScript( redeemScript, witnessScript, ) { - const isP2SH = (0, psbtutils_1.isP2SHScript)(script); + const isP2SH = (0, index_1.isP2SHScript)(script); const isP2SHP2WSH = - isP2SH && redeemScript && (0, psbtutils_1.isP2WSHScript)(redeemScript); - const isP2WSH = (0, psbtutils_1.isP2WSHScript)(script); + isP2SH && redeemScript && (0, index_1.isP2WSHScript)(redeemScript); + const isP2WSH = (0, index_1.isP2WSHScript)(script); if (isP2SH && redeemScript === undefined) throw new Error('scriptPubkey is P2SH but redeemScript missing'); if ((isP2WSH || isP2SHP2WSH) && witnessScript === undefined) @@ -1717,18 +1718,15 @@ function getMeaningfulScript( }; } function checkInvalidP2WSH(script) { - if ( - (0, psbtutils_1.isP2WPKH)(script) || - (0, psbtutils_1.isP2SHScript)(script) - ) { + if ((0, index_1.isP2WPKH)(script) || (0, index_1.isP2SHScript)(script)) { throw new Error('P2WPKH or P2SH can not be contained within P2WSH'); } } function classifyScript(script) { - if ((0, psbtutils_1.isP2WPKH)(script)) return 'witnesspubkeyhash'; - if ((0, psbtutils_1.isP2PKH)(script)) return 'pubkeyhash'; - if ((0, psbtutils_1.isP2MS)(script)) return 'multisig'; - if ((0, psbtutils_1.isP2PK)(script)) return 'pubkey'; + if ((0, index_1.isP2WPKH)(script)) return 'witnesspubkeyhash'; + if ((0, index_1.isP2PKH)(script)) return 'pubkeyhash'; + if ((0, index_1.isP2MS)(script)) return 'multisig'; + if ((0, index_1.isP2PK)(script)) return 'pubkey'; return 'nonstandard'; } function range(n) { diff --git a/src/psbt/bip371.js b/src/psbt/bip371.js index 0fe92721e..f42eef0f4 100644 --- a/src/psbt/bip371.js +++ b/src/psbt/bip371.js @@ -15,8 +15,9 @@ exports.checkTaprootInputForSigs = const types_1 = require('../types'); const transaction_1 = require('../transaction'); const psbtutils_1 = require('./psbtutils'); -const bip341_1 = require('../payments/bip341'); const payments_1 = require('../payments'); +const bip341_1 = require('../payments/bip341'); +const payments_2 = require('../payments'); const psbtutils_2 = require('./psbtutils'); /** * Converts a public key to an X-only public key. @@ -77,7 +78,7 @@ function isTaprootInput(input) { input.tapMerkleRoot || (input.tapLeafScript && input.tapLeafScript.length) || (input.tapBip32Derivation && input.tapBip32Derivation.length) || - (input.witnessUtxo && (0, psbtutils_1.isP2TR)(input.witnessUtxo.script)) + (input.witnessUtxo && (0, payments_1.isP2TR)(input.witnessUtxo.script)) ) ); } @@ -95,7 +96,7 @@ function isTaprootOutput(output, script) { output.tapInternalKey || output.tapTree || (output.tapBip32Derivation && output.tapBip32Derivation.length) || - (script && (0, psbtutils_1.isP2TR)(script)) + (script && (0, payments_1.isP2TR)(script)) ) ); } @@ -145,7 +146,7 @@ function checkTaprootScriptPubkey(outputData, newOutputData) { */ function getTaprootScripPubkey(tapInternalKey, tapTree) { const scriptTree = tapTree && tapTreeFromList(tapTree.leaves); - const { output } = (0, payments_1.p2tr)({ + const { output } = (0, payments_2.p2tr)({ internalPubkey: tapInternalKey, scriptTree, }); diff --git a/src/psbt/psbtutils.d.ts b/src/psbt/psbtutils.d.ts index b6351cf55..eebc9ca8c 100644 --- a/src/psbt/psbtutils.d.ts +++ b/src/psbt/psbtutils.d.ts @@ -1,12 +1,5 @@ /// import { PsbtInput } from 'bip174/src/lib/interfaces'; -export declare const isP2MS: (script: Buffer) => boolean; -export declare const isP2PK: (script: Buffer) => boolean; -export declare const isP2PKH: (script: Buffer) => boolean; -export declare const isP2WPKH: (script: Buffer) => boolean; -export declare const isP2WSHScript: (script: Buffer) => boolean; -export declare const isP2SHScript: (script: Buffer) => boolean; -export declare const isP2TR: (script: Buffer) => boolean; /** * Converts a witness stack to a script witness. * @param witness The witness stack to convert. diff --git a/src/psbt/psbtutils.js b/src/psbt/psbtutils.js index 8173e81d9..a20ab4e9e 100644 --- a/src/psbt/psbtutils.js +++ b/src/psbt/psbtutils.js @@ -5,41 +5,11 @@ exports.signatureBlocksAction = exports.pubkeyInScript = exports.pubkeyPositionInScript = exports.witnessStackToScriptWitness = - exports.isP2TR = - exports.isP2SHScript = - exports.isP2WSHScript = - exports.isP2WPKH = - exports.isP2PKH = - exports.isP2PK = - exports.isP2MS = void 0; const varuint = require('bip174/src/lib/converter/varint'); const bscript = require('../script'); const transaction_1 = require('../transaction'); const crypto_1 = require('../crypto'); -const payments = require('../payments'); -/** - * Checks if a given payment factory can generate a payment script from a given script. - * @param payment The payment factory to check. - * @returns A function that takes a script and returns a boolean indicating whether the payment factory can generate a payment script from the script. - */ -function isPaymentFactory(payment) { - return script => { - try { - payment({ output: script }); - return true; - } catch (err) { - return false; - } - }; -} -exports.isP2MS = isPaymentFactory(payments.p2ms); -exports.isP2PK = isPaymentFactory(payments.p2pk); -exports.isP2PKH = isPaymentFactory(payments.p2pkh); -exports.isP2WPKH = isPaymentFactory(payments.p2wpkh); -exports.isP2WSHScript = isPaymentFactory(payments.p2wsh); -exports.isP2SHScript = isPaymentFactory(payments.p2sh); -exports.isP2TR = isPaymentFactory(payments.p2tr); /** * Converts a witness stack to a script witness. * @param witness The witness stack to convert. diff --git a/ts_src/psbt.ts b/ts_src/psbt.ts index c73574035..313eadf84 100644 --- a/ts_src/psbt.ts +++ b/ts_src/psbt.ts @@ -35,6 +35,8 @@ import { witnessStackToScriptWitness, checkInputForSig, pubkeyInScript, +} from './psbt/psbtutils'; +import { isP2MS, isP2PK, isP2PKH, @@ -42,7 +44,7 @@ import { isP2WSHScript, isP2SHScript, isP2TR, -} from './psbt/psbtutils'; +} from './payments/index'; export interface TransactionInput { hash: string | Buffer; diff --git a/ts_src/psbt/bip371.ts b/ts_src/psbt/bip371.ts index 573264ab9..0f42cf117 100644 --- a/ts_src/psbt/bip371.ts +++ b/ts_src/psbt/bip371.ts @@ -14,8 +14,8 @@ import { Transaction } from '../transaction'; import { witnessStackToScriptWitness, pubkeyPositionInScript, - isP2TR, } from './psbtutils'; +import { isP2TR } from '../payments'; import { tweakKey, tapleafHash, diff --git a/ts_src/psbt/psbtutils.ts b/ts_src/psbt/psbtutils.ts index bc72db595..d88dc38e0 100644 --- a/ts_src/psbt/psbtutils.ts +++ b/ts_src/psbt/psbtutils.ts @@ -3,31 +3,6 @@ import { PartialSig, PsbtInput } from 'bip174/src/lib/interfaces'; import * as bscript from '../script'; import { Transaction } from '../transaction'; import { hash160 } from '../crypto'; -import * as payments from '../payments'; - -/** - * Checks if a given payment factory can generate a payment script from a given script. - * @param payment The payment factory to check. - * @returns A function that takes a script and returns a boolean indicating whether the payment factory can generate a payment script from the script. - */ -function isPaymentFactory(payment: any): (script: Buffer) => boolean { - return (script: Buffer): boolean => { - try { - payment({ output: script }); - return true; - } catch (err) { - return false; - } - }; -} - -export const isP2MS = isPaymentFactory(payments.p2ms); -export const isP2PK = isPaymentFactory(payments.p2pk); -export const isP2PKH = isPaymentFactory(payments.p2pkh); -export const isP2WPKH = isPaymentFactory(payments.p2wpkh); -export const isP2WSHScript = isPaymentFactory(payments.p2wsh); -export const isP2SHScript = isPaymentFactory(payments.p2sh); -export const isP2TR = isPaymentFactory(payments.p2tr); /** * Converts a witness stack to a script witness.