PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-coin-apt/test/unit
Просмотр файла: apt.ts
import 'should';
import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
import { BitGoAPI } from '@bitgo/sdk-api';
import { Apt, AptToken, Tapt, TransferTransaction } from '../../src';
import * as testData from '../resources/apt';
import _ from 'lodash';
import sinon from 'sinon';
import assert from 'assert';
import {
AccountAddress,
AccountAuthenticatorEd25519,
Aptos,
APTOS_COIN,
AptosConfig,
Ed25519PublicKey,
Ed25519Signature,
generateUserTransactionHash,
Network,
} from '@aptos-labs/ts-sdk';
import utils from '../../src/lib/utils';
import { AptCoin, coins, GasTankAccountCoin } from '@bitgo/statics';
describe('APT:', function () {
let bitgo: TestBitGoAPI;
let basecoin;
let newTxPrebuild;
let newTxParams;
const txPreBuild = {
txHex: testData.TRANSACTION_USING_TRANSFER_COINS,
txInfo: {},
};
const txParams = {
recipients: testData.recipients,
};
const batchFungibleTxPrebuild = {
txHex: testData.FUNGIBLE_BATCH_RAW_TX_HEX,
txInfo: {},
};
const batchFungibleTxParams = {
recipients: testData.batchFungibleRecipients,
type: 'transfer',
};
before(function () {
bitgo = TestBitGo.decorate(BitGoAPI, { env: 'mock' });
bitgo.safeRegister('apt', Apt.createInstance);
bitgo.safeRegister('tapt', Tapt.createInstance);
bitgo.safeRegister('apt:usdt', AptToken.createInstance);
bitgo.initializeTestVars();
basecoin = bitgo.coin('tapt');
newTxPrebuild = () => {
return _.cloneDeep(txPreBuild);
};
newTxParams = () => {
return _.cloneDeep(txParams);
};
});
it('should return the right info', function () {
const apt = bitgo.coin('apt');
const tapt = bitgo.coin('tapt');
const aptUsdt = bitgo.coin('apt:usdt');
const aptStatics = coins.get('apt') as GasTankAccountCoin;
const taptStatics = coins.get('tapt') as GasTankAccountCoin;
apt.getChain().should.equal('apt');
apt.getFamily().should.equal('apt');
apt.getFullName().should.equal('Aptos');
apt.getBaseFactor().should.equal(1e8);
tapt.getChain().should.equal('tapt');
tapt.getFamily().should.equal('apt');
tapt.getFullName().should.equal('Testnet Aptos');
tapt.getBaseFactor().should.equal(1e8);
aptStatics.gasTankLowBalanceAlertFactor.should.equal(80);
taptStatics.gasTankLowBalanceAlertFactor.should.equal(80);
aptStatics.gasTankMinBalanceRecommendationFactor.should.equal(200);
taptStatics.gasTankMinBalanceRecommendationFactor.should.equal(200);
aptUsdt.getFamily().should.equal('apt');
aptUsdt.getChain().should.equal('apt');
const aptUsdtStatics = aptUsdt.getConfig() as AptCoin;
aptUsdtStatics.fullName.should.equal('USD Tether');
aptUsdtStatics.assetId.should.equal('0x357b0b74bc833e95a115ad22604854d6b0fca151cecd94111770e5d6ffc9dc2b');
aptUsdtStatics.decimalPlaces.should.equal(6);
});
it('is valid pub', function () {
// with 0x prefix
basecoin.isValidPub('0x9b4e96086d111500259f9b38680b0509a405c1904da18976455a20c691d3bb07').should.equal(false);
// without 0x prefix
basecoin.isValidPub('9b4e96086d111500259f9b38680b0509a405c1904da18976455a20c691d3bb07').should.equal(true);
});
describe('Verify transaction: ', () => {
it('should succeed to verify transaction', async function () {
const txPrebuild = newTxPrebuild();
const txParams = newTxParams();
const verification = {};
const isTransactionVerified = await basecoin.verifyTransaction({ txParams, txPrebuild, verification });
isTransactionVerified.should.equal(true);
});
it('should succeed to verify fungible transaction', async function () {
const verification = {};
const isTransactionVerified = await basecoin.verifyTransaction({
txPrebuild: batchFungibleTxPrebuild,
txParams: batchFungibleTxParams,
verification,
});
isTransactionVerified.should.equal(true);
});
it('should succeed to verify transaction when recipients amount are numbers', async function () {
const txPrebuild = newTxPrebuild();
const txParamsWithNumberAmounts = newTxParams();
txParamsWithNumberAmounts.recipients = txParamsWithNumberAmounts.recipients.map(({ address, amount }) => {
return { address, amount: Number(amount) };
});
const verification = {};
const isTransactionVerified = await basecoin.verifyTransaction({
txParams: txParamsWithNumberAmounts,
txPrebuild,
verification,
});
isTransactionVerified.should.equal(true);
});
it('should fail to verify transaction with invalid param', async function () {
const txPrebuild = {};
const txParams = newTxParams();
txParams.recipients = undefined;
await basecoin
.verifyTransaction({
txParams,
txPrebuild,
})
.should.rejectedWith('missing required tx prebuild property txHex');
});
});
describe('Parse and Explain Transactions: ', () => {
const transferInputsResponse = [
{
address: testData.sender2.address,
amount: testData.AMOUNT.toString(),
},
];
const transferOutputsResponse = [
{
address: testData.recipients[0].address,
amount: testData.recipients[0].amount,
},
];
const transferFungibleInputResponse = [
{
address: testData.fungibleSender.address,
amount: testData.FUNGIBLE_TOKEN_AMOUNT.toString(),
},
];
const tranferFungibleOutputResponse = [
{
address: testData.fungibleTokenRecipients[1].address,
amount: testData.fungibleTokenRecipients[1].amount,
},
];
it('should parse a transfer transaction', async function () {
const parsedTransaction = await basecoin.parseTransaction({
txHex: testData.TRANSACTION_USING_TRANSFER_COINS,
});
parsedTransaction.should.deepEqual({
inputs: transferInputsResponse,
outputs: transferOutputsResponse,
});
});
it('should parse signed fungible transaction, only work if amount parsing correctly done from payload', async function () {
const parsedTransaction = await basecoin.parseTransaction({
txHex: testData.FUNGIBLE_SERIALIZED_TX_HEX,
});
parsedTransaction.should.deepEqual({
inputs: transferFungibleInputResponse,
outputs: tranferFungibleOutputResponse,
});
});
it('should explain a transfer transaction', async function () {
const rawTx = newTxPrebuild().txHex;
const transaction = new TransferTransaction(coins.get('tapt'));
transaction.fromRawTransaction(rawTx);
const explainedTx = transaction.explainTransaction();
console.log(explainedTx);
explainedTx.should.deepEqual({
displayOrder: [
'id',
'outputs',
'outputAmount',
'changeOutputs',
'changeAmount',
'fee',
'withdrawAmount',
'sender',
'type',
],
id: '0x249289a8178e4b9cdb89fad6e8e436ccc435753e4ea3c9d50e0c8b525582e90d',
outputs: [
{
address: '0xf7405c28a02cf5bab4ea4498240bb3579db45951794eb1c843bef0534c093ad9',
amount: '1000',
},
],
outputAmount: '1000',
changeOutputs: [],
changeAmount: '0',
fee: { fee: '0' },
sender: '0x1aed808916ab9b1b30b07abb53561afd46847285ce28651221d406173a372449',
type: 0,
});
});
it('should fail to explain a invalid raw transaction', async function () {
const rawTx = 'invalidRawTransaction';
const transaction = new TransferTransaction(coins.get('tapt'));
await assert.rejects(async () => transaction.fromRawTransaction(rawTx), {
message: 'invalid raw transaction',
});
});
it('should fail to parse a transfer transaction when explainTransaction response is undefined', async function () {
const stub = sinon.stub(Apt.prototype, 'explainTransaction');
stub.resolves(undefined);
await basecoin.parseTransaction({ txHex: testData.TRANSFER }).should.be.rejectedWith('Invalid transaction');
stub.restore();
});
});
describe('Address Validation', () => {
let keychains;
let commonKeychain;
before(function () {
commonKeychain =
'19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781';
keychains = [
{
id: '6424c353eaf78d000766e95949868468',
source: 'user',
type: 'tss',
commonKeychain:
'19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
encryptedPrv:
'{"iv":"cZd5i7L4RxtwrALW2rK7UA==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"5zgoH1Bd3Fw=","ct":"9vVlnXFRtrM9FVEo+d2chbGHlM9lFZemueBuAs3BIkPo33Fo7jzwwNK/kIWkEyg+NmEBd5IaqAS157nvvvwzzsmMWlQdUz9qbmXNv3pg987cXFR08exS+4uhwP1YNOjJTRvRNcO9ZqHb46d4fmyJ/yC9/susCge7r/EsbaN5C3afv1dzybuq912FwaQElZLYYp5BICudFOMZ9k0UDMfKM/PMDkH7WexoGHr9GKq/bgCH2B39TZZyHKU6Uy47lXep2s6h0DrMwHOrnmiL3DZjOj88Ynvphlzxuo4eOlD2UHia2+nvIaISYs29Pr0DAvREutchvcBpExj1kWWPv7hQYrv8F0NAdatsbWl3w+xKyfiMKo1USlrwyJviypGtQtXOJyw0XPN0rv2+L5lW8BbjpzHfYYN13fJTedlGTFhhkzVtbbPAKE02kx7zCJcjYaiexdSTsrDLScYNT9/Jhdt27KpsooehwVohLfSKz4vbFfRu2MPZw3/+c/hfiJNgtz6esWbnxGrcE8U2IwPYCaK+Ghk4DcqWNIni59RI5B5kAsQOToII40qPN510uTgxBSPO7q7MHgkxdd4CqBq+ojr9j0P7oao8E5Y+CBDJrojDoCh1oCCDW9vo2dXlVcD8SIbw7U/9AfvEbA4xyE/5md1M7CIwLnWs2Ynv0YtaKoqhdS9x6FmHlMDhN/DKHinrwmowtrTT82fOkpO5g9saSmgU7Qy3gLt8t+VwdEyeFeQUKRSyci8qgqXQaZIg4+aXgaSOnlCFMtmB8ekYxEhTY5uzRfrNgS4s1QeqFBpNtUF+Ydi297pbVXnJoXAN+SVWd80GCx+yI2dpVC89k3rOWK9WeyqlnzuLJWp2RIOB9cdW8GFv/fN+QAJpYeVxOE4+nZDsKnsj8nKcg9t4Dlx1G6gLM1/Vq9YxNLbuzuRC0asUYvdMnoMvszmpm++TxndYisgNYscpZSoz7wvcazJNEPfhPVjEkd6tUUuN4GM35H0DmKCUQNT+a6B6hmHlTZvjxiyGAg5bY59hdjvJ+22QduazlEEC6LI3HrA7uK0TpplWzS1tCIFvTMUhj65DEZmNJ2+ZY9bQ4vsMf+DRR3OOG4t+DMlNfjOd3zNv3QoY95BjfWpryFwPzDq7bCP67JDsoj7j2TY5FRSrRkD77H0Ewlux2cWfjRTwcMHcdQxxuV0OP0aNjGDjybFN"}',
},
{
id: '6424c353eaf78d000766e96137d4404b',
source: 'backup',
type: 'tss',
commonKeychain:
'19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
encryptedPrv:
'{"iv":"vi0dPef/Rx7kG/pRySQi6Q==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"9efhQsiEvVs=","ct":"Gw6atvf6gxKzsjtl3xseipO3rAxp1mAz7Yu1ihFsi5/lf2vMZegApgZx+pyILFS9KKLHbNF3U6WgSYdrr2t4vzdLsXkH1WIxfHS+cd2C5N59yADZDnPJBT6pv/IRvaYelP0Ck3nIYQ2hSMm8op+VOWC/SzHeh7slYDqwEHTGan0Wigfvk1yRd7CCJTaEAomnc/4eFi2NY3X3gt/3opy9IAgknnwUFohn96EWpEQ0F6pbzH/Z8VF6gF+DUcrrByAxExUPnHQZiFk3YHU/vVV4FxBU/mVAE8xBsBn5ul5e5SUMPfc7TBuJWv4BByTNg9xDShF/91Yx2nbfUm5d9QmM8lpKgzzQvcK8POAPk87gRCuKnsGh5vNS0UppkHc+ocfzRQlGA6jze7QyyQO0rMj5Ly8kWjwk2vISvKYHYS1NR7VU549UIXo7NXjatunKSc3+IreoRUHIshiaLg6hl+pxCCuc0qQ43V0mdIfCjTN8gkGWLNk8R7tAGPz9jyapQPcPEGHgEz0ATIi6yMNWCsibS2eLiE1uVEJONoM4lk6FPl3Q2CHbW2MeEbqjY8hbaw18mNb2xSBH/Fwpiial+Tvi2imqgnCO4ZpO9bllKftZPcQy0stN+eGBlb5ufyflKkDSiChHYroGjEpmiFicdde48cJszF52uKNnf1q67fA9/S2FAHQab3EXojxH2Gbk+kkV2h/TYKFFZSWC3vi4e8mO+vjMUcR0AdsgPFyEIz0SCGuba3CnTLNdEuZwsauAeHkx2vUTnRgJPVgNeeuXmsVG76Sy2ggJHuals0Hj8U2Xda0qO1RuFfoCWfss9wn6HGRwPPkhSB/8oNguAqmRVGKkd8Zwt3IvrTd9fk0/rFFDJKGz7WyNHkYgUmNiGcItD12v0jx7FZ52EJzl3Av1RyJUQK18+8EYPh3SGiU9dt7VX0aF0uo6JouKhOeldUvMP+AugQz8fUclwTQsbboVg27Yxo0DyATVwThW5a56R6Qf5ZiQJluFuzs5y98rq0S5q046lE6o3vVmJpEdwjeSCJoET5CL4nTgkXyWvhm4eB8u/e66l3o0qbaSx8q9YYmT9EpRcl5TP4ThLBKETYdzVvg4exjQfektMatk5EyUpEIhZPXh5vXpJZesdfO9LJ8zTaHBsBjDPU7cdNgQMbebpataRi8A0el2/IJXl+E+olgAz5zC4i2O1Q=="}',
},
{
id: '6424c353eaf78d000766e9510b125fba',
source: 'bitgo',
type: 'tss',
commonKeychain:
'19bdfe2a4b498a05511381235a8892d54267807c4a3f654e310b938b8b424ff4adedbe92f4c146de641c67508a961324c8504cdf8e0c0acbb68d6104ccccd781',
verifiedVssProof: true,
isBitGo: true,
},
];
});
it('should return true when validating a well formatted address prefixed with 0x', async function () {
const address = '0xf941ae3cbe5645dccc15da8346b533f7f91f202089a5521653c062b2ff10b304';
basecoin.isValidAddress(address).should.equal(true);
});
it('should return false when validating an old address', async function () {
const address = '0x2959bfc3fdb7dc23fed8deba2fafb70f3e606a59';
basecoin.isValidAddress(address).should.equal(false);
});
it('should return false when validating an incorrectly formatted', async function () {
const address = 'wrongaddress';
basecoin.isValidAddress(address).should.equal(false);
});
it('should return true for isWalletAddress with valid address for index 4', async function () {
const newAddress = '0x8b3c7807730d75792dd6c49732cf9f014d6984a9c77d386bdb1072a9e537d8d8';
const index = 4;
const params = { commonKeychain, address: newAddress, index, keychains };
(await basecoin.isWalletAddress(params)).should.equal(true);
});
it('should throw error for isWalletAddress when keychains is missing', async function () {
const address = '0x2959bfc3fdb7dc23fed8deba2fafb70f3e606a59';
const index = 0;
const params = { commonKeychain, address, index };
await assert.rejects(async () => basecoin.isWalletAddress(params));
});
it('should throw error for isWalletAddress when new address is invalid', async function () {
const wrongAddress = 'badAddress';
const index = 0;
const params = { commonKeychain, address: wrongAddress, index };
await assert.rejects(async () => basecoin.isWalletAddress(params), {
message: `invalid address: ${wrongAddress}`,
});
});
});
describe('ID Validation', () => {
it('check id', async function () {
const network: Network = Network.TESTNET;
const aptos = new Aptos(new AptosConfig({ network }));
const senderAddress = AccountAddress.fromString(
'0xc8f02d25aa698b3e9fbd8a08e8da4c8ee261832a25a4cde8731b5ec356537d09'
);
const recipientAddress = AccountAddress.fromString(
'0xf7405c28a02cf5bab4ea4498240bb3579db45951794eb1c843bef0534c093ad9'
);
const transaction = await aptos.transaction.build.simple({
sender: senderAddress,
data: {
function: '0x1::coin::transfer',
typeArguments: [APTOS_COIN],
functionArguments: [recipientAddress, 1000],
},
options: {
maxGasAmount: 200000,
gasUnitPrice: 100,
expireTimestamp: 1732699236,
accountSequenceNumber: 14,
},
});
const DEFAULT_PUBLIC_KEY = Buffer.alloc(32);
const DEFAULT_SIGNATURE = Buffer.alloc(64);
const publicKey = new Ed25519PublicKey(utils.getBufferFromHexString(DEFAULT_PUBLIC_KEY.toString('hex')));
const signature = new Ed25519Signature(DEFAULT_SIGNATURE);
const senderAuthenticator = new AccountAuthenticatorEd25519(publicKey, signature);
const id = generateUserTransactionHash({ transaction, senderAuthenticator });
id.should.equal('0x923d1cfed3afac24048451160337db75ba282912157ee43407b572923801d5ba');
});
});
});
Выполнить команду
Для локальной разработки. Не используйте в интернете!