PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-cspr/test/unit/lib/transactionBuilder
Просмотр файла: transactionBuilder.ts
import * as _ from 'lodash';
import assert from 'assert';
import * as should from 'should';
import * as testData from '../../../fixtures/resources';
import { KeyPair, TransactionBuilderFactory } from '../../../../src/lib';
import { Transaction } from '../../../../src/lib/transaction';
import { removeAlgoPrefixFromHexValue } from '../../../../src/lib/utils';
import { DEFAULT_CHAIN_NAMES } from '../../../../src/lib/constants';
import { coins } from '@bitgo/statics';
describe('Casper Transaction Builder', () => {
const factory = new TransactionBuilderFactory(coins.get('tcspr'));
const owner1Address = new KeyPair({ pub: testData.ACCOUNT_1.publicKey }).getAddress();
const owner2Address = new KeyPair({ pub: testData.ACCOUNT_2.publicKey }).getAddress();
const owner3Address = new KeyPair({ pub: testData.ACCOUNT_3.publicKey }).getAddress();
const sourceAddress = new KeyPair({ pub: testData.ROOT_ACCOUNT.publicKey }).getAddress();
const initTransferBuilder = () => {
const txBuilder = factory.getTransferBuilder();
txBuilder.fee({ gasLimit: testData.FEE.gasLimit, gasPrice: testData.FEE.gasPrice });
txBuilder.source({ address: owner1Address });
txBuilder.to(owner2Address);
txBuilder.transferId(255);
txBuilder.amount(testData.MIN_MOTES_AMOUNT);
return txBuilder;
};
const initWalletBuilder = () => {
const txBuilder = factory.getWalletInitializationBuilder();
txBuilder.fee(testData.FEE);
txBuilder.owner(owner1Address);
txBuilder.owner(owner2Address);
txBuilder.owner(owner3Address);
txBuilder.source({ address: sourceAddress });
return txBuilder;
};
const initDelegateBuilder = () => {
const txBuilder = factory.getDelegateBuilder();
txBuilder.fee({ gasLimit: testData.FEE.gasLimit, gasPrice: testData.FEE.gasPrice });
txBuilder.source({ address: sourceAddress });
txBuilder.amount(testData.MIN_MOTES_AMOUNT);
return txBuilder;
};
const initUndelegateBuilder = () => {
const txBuilder = factory.getUndelegateBuilder();
txBuilder.fee({ gasLimit: testData.FEE.gasLimit, gasPrice: testData.FEE.gasPrice });
txBuilder.source({ address: sourceAddress });
txBuilder.amount(testData.MIN_MOTES_AMOUNT);
return txBuilder;
};
describe('should validate', () => {
it('an empty raw transaction', () => {
const txBuilder = factory.getTransferBuilder();
assert.throws(
() => {
txBuilder.validateRawTransaction('');
},
(e: Error) => e.message === testData.ERROR_EMPTY_RAW_TRANSACTION
);
});
it('an invalid raw transfer transaction', () => {
const txBuilder = factory.getTransferBuilder();
assert.throws(
() => {
txBuilder.validateRawTransaction(testData.INVALID_RAW_TRANSACTION);
},
(e: Error) => e.message === testData.ERROR_JSON_PARSING
);
});
it('an invalid raw wallet init transaction', () => {
const txBuilder = factory.getWalletInitializationBuilder();
assert.throws(
() => {
txBuilder.validateRawTransaction(testData.INVALID_RAW_TRANSACTION);
},
(e: Error) => e.message === testData.ERROR_JSON_PARSING
);
});
it('a valid raw transfer transaction', async () => {
const builder = initTransferBuilder();
builder.sign({ key: testData.ACCOUNT_1.privateKey });
builder.sign({ key: testData.ACCOUNT_2.privateKey });
const tx = await builder.build();
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('a valid raw transfer transaction both accounts using extended keys', async () => {
const builder = initTransferBuilder();
builder.sign({ key: testData.ACCOUNT_1.xPrivateKey });
builder.sign({ key: testData.ACCOUNT_2.xPrivateKey });
const tx = await builder.build();
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('a valid raw transfer transaction one account using extended key', async () => {
const builder = initTransferBuilder();
builder.sign({ key: testData.ACCOUNT_1.xPrivateKey });
builder.sign({ key: testData.ACCOUNT_2.privateKey });
const tx = await builder.build();
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('a valid raw wallet init transaction', async () => {
const builder = initWalletBuilder();
const tx = await builder.build();
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('an invalid expiration time', async () => {
const builder = initWalletBuilder();
assert.throws(
() => builder.expiration(testData.MAX_TRANSACTION_EXPIRATION + 1),
(e: Error) => e.message === testData.INVALID_TRANSACTION_EXPIRATION_MESSAGE
);
});
it('should validate addresses', async function () {
// validate secp256k1 address
const builder = initTransferBuilder();
let tx = await builder.build();
let txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateAddress({ address: txJson.to });
});
// validate ed25519 address
const ed25519Address = '01513fa90c1a74c34a8958dd86055e9736edb1ead918bd4d4d750ca851946be7aa';
builder.to(ed25519Address);
tx = await builder.build();
txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateAddress({ address: txJson.to });
});
});
});
describe('signatures', function () {
it('should sign a transaction', async function () {
const builder = initWalletBuilder();
builder.sign({ key: testData.ROOT_ACCOUNT.privateKey });
const tx = (await builder.build()) as Transaction;
should.exists(tx.casperTx.approvals[0].signer);
should.exists(tx.casperTx.approvals[0].signature);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('should sign a transaction using extended key', async function () {
const builder = initWalletBuilder();
builder.sign({ key: testData.ROOT_ACCOUNT.xPrivateKey });
const tx = (await builder.build()) as Transaction;
should.exists(tx.casperTx.approvals[0].signer);
should.exists(tx.casperTx.approvals[0].signature);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('should process signing only once per signer', async function () {
const builder = initWalletBuilder();
builder.sign({ key: testData.ROOT_ACCOUNT.privateKey });
let tx = (await builder.build()) as Transaction;
tx.casperTx.approvals.length.should.equal(1);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
tx = (await builder.build()) as Transaction;
tx.casperTx.approvals.length.should.equal(1);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
});
it('should process signing only once per signer with extended key', async function () {
const builder = initWalletBuilder();
builder.sign({ key: testData.ROOT_ACCOUNT.xPrivateKey });
let tx = (await builder.build()) as Transaction;
tx.casperTx.approvals.length.should.equal(1);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
tx = (await builder.build()) as Transaction;
tx.casperTx.approvals.length.should.equal(1);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
});
it('should add a signature to a transaction', async function () {
const builder = initWalletBuilder();
const sig =
'0072f40621663fd03c5e13b413d5c354cdf4c7e76672aa61fd8ede0f1ac09f5de107d725eb40e1efb9037940d74ef9b2efaa1d66d0991a5322639481c2d4280775';
const pub = '03dca7d5d68fba12a604e992a47504d10e6795cdc6db438abb741788c71c4b7428';
const signingKeyPair = new KeyPair({ pub });
builder.signature(sig, signingKeyPair);
const tx = (await builder.build()) as Transaction;
const signer = tx.casperTx.approvals[0].signer;
const signature = tx.casperTx.approvals[0].signature;
removeAlgoPrefixFromHexValue(signer).should.equal(pub);
removeAlgoPrefixFromHexValue(signature).should.equal(_.toLower(sig));
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('should add a signature to a transaction using extended key', async function () {
const builder = initWalletBuilder();
const sig =
'0220ade206fc0e7bf19c672aae122e037a7c0ad6c82fb65126735e61f370923f2706114647f9ea1e405fdbf9915c7eaf4325a5ddf9faf24935b20333526cf3b44d';
const xPub =
'xpub661MyMwAqRbcH4WAWt79QwMXc1MKaqxU8axkYJGfECGg3gTMuxHYfZzW8AyrRJwFrGZxdA1CgYtXtjVToMyUyfzQrjBayP47pbdWuhdrbYz';
const signingKeyPair = new KeyPair({ pub: xPub });
builder.signature(sig, signingKeyPair);
const tx = (await builder.build()) as Transaction;
const signer = tx.casperTx.approvals[0].signer;
const signature = tx.casperTx.approvals[0].signature;
removeAlgoPrefixFromHexValue(signer).should.equal(signingKeyPair.getKeys().pub);
removeAlgoPrefixFromHexValue(signature).should.equal(_.toLower(sig));
const txJson = tx.toJson();
should.doesNotThrow(() => {
builder.validateRawTransaction(JSON.stringify(txJson));
});
});
it('should process signing only once per signature added', async function () {
const builder = initWalletBuilder();
const sig =
'0072f40621663fd03c5e13b413d5c354cdf4c7e76672aa61fd8ede0f1ac09f5de107d725eb40e1efb9037940d74ef9b2efaa1d66d0991a5322639481c2d4280775';
const pub = '03dca7d5d68fba12a604e992a47504d10e6795cdc6db438abb741788c71c4b7428';
const signingKeyPair = new KeyPair({ pub });
builder.signature(sig, signingKeyPair);
let tx = (await builder.build()) as Transaction;
tx.casperTx.approvals.length.should.equal(1);
tx = (await builder.build()) as Transaction;
tx.casperTx.approvals.length.should.equal(1);
});
it('should process signing only once per signature added using extended key', async function () {
const builder = initWalletBuilder();
const sig =
'0220ade206fc0e7bf19c672aae122e037a7c0ad6c82fb65126735e61f370923f2706114647f9ea1e405fdbf9915c7eaf4325a5ddf9faf24935b20333526cf3b44d';
const xPub =
'xpub661MyMwAqRbcH4WAWt79QwMXc1MKaqxU8axkYJGfECGg3gTMuxHYfZzW8AyrRJwFrGZxdA1CgYtXtjVToMyUyfzQrjBayP47pbdWuhdrbYz';
const signingKeyPair = new KeyPair({ pub: xPub });
builder.signature(sig, signingKeyPair);
let tx = (await builder.build()) as Transaction;
tx.casperTx.approvals.length.should.equal(1);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
tx = (await builder.build()) as Transaction;
tx.casperTx.approvals.length.should.equal(1);
should.equal(tx.casperTx.approvals[0].signer, sourceAddress);
});
});
describe('chain name', function () {
describe('has default value for', function () {
it('transfer transaction', function () {
const txBuilder = initTransferBuilder();
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(DEFAULT_CHAIN_NAMES.testnet);
});
it('wallet initialization transaction', function () {
const txBuilder = initWalletBuilder();
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(DEFAULT_CHAIN_NAMES.testnet);
});
it('delegation transaction', function () {
const txBuilder = initDelegateBuilder();
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(DEFAULT_CHAIN_NAMES.testnet);
});
it('undelegation transaction', function () {
const txBuilder = initUndelegateBuilder();
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(DEFAULT_CHAIN_NAMES.testnet);
});
});
describe('can be manually set for', function () {
it('transfer transaction', function () {
const txBuilder = initTransferBuilder()
.amount(testData.MIN_MOTES_AMOUNT)
.nodeChainName(testData.CUSTOM_CHAIN_NAME);
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(testData.CUSTOM_CHAIN_NAME);
});
it('wallet initialization transaction', function () {
const txBuilder = initWalletBuilder().nodeChainName(testData.CUSTOM_CHAIN_NAME);
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(testData.CUSTOM_CHAIN_NAME);
});
it('delegation transaction', function () {
const txBuilder = initDelegateBuilder().nodeChainName(testData.CUSTOM_CHAIN_NAME);
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(testData.CUSTOM_CHAIN_NAME);
});
it('undelegation transaction', function () {
const txBuilder = initUndelegateBuilder().nodeChainName(testData.CUSTOM_CHAIN_NAME);
should.doesNotThrow(() => txBuilder.validateMandatoryFields());
txBuilder.chainName.should.equals(testData.CUSTOM_CHAIN_NAME);
});
});
});
});
Выполнить команду
Для локальной разработки. Не используйте в интернете!