PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-cspr/test/unit/lib/transactionBuilder
Просмотр файла: transferBuilder.ts
import assert from 'assert';
import should from 'should';
import { DeployUtil, CLOption, CLString, CLU512, CLU64, CLValueBuilder } from 'casper-js-sdk';
import BigNumber from 'bignumber.js';
import { KeyPair, TransactionBuilderFactory } from '../../../../src/lib';
import * as testData from '../../../fixtures/resources';
import { Transaction } from '../../../../src/lib/transaction';
import { DEFAULT_CHAIN_NAMES } from '../../../../src/lib/constants';
import { coins } from '@bitgo/statics';
describe('Casper Transfer Builder', () => {
const factory = new TransactionBuilderFactory(coins.get('tcspr'));
const factoryProd = new TransactionBuilderFactory(coins.get('cspr'));
const owner1Address = new KeyPair({ pub: testData.ACCOUNT_1.publicKey }).getAddress();
const owner2Address = new KeyPair({ pub: testData.ACCOUNT_2.publicKey }).getAddress();
const initTxTransferBuilder = () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.fee({ gasLimit: testData.FEE.gasLimit, gasPrice: testData.FEE.gasPrice });
txBuilder.source({ address: owner1Address });
txBuilder.to(owner2Address);
txBuilder.transferId(255);
return txBuilder;
};
describe('transfer builder environment', function () {
it('should select the right chain name', function () {
should.equal(factory.getTransferBuilder().coinName(), 'tcspr');
should.equal(factoryProd.getTransferBuilder().coinName(), 'cspr');
should.equal(factory.getTransferBuilder().chainName, DEFAULT_CHAIN_NAMES.testnet);
should.equal(factoryProd.getTransferBuilder().chainName, DEFAULT_CHAIN_NAMES.mainnet);
});
});
describe('should build ', () => {
describe('non serialized transactions', () => {
it('should build a transaction without transferId', async function () {
const txBuilder = factory.getTransferBuilder();
txBuilder.fee({ gasLimit: testData.FEE.gasLimit, gasPrice: testData.FEE.gasPrice });
txBuilder.source({ address: owner1Address });
txBuilder.to(owner2Address);
txBuilder.amount(testData.MIN_MOTES_AMOUNT);
txBuilder.sign({ key: testData.ACCOUNT_1.privateKey });
const tx = (await txBuilder.build()) as Transaction;
const txJson = tx.toJson();
should.exist(tx.casperTx.approvals, 'There are no approvals');
should.deepEqual(tx.casperTx.approvals.length, 1, 'Error in the number of signatures');
should.deepEqual(tx.casperTx.approvals[0].signer, owner1Address, 'Error in the signature');
should.exist(tx.casperTx.hash, 'There is no hash');
should.exist(txJson.from, 'There is no from');
should.deepEqual(txJson.from, owner1Address, 'The recipient does not match');
should.exist(tx.casperTx.header.gasPrice, 'There is no gasPrice');
should.equal(
tx.casperTx.header.gasPrice.toString(),
testData.FEE.gasPrice,
'Gas price does not match expected'
);
should.exist(txJson.fee.gasLimit, 'Gas Limit is not defined');
should.equal(txJson.fee.gasLimit, testData.FEE.gasLimit);
should.equal(txJson.to, owner2Address, 'To address was not the expected one');
should.equal(txJson.amount, testData.MIN_MOTES_AMOUNT, 'Amount was not as expected');
should.equal(txJson.transferId, undefined);
});
it('should build a transaction to an address from an ed25519 key', async function () {
const ed25519Address = '01513fa90c1a74c34a8958dd86055e9736edb1ead918bd4d4d750ca851946be7aa';
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
builder.to(ed25519Address);
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
should.equal(txJson.to, ed25519Address);
});
it('should build a transaction with transferId of type string', async function () {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT).transferId('26794144639134510');
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
should.equal(txJson.transferId, '26794144639134510');
});
it('should build a transaction with large numeric transfer id value', async function () {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT).transferId(26794144639134510);
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
should.equal(txJson.transferId, '26794144639134510');
});
it('a signed transfer transaction', async () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
builder.sign({ key: testData.ACCOUNT_1.privateKey });
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
should.exist(tx.casperTx.approvals, 'There are no approvals');
should.deepEqual(tx.casperTx.approvals.length, 1, 'Error in the number of signatures');
should.deepEqual(tx.casperTx.approvals[0].signer, owner1Address, 'Error in the signature');
should.exist(tx.casperTx.hash, 'There is no hash');
should.exist(txJson.from, 'There is no from');
should.deepEqual(txJson.from, owner1Address, 'The recipient does not match');
should.exist(tx.casperTx.header.gasPrice, 'There is no gasPrice');
should.equal(
tx.casperTx.header.gasPrice.toString(),
testData.FEE.gasPrice,
'Gas price does not match expected'
);
should.exist(txJson.fee.gasLimit, 'Gas Limit is not defined');
should.equal(txJson.fee.gasLimit, testData.FEE.gasLimit);
should.equal(txJson.to, owner2Address, 'To address was not the expected one');
should.equal(txJson.amount, testData.MIN_MOTES_AMOUNT, 'Amount was not as expected');
});
it('a signed transfer transaction using extended key', async () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
builder.sign({ key: testData.ACCOUNT_1.xPrivateKey });
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
should.exist(tx.casperTx.approvals, 'There are no approvals');
should.deepEqual(tx.casperTx.approvals.length, 1, 'Error in the number of signatures');
should.deepEqual(tx.casperTx.approvals[0].signer, owner1Address, 'Error in the signature');
should.exist(tx.casperTx.hash, 'There is no hash');
should.exist(txJson.from, 'There is no from');
should.deepEqual(txJson.from, owner1Address, 'The recipient does not match');
should.exist(tx.casperTx.header.gasPrice, 'There is no gasPrice');
should.equal(
tx.casperTx.header.gasPrice.toString(),
testData.FEE.gasPrice,
'Gas price does not match expected'
);
should.exist(txJson.fee.gasLimit, 'Gas Limit is not defined');
should.equal(txJson.fee.gasLimit, testData.FEE.gasLimit);
should.equal(txJson.to, owner2Address, 'To address was not the expected one');
should.equal(txJson.amount, testData.MIN_MOTES_AMOUNT, 'Amount was not as expected');
});
it('a transfer transaction signed multiple times', async () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
builder.sign({ key: testData.ACCOUNT_1.privateKey });
builder.sign({ key: testData.ACCOUNT_2.privateKey });
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
should.exist(tx.casperTx.approvals, 'There are no approvals');
should.deepEqual(tx.casperTx.approvals.length, 2, 'Error in the number of signatures');
should.deepEqual(tx.casperTx.approvals[0].signer, owner1Address, 'Error in the signature');
should.deepEqual(tx.casperTx.approvals[1].signer, owner2Address, 'Error in the signature');
should.exist(tx.casperTx.hash, 'There is no hash');
should.exist(txJson.from, 'There is no from');
should.deepEqual(txJson.from, owner1Address, 'The recipient does not match');
should.exist(tx.casperTx.header.gasPrice, 'There is no gasPrice');
should.equal(
tx.casperTx.header.gasPrice.toString(),
testData.FEE.gasPrice,
'Gas price does not match expected'
);
should.exist(txJson.fee.gasLimit, 'Gas Limit is not defined');
should.equal(txJson.fee.gasLimit, testData.FEE.gasLimit);
should.equal(txJson.to, owner2Address, 'To address was not the expected one');
should.equal(txJson.amount, testData.MIN_MOTES_AMOUNT, 'Amount does not match expected');
});
it('a transfer transaction signed multiple times using extended keys', async () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
builder.sign({ key: testData.ACCOUNT_1.xPrivateKey });
builder.sign({ key: testData.ACCOUNT_2.xPrivateKey });
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
should.exist(tx.casperTx.approvals, 'There are no approvals');
should.deepEqual(tx.casperTx.approvals.length, 2, 'Error in the number of signatures');
should.deepEqual(tx.casperTx.approvals[0].signer, owner1Address, 'Error in the signature');
should.deepEqual(tx.casperTx.approvals[1].signer, owner2Address, 'Error in the signature');
should.exist(tx.casperTx.hash, 'There is no hash');
should.exist(txJson.from, 'There is no from');
should.deepEqual(txJson.from, owner1Address, 'The recipient does not match');
should.exist(tx.casperTx.header.gasPrice, 'There is no gasPrice');
should.equal(
tx.casperTx.header.gasPrice.toString(),
testData.FEE.gasPrice,
'Gas price does not match expected'
);
should.exist(txJson.fee.gasLimit, 'Gas Limit is not defined');
should.equal(txJson.fee.gasLimit, testData.FEE.gasLimit);
should.equal(txJson.to, owner2Address, 'To address was not the expected one');
should.equal(txJson.amount, testData.MIN_MOTES_AMOUNT, 'Amount does not match expected');
});
it('a transfer transaction signed multiple times using one extended key', async () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
builder.sign({ key: testData.ACCOUNT_1.xPrivateKey });
builder.sign({ key: testData.ACCOUNT_2.privateKey });
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
should.exist(tx.casperTx.approvals, 'There are no approvals');
should.deepEqual(tx.casperTx.approvals.length, 2, 'Error in the number of signatures');
should.deepEqual(tx.casperTx.approvals[0].signer, owner1Address, 'Error in the signature');
should.deepEqual(tx.casperTx.approvals[1].signer, owner2Address, 'Error in the signature');
should.exist(tx.casperTx.hash, 'There is no hash');
should.exist(txJson.from, 'There is no from');
should.deepEqual(txJson.from, owner1Address, 'The recipient does not match');
should.exist(tx.casperTx.header.gasPrice, 'There is no gasPrice');
should.equal(
tx.casperTx.header.gasPrice.toString(),
testData.FEE.gasPrice,
'Gas price does not match expected'
);
should.exist(txJson.fee.gasLimit, 'Gas Limit is not defined');
should.equal(txJson.fee.gasLimit, testData.FEE.gasLimit);
should.equal(txJson.to, owner2Address, 'To address was not the expected one');
should.equal(txJson.amount, testData.MIN_MOTES_AMOUNT, 'Amount does not match expected');
});
it('a non signed transfer transaction', async () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
should.deepEqual(tx.casperTx.approvals.length, 0, 'Error in the number of signatures');
should.exist(tx.casperTx.hash, 'There is no hash');
should.exist(txJson.from, 'There is no from');
should.deepEqual(txJson.from, owner1Address, 'The recipient does not match');
should.exist(tx.casperTx.header.gasPrice, 'There is no gasPrice');
should.exist(tx.casperTx.header.gasPrice, 'There is no gasPrice');
should.equal(
tx.casperTx.header.gasPrice.toString(),
testData.FEE.gasPrice,
'Gas price does not match expected'
);
should.exist(txJson.fee.gasLimit, 'Gas Limit is not defined');
should.equal(txJson.fee.gasLimit, testData.FEE.gasLimit);
should.equal(txJson.to, owner2Address, 'To address was not the expected one');
should.equal(txJson.amount, testData.MIN_MOTES_AMOUNT, 'Amount does not match expected');
});
});
describe('should build from', () => {
describe('serialized transactions', () => {
it('a non signed transfer transaction from serialized', async () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
const txId = tx.casperTx.session.getArgByName('id') as CLOption<CLU64>;
should.equal((tx.casperTx.session.getArgByName('deploy_type') as CLString).value(), 'Send');
should.equal((tx.casperTx.session.getArgByName('to_address') as CLString).value(), owner2Address);
should.equal(txId.isSome(), true);
should.equal(txId.value().unwrap().value().toNumber(), 255);
should.equal(
(tx.casperTx.session.getArgByName('amount') as CLU512).value().toString(),
testData.MIN_MOTES_AMOUNT
);
const builder2 = factory.getTransferBuilder();
builder2.from(tx.toBroadcastFormat());
const tx2 = (await builder2.build()) as Transaction;
const tx2Json = tx2.toJson();
const txId2 = tx2.casperTx.session.getArgByName('id') as CLOption<CLU64>;
should.equal((tx2.casperTx.session.getArgByName('deploy_type') as CLString).value(), 'Send');
should.equal((tx2.casperTx.session.getArgByName('to_address') as CLString).value(), owner2Address);
should.equal(txId2.isSome(), true);
should.equal(txId2.value().unwrap().value().toNumber(), 255);
should.equal(
(tx2.casperTx.session.getArgByName('amount') as CLU512).value().toString(),
testData.MIN_MOTES_AMOUNT
);
should.deepEqual(tx2Json, txJson, 'from implementation from factory should recreate original transaction');
});
it('a signed transfer transaction from serialized', async () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
builder.sign({ key: testData.ROOT_ACCOUNT.privateKey });
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
const txId = tx.casperTx.session.getArgByName('id') as CLOption<CLU64>;
should.equal((tx.casperTx.session.getArgByName('deploy_type') as CLString).value(), 'Send');
should.equal((tx.casperTx.session.getArgByName('to_address') as CLString).value(), owner2Address);
should.equal(txId.isSome(), true);
should.equal(txId.value().unwrap().value().toNumber(), 255);
should.equal(
(tx.casperTx.session.getArgByName('amount') as CLU512).value().toString(),
testData.MIN_MOTES_AMOUNT
);
const builder2 = factory.getTransferBuilder();
builder2.from(tx.toBroadcastFormat());
const tx2 = (await builder2.build()) as Transaction;
const tx2Json = tx2.toJson();
const txId2 = tx2.casperTx.session.getArgByName('id') as CLOption<CLU64>;
should.equal((tx2.casperTx.session.getArgByName('deploy_type') as CLString).value(), 'Send');
should.equal((tx2.casperTx.session.getArgByName('to_address') as CLString).value(), owner2Address);
should.equal(txId2.isSome(), true);
should.equal(txId2.value().unwrap().value().toNumber(), 255);
should.equal(
(tx2.casperTx.session.getArgByName('amount') as CLU512).value().toString(),
testData.MIN_MOTES_AMOUNT
);
should.deepEqual(tx2Json, txJson, 'from implementation from factory should recreate original transaction');
should.deepEqual(
tx2.casperTx.approvals,
tx.casperTx.approvals,
'from implementation from factory should get approvals correctly'
);
});
it('a signed transfer transaction from serialized with extended key ', async () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
builder.sign({ key: testData.ROOT_ACCOUNT.xPrivateKey });
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
const txId = tx.casperTx.session.getArgByName('id') as CLOption<CLU64>;
should.equal((tx.casperTx.session.getArgByName('deploy_type') as CLString).value(), 'Send');
should.equal((tx.casperTx.session.getArgByName('to_address') as CLString).value(), owner2Address);
should.equal(txId.isSome(), true);
should.equal(txId.value().unwrap().value().toNumber(), 255);
should.equal(
(tx.casperTx.session.getArgByName('amount') as CLU512).value().toString(),
testData.MIN_MOTES_AMOUNT
);
const builder2 = factory.getTransferBuilder();
builder2.from(tx.toBroadcastFormat());
const tx2 = (await builder2.build()) as Transaction;
const tx2Json = tx2.toJson();
const txId2 = tx2.casperTx.session.getArgByName('id') as CLOption<CLU64>;
should.equal((tx2.casperTx.session.getArgByName('deploy_type') as CLString).value(), 'Send');
should.equal((tx2.casperTx.session.getArgByName('to_address') as CLString).value(), owner2Address);
should.equal(txId2.isSome(), true);
should.equal(txId2.value().unwrap().value().toNumber(), 255);
should.equal(
(tx2.casperTx.session.getArgByName('amount') as CLU512).value().toString(),
testData.MIN_MOTES_AMOUNT
);
should.deepEqual(tx2Json, txJson, 'from implementation from factory should recreate original transaction');
should.deepEqual(
tx2.casperTx.approvals,
tx.casperTx.approvals,
'from implementation from factory should get approvals correctly'
);
});
it('an offline multisig transfer transaction', async () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
builder.sign({ key: testData.ROOT_ACCOUNT.privateKey });
builder.sign({ key: testData.ACCOUNT_1.privateKey });
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
const txId = tx.casperTx.session.getArgByName('id') as CLOption<CLU64>;
should.equal((tx.casperTx.session.getArgByName('deploy_type') as CLString).value(), 'Send');
should.equal((tx.casperTx.session.getArgByName('to_address') as CLString).value(), owner2Address);
should.equal(txId.isSome(), true);
should.equal(txId.value().unwrap().value().toNumber(), 255);
should.equal(
(tx.casperTx.session.getArgByName('amount') as CLU512).value().toString(),
testData.MIN_MOTES_AMOUNT
);
const builder2 = factory.getTransferBuilder();
builder2.from(tx.toBroadcastFormat());
const tx2 = (await builder2.build()) as Transaction;
const tx2Json = tx2.toJson();
const txId2 = tx2.casperTx.session.getArgByName('id') as CLOption<CLU64>;
should.equal((tx2.casperTx.session.getArgByName('deploy_type') as CLString).value(), 'Send');
should.equal((tx2.casperTx.session.getArgByName('to_address') as CLString).value(), owner2Address);
should.equal(txId2.isSome(), true);
should.equal(txId2.value().unwrap().value().toNumber(), 255);
should.equal(
(tx2.casperTx.session.getArgByName('amount') as CLU512).value().toString(),
testData.MIN_MOTES_AMOUNT
);
should.deepEqual(tx2Json, txJson, 'from implementation from factory should recreate original transaction');
should.deepEqual(
tx2.casperTx.approvals,
tx.casperTx.approvals,
'from implementation from factory should get approvals correctly'
);
});
it('an offline multisig transfer transaction with one extended key', async () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
builder.sign({ key: testData.ROOT_ACCOUNT.xPrivateKey });
builder.sign({ key: testData.ACCOUNT_1.privateKey });
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
const txId = tx.casperTx.session.getArgByName('id') as CLOption<CLU64>;
should.equal((tx.casperTx.session.getArgByName('deploy_type') as CLString).value(), 'Send');
should.equal((tx.casperTx.session.getArgByName('to_address') as CLString).value(), owner2Address);
should.equal(txId.isSome(), true);
should.equal(txId.value().unwrap().value().toNumber(), 255);
should.equal(
(tx.casperTx.session.getArgByName('amount') as CLU512).value().toString(),
testData.MIN_MOTES_AMOUNT
);
const builder2 = factory.getTransferBuilder();
builder2.from(tx.toBroadcastFormat());
const tx2 = (await builder2.build()) as Transaction;
const tx2Json = tx2.toJson();
const txId2 = tx2.casperTx.session.getArgByName('id') as CLOption<CLU64>;
should.equal((tx2.casperTx.session.getArgByName('deploy_type') as CLString).value(), 'Send');
should.equal((tx2.casperTx.session.getArgByName('to_address') as CLString).value(), owner2Address);
should.equal(txId2.isSome(), true);
should.equal(txId2.value().unwrap().value().toNumber(), 255);
should.equal(
(tx2.casperTx.session.getArgByName('amount') as CLU512).value().toString(),
testData.MIN_MOTES_AMOUNT
);
should.deepEqual(tx2Json, txJson, 'from implementation from factory should recreate original transaction');
should.deepEqual(
tx2.casperTx.approvals,
tx.casperTx.approvals,
'from implementation from factory should get approvals correctly'
);
});
it('an offline multisig transfer transaction with extended keys', async () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
builder.sign({ key: testData.ROOT_ACCOUNT.xPrivateKey });
builder.sign({ key: testData.ACCOUNT_1.xPrivateKey });
const tx = (await builder.build()) as Transaction;
const txJson = tx.toJson();
const txId = tx.casperTx.session.getArgByName('id') as CLOption<CLU64>;
should.equal((tx.casperTx.session.getArgByName('deploy_type') as CLString).value(), 'Send');
should.equal((tx.casperTx.session.getArgByName('to_address') as CLString).value(), owner2Address);
should.equal(txId.isSome(), true);
should.equal(txId.value().unwrap().value().toNumber(), 255);
should.equal(
(tx.casperTx.session.getArgByName('amount') as CLU512).value().toString(),
testData.MIN_MOTES_AMOUNT
);
const builder2 = factory.getTransferBuilder();
builder2.from(tx.toBroadcastFormat());
const tx2 = (await builder2.build()) as Transaction;
const tx2Json = tx2.toJson();
const txId2 = tx2.casperTx.session.getArgByName('id') as CLOption<CLU64>;
should.equal((tx2.casperTx.session.getArgByName('deploy_type') as CLString).value(), 'Send');
should.equal((tx2.casperTx.session.getArgByName('to_address') as CLString).value(), owner2Address);
should.equal(txId2.isSome(), true);
should.equal(txId2.value().unwrap().value().toNumber(), 255);
should.equal(
(tx2.casperTx.session.getArgByName('amount') as CLU512).value().toString(),
testData.MIN_MOTES_AMOUNT
);
should.deepEqual(tx2Json, txJson, 'from implementation from factory should recreate original transaction');
should.deepEqual(
tx2.casperTx.approvals,
tx.casperTx.approvals,
'from implementation from factory should get approvals correctly'
);
});
});
});
});
describe('should fail rebuild from', () => {
it('a serialized transaction with invalid destination address', async () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
const tx = (await builder.build()) as Transaction;
tx.casperTx = DeployUtil.addArgToDeploy(tx.casperTx, 'to_address', CLValueBuilder.byteArray(Uint8Array.from([])));
const builder2 = factory.getTransferBuilder();
assert.throws(() => {
builder2.from(tx.toBroadcastFormat());
}, new RegExp(testData.ERROR_INVALID_DESTINATION_ADDRESS_ON_FROM));
});
});
describe('should fail', () => {
it('a transfer transaction with an invalid source address', () => {
assert.throws(() => {
initTxTransferBuilder().source({ address: testData.INVALID_ADDRESS });
}, new RegExp(testData.ERROR_INVALID_ADDRESS));
});
it('a transfer transaction with an invalid destination address', () => {
assert.throws(() => {
initTxTransferBuilder().to(testData.INVALID_ADDRESS);
}, new RegExp(testData.ERROR_INVALID_ADDRESS));
});
it('a transfer transaction with repeated sign', async () => {
const txBuilder = await initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
assert.throws(() => {
txBuilder.sign({ key: testData.ACCOUNT_3.privateKey });
txBuilder.sign({ key: testData.ACCOUNT_3.privateKey });
}, new RegExp(testData.ERROR_REPEATED_SIGNATURE));
});
it('a transfer transaction with repeated sign using extended keys', async () => {
const txBuilder = await initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
assert.throws(() => {
txBuilder.sign({ key: testData.ACCOUNT_3.xPrivateKey });
txBuilder.sign({ key: testData.ACCOUNT_3.xPrivateKey });
}, new RegExp(testData.ERROR_REPEATED_SIGNATURE));
});
it('a transfer transaction with an invalid amount: text value', () => {
assert.throws(() => {
initTxTransferBuilder().amount('invalid_value');
}, new RegExp(testData.ERROR_INVALID_AMOUNT));
});
it('a transfer transaction with an invalid amount: negative value', () => {
assert.throws(() => {
initTxTransferBuilder().amount('-1');
}, new RegExp(testData.ERROR_INVALID_AMOUNT));
});
it('a transfer transaction with an invalid amount: zero', () => {
assert.throws(() => {
initTxTransferBuilder().amount('0');
}, new RegExp(testData.ERROR_INVALID_AMOUNT));
});
it('a transfer transaction with an invalid amount: minAmount - 1', () => {
const maxInvalidAmount = new BigNumber(testData.MIN_MOTES_AMOUNT).minus(1).toString();
assert.throws(() => {
initTxTransferBuilder().amount(maxInvalidAmount);
}, new RegExp(testData.ERROR_INVALID_AMOUNT));
});
it('a transfer transaction without destination param', () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.fee(testData.FEE);
txBuilder.source({ address: owner1Address });
txBuilder.amount(testData.MIN_MOTES_AMOUNT);
txBuilder.build().should.be.rejectedWith(testData.ERROR_MISSING_TRANSFER_TARGET);
});
it('a transfer transaction with invalid destination param', () => {
const txBuilder = factory.getTransferBuilder();
assert.throws(() => {
txBuilder.to(testData.INVALID_ADDRESS);
}, new RegExp(testData.ERROR_INVALID_ADDRESS));
});
it('a transfer transaction without amount', () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.fee(testData.FEE);
txBuilder.source({ address: owner1Address });
// txBuilder.to(owner2Address);
txBuilder.to('01513fa90c1a74c34a8958dd86055e9736edb1ead918bd4d4d750ca851946be7aa');
txBuilder.build().should.be.rejectedWith(testData.ERROR_MISSING_TRANSFER_AMOUNT);
});
it('a transfer transaction with invalid amount', async () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.fee(testData.FEE);
txBuilder.source({ address: owner1Address });
txBuilder.to(owner2Address);
assert.throws(() => {
txBuilder.amount('');
}, new RegExp(testData.ERROR_INVALID_AMOUNT));
});
it('a transfer transaction with invalid transfer id', () => {
const txBuilder = factory.getTransferBuilder();
assert.throws(() => {
txBuilder.transferId(-1);
}, new RegExp(testData.ERROR_INVALID_TRANSFER_ID));
});
it('a transfer transaction with more than 3 signatures', () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
builder.sign({ key: testData.ROOT_ACCOUNT.privateKey });
builder.sign({ key: testData.ACCOUNT_1.privateKey });
builder.sign({ key: testData.ACCOUNT_2.privateKey });
assert.throws(() => {
builder.sign({ key: testData.ACCOUNT_2.privateKey });
}, new RegExp(testData.ERROR_MAX_AMOUNT_OF_SIGNERS_REACHED));
});
it('a transfer transaction with more than 3 signatures with extended keys', () => {
const builder = initTxTransferBuilder().amount(testData.MIN_MOTES_AMOUNT);
builder.sign({ key: testData.ROOT_ACCOUNT.xPrivateKey });
builder.sign({ key: testData.ACCOUNT_1.xPrivateKey });
builder.sign({ key: testData.ACCOUNT_2.xPrivateKey });
assert.throws(() => {
builder.sign({ key: testData.ACCOUNT_2.xPrivateKey });
}, new RegExp(testData.ERROR_MAX_AMOUNT_OF_SIGNERS_REACHED));
});
});
describe('txJson validation', () => {
it('contains all required fields for Transfer', async () => {
const txBuilder = initTxTransferBuilder();
txBuilder.amount(testData.MIN_MOTES_AMOUNT);
txBuilder.sign({ key: testData.ACCOUNT_1.privateKey });
const tx = (await txBuilder.build()) as Transaction;
const txJson = tx.toJson();
should.deepEqual(txJson.fee, testData.FEE);
should.equal(txJson.deployType, 'Send');
should.equal(txJson.from, owner1Address);
should.equal(txJson.hash, Buffer.from(tx.casperTx.hash).toString('hex'));
should.equal(txJson.amount, testData.MIN_MOTES_AMOUNT);
should.equal(txJson.to, owner2Address);
should.equal(txJson.transferId, 255);
});
it('contains all required fields for Transfer signed with extended key', async () => {
const txBuilder = initTxTransferBuilder();
txBuilder.amount(testData.MIN_MOTES_AMOUNT);
txBuilder.sign({ key: testData.ACCOUNT_1.xPrivateKey });
const tx = (await txBuilder.build()) as Transaction;
const txJson = tx.toJson();
should.deepEqual(txJson.fee, testData.FEE);
should.equal(txJson.deployType, 'Send');
should.equal(txJson.from, owner1Address);
should.equal(txJson.hash, Buffer.from(tx.casperTx.hash).toString('hex'));
should.equal(txJson.amount, testData.MIN_MOTES_AMOUNT);
should.equal(txJson.to, owner2Address);
should.equal(txJson.transferId, 255);
});
});
});
Выполнить команду
Для локальной разработки. Не используйте в интернете!