PHP WebShell

Текущая директория: /opt/BitGoJS/modules/utxo-lib/test/bitgo/psbt

Просмотр файла: signingAndValidation.ts

import * as assert from 'assert';
import { describe, it } from 'mocha';
import * as bs58check from 'bs58check';

import { getDefaultWalletKeys, mockReplayProtectionUnspent, mockUnspents } from '../../../src/testutil';
import {
  addReplayProtectionUnspentToPsbt,
  addWalletOutputToPsbt,
  addWalletUnspentToPsbt,
  createPsbtForNetwork,
  MAX_BIP125_RBF_SEQUENCE,
  TX_INPUT_SEQUENCE_NUMBER_FINAL,
  getInternalChainCode,
  KeyName,
  outputScripts,
  UtxoPsbt,
  WalletUnspent,
} from '../../../src/bitgo';
import { getNetworkName, Network, networks } from '../../../src';
import { createOutputScriptP2shP2pk } from '../../../src/bitgo/outputScripts';

function getScriptTypes(): outputScripts.ScriptType[] {
  return [...outputScripts.scriptTypes2Of3, 'p2shP2pk'];
}

const walletKeys = getDefaultWalletKeys();
function runTest(scriptType: outputScripts.ScriptType, signerName: KeyName, cosignerName: KeyName, network: Network) {
  const signer = walletKeys[signerName];
  const cosigner = walletKeys[cosignerName];

  const networkName = getNetworkName(network);
  const signingKeys = [
    signerName === 'user' || (cosignerName === 'user' && scriptType !== 'p2shP2pk'),
    signerName === 'backup' || (cosignerName === 'backup' && scriptType !== 'p2shP2pk'),
    signerName === 'bitgo' || (cosignerName === 'bitgo' && scriptType !== 'p2shP2pk'),
  ];

  describe(`UtxoPsbt ${[
    `scriptType=${scriptType}`,
    `network=${networkName}`,
    `signer=${signerName}`,
    `cosigner=${cosignerName}`,
  ].join(',')}`, function () {
    let psbt: UtxoPsbt;
    before('create transaction', async function () {
      // Build a fully hydrated UtxoPsbt
      psbt = createPsbtForNetwork({ network });
      psbt.updateGlobal({
        globalXpub: walletKeys.triple.map((bip32) => {
          const extendedPubkey = bip32.neutered().toBase58();
          return {
            extendedPubkey: bs58check.decode(extendedPubkey),
            masterFingerprint: bip32.fingerprint,
            path: 'm',
          };
        }),
      });

      // Add the inputs
      if (scriptType === 'p2shP2pk') {
        const unspent = mockReplayProtectionUnspent(network, BigInt(1e8), { key: signer });
        const { redeemScript } = createOutputScriptP2shP2pk(signer.publicKey);
        assert(redeemScript);
        addReplayProtectionUnspentToPsbt(psbt, unspent, redeemScript);
      } else {
        const unspents = mockUnspents(walletKeys, [scriptType], BigInt(1e8), network) as WalletUnspent<bigint>[];
        unspents.forEach((unspent) =>
          addWalletUnspentToPsbt(psbt, unspent, walletKeys, signerName, cosignerName, {
            isReplaceableByFee: true,
          })
        );
      }

      // Add the outputs
      addWalletOutputToPsbt(psbt, walletKeys, getInternalChainCode('p2sh'), 0, BigInt(1e8 - 10000));
    });

    it('can go from unsigned to fully signed', async function () {
      if (scriptType === 'p2trMusig2' && signerName === 'user' && cosignerName === 'bitgo') {
        psbt.setAllInputsMusig2NonceHD(signer);
        psbt.setAllInputsMusig2NonceHD(cosigner);
      }
      assert.ok(psbt.getSignatureValidationArray(0, { rootNodes: walletKeys.triple }).every((res) => !res));
      if (scriptType === 'p2shP2pk') {
        psbt.signAllInputs(signer);
      } else {
        psbt.signAllInputsHD(signer);
        psbt.signAllInputsHD(cosigner);
      }
      assert(psbt.validateSignaturesOfAllInputs());
      assert.deepStrictEqual(psbt.getSignatureValidationArray(0, { rootNodes: walletKeys.triple }), signingKeys);
      psbt.finalizeAllInputs();
      const tx = psbt.extractTransaction();
      assert(tx);
      if (scriptType === 'p2shP2pk') {
        tx.ins.forEach((input) => assert.strictEqual(input.sequence, TX_INPUT_SEQUENCE_NUMBER_FINAL));
      } else {
        tx.ins.forEach((input) => assert.strictEqual(input.sequence, MAX_BIP125_RBF_SEQUENCE));
      }
    });
  });
}

getScriptTypes().forEach((t) => {
  runTest(t, 'user', 'bitgo', networks.bitcoin);
  runTest(t, 'backup', 'user', networks.bitcoin);
});

Выполнить команду


Для локальной разработки. Не используйте в интернете!