PHP WebShell
Текущая директория: /opt/BitGoJS/modules/abstract-utxo/test/offlineVault
Просмотр файла: halfSigned.ts
import * as fs from 'fs';
import assert from 'assert';
import crypto from 'crypto';
import * as t from 'io-ts';
import { decodeOrElse } from '@bitgo/sdk-core';
import * as utxolib from '@bitgo/utxo-lib';
import { createHalfSigned, getTransactionExplanation } from '../../src/offlineVault';
import { DescriptorTransaction } from '../../src/offlineVault/descriptor';
import { getFixtureRoot } from '../transaction/descriptor/fixtures.utils';
const { assertEqualFixture } = getFixtureRoot(__dirname + '/fixtures');
function getFixturesNames(): string[] {
// I'm using sync here because mocha cannot do async setup
// eslint-disable-next-line no-sync
return fs.readdirSync(__dirname + '/fixtures').filter((f) => f.endsWith('.json') && !f.endsWith('.explanation.json'));
}
const KeyPair = t.intersection([t.type({ xpub: t.string }), t.partial({ xprv: t.string })]);
const KeyWithParent = t.intersection([KeyPair, t.partial({ parent: KeyPair })]);
type KeyWithParent = t.TypeOf<typeof KeyWithParent>;
const Fixture = t.type({
walletKeys: t.array(KeyWithParent),
response: t.unknown,
});
type Fixture = t.TypeOf<typeof Fixture>;
async function readFixture(name: string): Promise<Fixture> {
const data = JSON.parse(await fs.promises.readFile(__dirname + '/fixtures/' + name, 'utf-8'));
return decodeOrElse('Fixture', Fixture, data, (e) => {
throw new Error(`failed to decode fixture ${name}: ${e}`);
});
}
function withRotatedXpubs(tx: DescriptorTransaction): DescriptorTransaction {
const { user, backup, bitgo } = tx.xpubsWithDerivationPath;
return {
...tx,
xpubsWithDerivationPath: {
user: bitgo,
backup: user,
bitgo: backup,
},
};
}
function withRandomXpubs(tx: DescriptorTransaction) {
function randomXpub() {
const bytes = crypto.getRandomValues(new Uint8Array(32));
return utxolib.bip32.fromSeed(Buffer.from(bytes)).neutered().toBase58();
}
return {
...tx,
xpubsWithDerivationPath: {
user: randomXpub(),
backup: randomXpub(),
bitgo: randomXpub(),
},
};
}
function withoutDescriptors(tx: DescriptorTransaction): DescriptorTransaction {
return {
...tx,
descriptors: [],
};
}
function getDerivationId(v: DescriptorTransaction['xpubsWithDerivationPath']): string {
const id = v.user.derivedFromParentWithSeed;
assert(id);
return id;
}
function getRootPrv(walletKeys: KeyWithParent[]): utxolib.BIP32Interface {
assert(walletKeys[0]);
assert(walletKeys[0].parent);
assert(walletKeys[0].parent.xprv);
return utxolib.bip32.fromBase58(walletKeys[0].parent.xprv);
}
describe('OfflineVaultHalfSigned', function () {
for (const fixtureName of getFixturesNames()) {
it(`can sign fixture ${fixtureName}`, async function () {
const { walletKeys, response } = await readFixture(fixtureName);
assert(DescriptorTransaction.is(response));
const rootPrv = getRootPrv(walletKeys);
const derivationId = getDerivationId(response.xpubsWithDerivationPath);
createHalfSigned('btc', rootPrv, derivationId, response);
const mutations = [withRotatedXpubs(response), withRandomXpubs(response), withoutDescriptors(response)];
for (const mutation of mutations) {
assert.throws(() => createHalfSigned('btc', rootPrv, derivationId, mutation));
}
await assertEqualFixture(
fixtureName.replace(/\.json$/, '.explanation.json'),
getTransactionExplanation('btc', response)
);
});
}
});
Выполнить команду
Для локальной разработки. Не используйте в интернете!