PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-stx/test/unit/transactionBuilder
Просмотр файла: transferBuilder.ts
import assert from 'assert';
import should from 'should';
import { StacksMainnet, StacksTestnet } from '@stacks/network';
import { TransactionType, rawPrvToExtendedKeys } from '@bitgo/sdk-core';
import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
import { BitGoAPI } from '@bitgo/sdk-api';
import { coins } from '@bitgo/statics';
import { Stx, Tstx, StxLib } from '../../../src';
import * as testData from '../resources';
const { KeyPair } = StxLib;
describe('Stacks: Send Many Builder', function () {
const coinName = 'stx';
const coinNameTest = 'tstx';
let bitgo: TestBitGoAPI;
before(function () {
bitgo = TestBitGo.decorate(BitGoAPI, {
env: 'mock',
});
bitgo.initializeTestVars();
bitgo.safeRegister('stx', Stx.createInstance);
bitgo.safeRegister('tstx', Tstx.createInstance);
});
describe('Stx Transfer Builder', () => {
const factory = new StxLib.TransactionBuilderFactory(coins.get(coinNameTest));
const factoryProd = new StxLib.TransactionBuilderFactory(coins.get(coinName));
const initTxBuilder = () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.fee({ fee: '180' });
txBuilder.nonce(0);
txBuilder.to(testData.TX_RECIEVER.address);
txBuilder.amount('1000');
return txBuilder;
};
describe('transfer builder environment', function () {
it('should select the right network', function () {
should.equal(factory.getTransferBuilder().coinName(), 'tstx');
should.equal(factoryProd.getTransferBuilder().coinName(), 'stx');
// used type any to access protected properties
const txBuilder: any = factory.getTransferBuilder();
const txBuilderProd: any = factoryProd.getTransferBuilder();
txBuilder._network.should.deepEqual(new StacksTestnet());
txBuilderProd._network.should.deepEqual(new StacksMainnet());
});
});
describe('should build ', () => {
it('a signed transfer transaction', async () => {
const builder = initTxBuilder();
builder.fromPubKey(testData.TX_SENDER.pub);
builder.sign({ key: testData.TX_SENDER.prv });
const tx = await builder.build();
const txJson = tx.toJson();
// should.deepEqual(tx.signature.length, 1);
should.deepEqual(txJson.payload.to, testData.TX_RECIEVER.address);
should.deepEqual(txJson.payload.amount, '1000');
should.deepEqual(txJson.from, testData.TX_SENDER.address);
should.deepEqual(txJson.nonce, 0);
should.deepEqual(txJson.fee.toString(), '180');
should.deepEqual(tx.toBroadcastFormat(), testData.SIGNED_TRANSACTION);
tx.type.should.equal(TransactionType.Send);
tx.outputs.length.should.equal(1);
tx.outputs[0].address.should.equal(testData.TX_RECIEVER.address);
tx.outputs[0].value.should.equal('1000');
tx.inputs.length.should.equal(1);
tx.inputs[0].address.should.equal(testData.TX_SENDER.address);
tx.inputs[0].value.should.equal('1000');
});
it('a transfer transaction with memo', async () => {
const builder = initTxBuilder();
builder.fromPubKey(testData.TX_SENDER.pub);
builder.memo('This is an example');
builder.sign({ key: testData.TX_SENDER.prv });
const tx = await builder.build();
const txJson = tx.toJson();
should.deepEqual(txJson.payload.to, testData.TX_RECIEVER.address);
should.deepEqual(txJson.payload.amount, '1000');
should.deepEqual(txJson.payload.memo, 'This is an example');
should.deepEqual(txJson.from, testData.TX_SENDER.address);
should.deepEqual(txJson.nonce, 0);
should.deepEqual(txJson.fee.toString(), '180');
});
it('an unsigned multisig signed and verified', async () => {
const destination = 'STDE7Y8HV3RX8VBM2TZVWJTS7ZA1XB0SSC3NEVH0';
const amount = '1000';
const memo = 'test';
const kp = new KeyPair({ prv: '21d43d2ae0da1d9d04cfcaac7d397a33733881081f0b2cd038062cf0ccbb752601' });
const kp1 = new KeyPair({ prv: 'c71700b07d520a8c9731e4d0f095aa6efb91e16e25fb27ce2b72e7b698f8127a01' });
const kp2 = new KeyPair({ prv: 'e75dcb66f84287eaf347955e94fa04337298dbd95aa0dbb985771104ef1913db01' });
const txBuilder = factory.getTransferBuilder();
txBuilder.fee({
fee: '180',
});
txBuilder.to(destination);
txBuilder.amount(amount);
txBuilder.nonce(1);
txBuilder.fromPubKey([kp.getKeys().pub, kp1.getKeys().pub, kp2.getKeys().pub]);
txBuilder.numberSignatures(2);
txBuilder.memo(memo);
const tx = await txBuilder.build(); // unsigned multisig tx
const txBuilder2 = factory.getTransferBuilder();
txBuilder2.from(tx.toBroadcastFormat());
txBuilder2.sign({ key: '21d43d2ae0da1d9d04cfcaac7d397a33733881081f0b2cd038062cf0ccbb752601' });
txBuilder2.sign({ key: 'c71700b07d520a8c9731e4d0f095aa6efb91e16e25fb27ce2b72e7b698f8127a01' });
txBuilder.fromPubKey([kp.getKeys().pub, kp1.getKeys().pub, kp2.getKeys().pub]);
const signedTx = await txBuilder2.build(); // signed multisig tx
const txBuilder3 = factory.getTransferBuilder();
txBuilder3.from(signedTx.toBroadcastFormat());
const remake = await txBuilder3.build();
should.deepEqual(remake.toBroadcastFormat(), signedTx.toBroadcastFormat());
});
it('an half signed tx', async () => {
const destination = 'STDE7Y8HV3RX8VBM2TZVWJTS7ZA1XB0SSC3NEVH0';
const amount = '1000';
const memo = 'test';
const kp = new KeyPair({ prv: '21d43d2ae0da1d9d04cfcaac7d397a33733881081f0b2cd038062cf0ccbb752601' });
const kp1 = new KeyPair({ prv: 'c71700b07d520a8c9731e4d0f095aa6efb91e16e25fb27ce2b72e7b698f8127a01' });
const kp2 = new KeyPair({ prv: 'e75dcb66f84287eaf347955e94fa04337298dbd95aa0dbb985771104ef1913db01' });
const txBuilder = factory.getTransferBuilder();
txBuilder.fee({
fee: '180',
});
txBuilder.to(destination);
txBuilder.amount(amount);
txBuilder.nonce(1);
txBuilder.sign({ key: '21d43d2ae0da1d9d04cfcaac7d397a33733881081f0b2cd038062cf0ccbb752601' });
txBuilder.fromPubKey([kp.getKeys(true).pub, kp1.getKeys(true).pub, kp2.getKeys(true).pub]);
txBuilder.numberSignatures(2);
txBuilder.memo(memo);
const tx = await txBuilder.build(); // half signed multisig tx
should.deepEqual(tx.signature.length, 1);
const txBuilder2 = factory.getTransferBuilder();
txBuilder2.from(tx.toBroadcastFormat());
txBuilder2.sign({ key: 'c71700b07d520a8c9731e4d0f095aa6efb91e16e25fb27ce2b72e7b698f8127a01' });
txBuilder2.fromPubKey([kp.getKeys(true).pub, kp1.getKeys(true).pub, kp2.getKeys(true).pub]);
const signedTx = await txBuilder2.build();
should.deepEqual(
signedTx.toBroadcastFormat(),
'808000000004012fe507c09dbb23c3b7e5d166c81fc4b87692510b000000000000000100000000000000b4000000030201091538373641a50a4ebd6f653bb7b477489aceec50eff963072a838d2eaf50e4784c7c6d1490f57b899f0f04c215fce9176d9bb4ce19bfb07499c48878675a1f02008074202e04a7c777b4cdd26ad3fd35194311536113666d81a3840148e59eb43f274d88768ef1202d55633bfdcde8c6057932107354f406af6c378b6ea6b75d1a00038e3c4529395611be9abf6fa3b6987e81d402385e3d605a073f42f407565a4a3d000203020000000000051a1ae3f911d8f1d46d7416bfbe4b593fd41eac19cb00000000000003e874657374000000000000000000000000000000000000000000000000000000000000'
);
should.deepEqual(signedTx.signature.length, 2);
});
it('an half signed tx with xprv', async () => {
const destination = 'STDE7Y8HV3RX8VBM2TZVWJTS7ZA1XB0SSC3NEVH0';
const amount = '1000';
const memo = 'test';
const kp = new KeyPair({ prv: '21d43d2ae0da1d9d04cfcaac7d397a33733881081f0b2cd038062cf0ccbb752601' });
const kp1 = new KeyPair({ prv: 'c71700b07d520a8c9731e4d0f095aa6efb91e16e25fb27ce2b72e7b698f8127a01' });
const kp2 = new KeyPair({ prv: 'e75dcb66f84287eaf347955e94fa04337298dbd95aa0dbb985771104ef1913db01' });
const txBuilder = factory.getTransferBuilder();
txBuilder.fee({
fee: '180',
});
txBuilder.to(destination);
txBuilder.amount(amount);
txBuilder.nonce(1);
txBuilder.sign({ key: '21d43d2ae0da1d9d04cfcaac7d397a33733881081f0b2cd038062cf0ccbb752601' });
txBuilder.fromPubKey([kp.getKeys(true).pub, kp1.getKeys(true).pub, kp2.getKeys(true).pub]);
txBuilder.numberSignatures(2);
txBuilder.memo(memo);
const tx = await txBuilder.build(); // half signed multisig tx
should.deepEqual(tx.signature.length, 1);
const txBuilder2 = factory.getTransferBuilder();
txBuilder2.from(tx.toBroadcastFormat());
txBuilder2.fromPubKey([kp.getKeys(true).pub, kp1.getKeys(true).pub, kp2.getKeys(true).pub]);
const extendedKey = rawPrvToExtendedKeys(kp1.getKeys(false).prv!);
txBuilder2.sign({ key: extendedKey.xprv });
const signedTx = await txBuilder2.build();
should.deepEqual(
signedTx.toBroadcastFormat(),
'808000000004012fe507c09dbb23c3b7e5d166c81fc4b87692510b000000000000000100000000000000b4000000030201091538373641a50a4ebd6f653bb7b477489aceec50eff963072a838d2eaf50e4784c7c6d1490f57b899f0f04c215fce9176d9bb4ce19bfb07499c48878675a1f02008074202e04a7c777b4cdd26ad3fd35194311536113666d81a3840148e59eb43f274d88768ef1202d55633bfdcde8c6057932107354f406af6c378b6ea6b75d1a00038e3c4529395611be9abf6fa3b6987e81d402385e3d605a073f42f407565a4a3d000203020000000000051a1ae3f911d8f1d46d7416bfbe4b593fd41eac19cb00000000000003e874657374000000000000000000000000000000000000000000000000000000000000'
);
should.deepEqual(signedTx.signature.length, 2);
});
it('a multisig transfer transaction', async () => {
const builder = initTxBuilder();
builder.memo('test memo');
builder.sign({ key: testData.prv1 });
builder.sign({ key: testData.prv2 });
builder.fromPubKey([testData.pub1, testData.pub2, testData.pub3]);
const tx = await builder.build();
should.deepEqual(tx.toBroadcastFormat(), testData.MULTI_SIG_SIGNED_TRANSACTION);
should.deepEqual(tx.signature.length, 2);
});
it('a multisig serialized transfer transaction', async () => {
const builder = factory.from(testData.MULTI_SIG_SIGNED_TRANSACTION);
const tx = await builder.build();
should.deepEqual(tx.toBroadcastFormat(), testData.MULTI_SIG_SIGNED_TRANSACTION);
});
it('a transfer transaction signed multiple times', async () => {
const builder = initTxBuilder();
builder.memo('test memo');
builder.sign({ key: testData.prv1 });
builder.sign({ key: testData.prv2 });
builder.fromPubKey([testData.pub1, testData.pub2, testData.pub3]);
builder.numberSignatures(2);
const tx = await builder.build();
const txJson = tx.toJson();
should.deepEqual(tx.signature.length, 2);
should.deepEqual(txJson.fee.toString(), '180');
should.deepEqual(txJson.payload.to, testData.TX_RECIEVER.address);
should.deepEqual(txJson.payload.memo, 'test memo');
should.deepEqual(txJson.payload.amount, '1000');
});
it('a transfer transaction with amount 0', async () => {
const builder = initTxBuilder();
builder.amount('0');
builder.fromPubKey(testData.TX_SENDER.pub);
builder.sign({ key: testData.TX_SENDER.prv });
const tx = await builder.build();
const txJson = tx.toJson();
should.deepEqual(txJson.payload.to, testData.TX_RECIEVER.address);
should.deepEqual(txJson.payload.amount, '0');
should.deepEqual(txJson.from, testData.TX_SENDER.address);
should.deepEqual(txJson.fee.toString(), '180');
});
it('get pubkey of a transfer transaction signed 1', async () => {
const txBuilder2: any = factory.getTransferBuilder();
txBuilder2.from(testData.SIGNED_TRANSACTION_PK_1_3);
should.deepEqual(txBuilder2._fromPubKeys, [testData.pub1, testData.pub2, testData.pub3]);
});
it('get pubkey of a transfer transaction signed 2', async () => {
const txBuilder2: any = factory.getTransferBuilder();
txBuilder2.from(testData.SIGNED_TRANSACTION_PK_2_3);
should.deepEqual(txBuilder2._fromPubKeys, [testData.pub1, testData.pub2, testData.pub3]);
});
it('a transfer transaction signed multiple times with mid key no signer', async () => {
const builder = initTxBuilder();
builder.memo('test');
builder.sign({ key: testData.prv1 });
builder.fromPubKey([testData.pub1, testData.pub2, testData.pub3]);
builder.numberSignatures(2);
const tx = await builder.build();
const txBuilder2 = factory.getTransferBuilder();
txBuilder2.from(tx.toBroadcastFormat());
txBuilder2.sign({ key: testData.prv3 });
const signedTx = await txBuilder2.build();
const txJson = signedTx.toJson();
should.deepEqual(signedTx.toBroadcastFormat(), testData.SIGNED_TRANSACTION_PK_1_3);
should.deepEqual(signedTx.signature.length, 2);
should.deepEqual(txJson.fee.toString(), '180');
should.deepEqual(txJson.payload.to, testData.TX_RECIEVER.address);
should.deepEqual(txJson.payload.memo, 'test');
should.deepEqual(txJson.payload.amount, '1000');
});
it('a transfer transaction signed multiple times with first key no signer', async () => {
const builder = initTxBuilder();
builder.memo('test');
builder.sign({ key: testData.prv2 });
builder.fromPubKey([testData.pub1, testData.pub2, testData.pub3]);
builder.numberSignatures(2);
const tx = await builder.build();
const txBuilder2 = factory.getTransferBuilder();
txBuilder2.from(tx.toBroadcastFormat());
txBuilder2.sign({ key: testData.prv3 });
const signedTx = await txBuilder2.build();
const txJson = signedTx.toJson();
should.deepEqual(signedTx.toBroadcastFormat(), testData.SIGNED_TRANSACTION_PK_2_3);
should.deepEqual(signedTx.signature.length, 2);
should.deepEqual(txJson.fee.toString(), '180');
should.deepEqual(txJson.payload.to, testData.TX_RECIEVER.address);
should.deepEqual(txJson.payload.memo, 'test');
should.deepEqual(txJson.payload.amount, '1000');
});
describe('serialized transactions', () => {
it('a non signed transfer transaction from serialized', async () => {
const builder = factory.from(testData.RAW_TX_UNSIGNED);
builder.sign({ key: testData.TX_SENDER.prv });
const tx2 = await builder.build();
should.deepEqual(tx2.toBroadcastFormat(), testData.SIGNED_TRANSACTION);
tx2.type.should.equal(TransactionType.Send);
});
it('a signed transfer transaction from serialized', async () => {
const txBuilder = factory.from(testData.SIGNED_TRANSACTION);
const tx = await txBuilder.build();
should.deepEqual(tx.toBroadcastFormat(), testData.SIGNED_TRANSACTION);
tx.type.should.equal(TransactionType.Send);
});
it('a signed transfer transaction from serilaized 1', async () => {
const txBuilder = factory.from(testData.SIGNED_TRANSACTION_PK_2_3);
const tx = await txBuilder.build();
should.deepEqual(tx.toBroadcastFormat(), testData.SIGNED_TRANSACTION_PK_2_3);
tx.type.should.equal(TransactionType.Send);
});
it('a signed transfer transaction from serilaized 2', async () => {
const txBuilder = factory.from(testData.SIGNED_TRANSACTION_PK_1_3);
const tx = await txBuilder.build();
should.deepEqual(tx.toBroadcastFormat(), testData.SIGNED_TRANSACTION_PK_1_3);
tx.type.should.equal(TransactionType.Send);
});
});
describe('should fail', () => {
it('a transfer transaction with an invalid key', () => {
const builder = initTxBuilder();
assert.throws(() => builder.sign({ key: 'invalidKey' }), /Unsupported private key/);
});
it('a transfer transaction with an invalid destination address', () => {
const txBuilder = factory.getTransferBuilder();
assert.throws(() => txBuilder.to('invalidaddress'), /Invalid address/);
});
it('a transfer transaction with an invalid amount: text value', () => {
const txBuilder = factory.getTransferBuilder();
assert.throws(() => txBuilder.amount('invalidamount'), /Invalid amount/);
});
it('a transfer transaction with an invalid amount: negative value', () => {
const txBuilder = factory.getTransferBuilder();
assert.throws(() => txBuilder.amount('-5'), /Invalid amount/);
});
it('a transfer transaction with an invalid memo', async () => {
const txBuilder = factory.getTransferBuilder();
assert.throws(() => txBuilder.memo('This is a memo that is too long for a transaction'), /Memo is too long/);
});
});
});
});
});
Выполнить команду
Для локальной разработки. Не используйте в интернете!