Skip to content

Commit

Permalink
test(sdk-coin-rune): add tests for wallet recovery
Browse files Browse the repository at this point in the history
Ticket: COIN-2417
  • Loading branch information
at31416 committed Jan 7, 2025
1 parent 6bcb1c6 commit f8db801
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 3 deletions.
2 changes: 1 addition & 1 deletion modules/sdk-coin-rune/src/rune.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class Rune extends CosmosCoin {

/** @inheritDoc **/
protected getPublicNodeUrl(): string {
return Environments[this.bitgo.getEnv()].coreumNodeUrl;
return Environments[this.bitgo.getEnv()].runeNodeUrl;
}

/** @inheritDoc **/
Expand Down
12 changes: 12 additions & 0 deletions modules/sdk-coin-rune/test/resources/trune.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,15 @@ export const testnetCoinAmounts = {
amount4: { amount: '-1', denom: 'rune' },
amount5: { amount: '1000000000', denom: 'arune' },
};

export const wrwUser = {
senderAddress: 'sthor1gqek8kl5mr9c37rl8yp2mljne67jgaqm96jg2f',
destinationAddress: 'sthor1tl46dxfh3qupqxgap5vtpah4pxwn35j5tnjzls',
userPrivateKey:
'{"iv":"9rcHMytmmnHjG1llBoc49g==","v":1,"iter":10000,"ks":256,"ts":64,"mode" :"ccm","adata":"","cipher":"aes","salt":"8lFAwTrcCzQ=","ct":"1gMRC60nu01IYr jgir9GCuQNLMZC2vt/pFjgL+tV3K7/rviSguDsua133PkNEeuty1mZxNH2S1TKu1KxZJMlB+MAs vo7k9dIyCgQvkX/nbJFFaRrnLL55mcQe0PhCdVNRHx9doXMngRF+UqEMLD8F0HNE1+ZPGzsathH DLFPxLCRMrwA/Ss/LQowGiXo4WnzVK3MQcX6wdmZvfV+S3xswRjHkLvolVY3rVGP5PkU86Wwrmy e1CKM4hSGA8FModa718Svk7C+LHr0yOTuuPftXtH0fAPPo9KH7f+EbBWMJPQgjK8DW/z1xnDgLH dzhveyNPevqUqb3FEyutjow+KBkxl+xHqJ4gKcU9MLsghPMCy0zSq2kBbhlqWJ7XwduhHVGv2nT rlsEfh7Z0fbqZTX1RQ5AKZhSBFEqmq1hKxRlhVcr9KqBw814tIfdFD7nMgV7rz+3X8cJaK2tDXH 0QaY8bJGwxwH38FsfNevs8Qf2bx5VrD/Vw3wo0G5hJ7+TdPCrib8UWyxPGuruH7b8hwCUTZaq97 zkDp7c79BDWyH8ycTxQXjLPwb1CwpUiRDc6NHD2p3iGVaztMdQOMXmPeeMhBNGVI0MPAfSdcDip 2E5Ek0fwnI1mEuFjPMkc+VOlsVhlWfV/9Xpoh3NadPhqg3i9Cr2uNT/PSyHd/jpIqG5DlaaEvVD f7COqNvXX5Qqmlr9dL3R2cf0zP8TPImAlRfef4D8zatHtylKkImMc0JcdcXTzwU/5tf21o/Y701 DLYjwUUgqQ57ObHHNlSvmdIuO1rD5LAn96NAYNRStrENqmbibE5MsYrp9nPAprCNFnZR6UNpXwD hvq9gvxRG+PjmXGj0nuyR7cshxURLy0/p4tq7LkGjk4Gg31Mgk41lcYUW2tLuUbTYmpteu3Cdwe DFuLsfI1qZxKyr6V5Nse3ZAvnJLTZnQXiHOnc2y5/e53+MAVupXR7HZzx7SIJ+fqxpjxvccmgJC sWaPo+Lsx6KaSNkQGFMGuyZ87IEvm7vk2GyIP+FQUn4nmTdEDLzg7nNo+zf5WT4A6Yz3GNAa3Nh 2QHZSFGWcubOXDawh6lAjZ78GNK9yJDp22dJTmfZ+1TsVORpbZw="}',
backupPrivateKey:
'{"iv":"0EDqGU1yBE2PM4ry6TxARA==","v":1,"iter":10000,"ks":256,"ts":64,"mode" :"ccm","adata":"","cipher":"aes","salt":"a8T0fVVhTz0=","ct":"syCrJ+RD8oHZ4z jltLmyNS/VVmSLXLMAdnVnoPNEfFX9mIMAycYCajMR297l09fPsWWqDcDs0cSI0xNbnMjyW30b/ JOvQ33eaBSiyBr3vbmhaEFduZTUgOCNg/Js0cAkEkeE/KDkfOUB0HzfSEQb6m0eXmWgGSnySUOd TlZZ/thT7j2oPHVpPE52h6Yi3LS1Jkt3S7ySStXvG/4iurhcL32a32Fx3IQxs/bg8JBIGlRG644 aLttCJ+uPihaSISUGn1hh0iEz2ZAaCoCkq7oNPrK+pxHHOmbjxp6XpV67EmQ/JRfSt47eW3jC7A D+xaLLHspjQifp6ClZeHT2pBrkcWrZfr1uL5w3CKrXQeJ0pXUoRmJwGys4hm5Bzu4imANo+jd1+ wg73ByYQ5VwRhV1qhb82vUrQ0i4k5Gt2l6U2LZ/DMQiUbq7FdjYWqfZmk18GIZ6g3IPJtGjnA6x o8RTvkytMMv8btsx/aa6jE6EMeFtGzlhhJJunpcS4QG4IkIuyAjPafwOklEwXklZCLDpKdVYgTR RE0XHC0VXOGQwGUARzMZwQO5OaRyQkxtZ5/CawI5jrwMZP+bpC9dKzsGOXfSvvFsJWnkboXyy09 bFwTuKHx0ZILdA/8Xq5689YEmFljHTeQ0Es/q5y5kU+XzT4sjjgxz1qqhUJVh7wDwQevRDWTwGJ Lfi2AeLsv2f0PKiGTYJzQGSXUerhLMwhg3rXNfXGkrWSmEhJH/RsvF6CdaRKWxVd+k8K5ULLwK+ sdujA5murZ24KI5z0Yr9qW2TSsJRG3PS+ZH1q3VGYaz6k912QVzyvzds8+hfaHNtr6OGBWahGZo JchgnQHSfAZxOUz7K7WNzh934HK5+e11/lF/Fxssumz2OStFWI18oBB7/8YBi6PEp3sFddOQVSA BXRGuStolGna43nly4bavOic7XIoNHs61hynMeR6NcthsSrj5xZ6q36EqLdfkDImQvu+3BXClT7 Q4bdEfXm0t7Bgmid4NeJ1I3grXZMOmVbPgcypfxp2jrkjme/R0/eJL4B38WU2xjxDg+WlBGy8dA xg8ll+n2NkA7lvJz5NBDxbGHRAhtyVTF8YA+Oxps3rumIw=="}',
bitgoPublicKey:
'02d754ffd645ba3d87fbdeb3578dbc22fc252ebb299416434a7059d9638f52d11e0fd153d9d dfb2a193531ac5b7d3b223188a957de1312d3ede35305ee70b76376',
walletPassphrase: 'Ghghjkg!455544llll',
};
124 changes: 122 additions & 2 deletions modules/sdk-coin-rune/test/unit/rune.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { BitGoAPI } from '@bitgo/sdk-api';
import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
import { NetworkType } from '@bitgo/statics';
import { coins, NetworkType } from '@bitgo/statics';
import BigNumber from 'bignumber.js';
import sinon from 'sinon';
import { Rune, Trune } from '../../src';
import { RuneUtils } from '../../src/lib/utils';
import { mainnetAddress } from '../resources/rune';
import { TEST_SEND_TX, TEST_TX_WITH_MEMO, testnetAddress } from '../resources/trune';
import { TEST_SEND_TX, TEST_TX_WITH_MEMO, testnetAddress, wrwUser } from '../resources/trune';
const bech32 = require('bech32-buffer');
import should = require('should');
import { beforeEach } from 'mocha';
import { CosmosTransaction, SendMessage } from '@bitgo/abstract-cosmos';
import { GAS_AMOUNT } from '../../src/lib/constants';

describe('Rune', function () {
let bitgo: TestBitGoAPI;
Expand Down Expand Up @@ -265,4 +268,121 @@ describe('Rune', function () {
stub.restore();
});
});

describe('Recover transaction: success path', () => {
const sandBox = sinon.createSandbox();
const coin = coins.get('tthorchain:rune');
const testBalance = '1500000';
const testAccountNumber = '123';
const testSequenceNumber = '0';
const testChainId = 'thorchain-stagenet-2';

beforeEach(() => {
const accountBalance = sandBox.stub(Trune.prototype, 'getAccountBalance' as keyof Trune);
accountBalance.withArgs(wrwUser.senderAddress).resolves(testBalance);

const accountDetails = sandBox.stub(Trune.prototype, 'getAccountDetails' as keyof Trune);
accountDetails.withArgs(wrwUser.senderAddress).resolves([testAccountNumber, testSequenceNumber]);

const chainId = sandBox.stub(Trune.prototype, 'getChainId' as keyof Trune);
chainId.withArgs().resolves(testChainId);
});

afterEach(() => {
sandBox.restore();
sinon.restore();
});

it('should recover funds for non-bitgo recoveries', async function () {
const res = await trune.recover({
userKey: wrwUser.userPrivateKey,
backupKey: wrwUser.backupPrivateKey,
bitgoKey: wrwUser.bitgoPublicKey,
walletPassphrase: wrwUser.walletPassphrase,
recoveryDestination: wrwUser.destinationAddress,
});
res.should.not.be.empty();
res.should.hasOwnProperty('serializedTx');
sandBox.assert.calledOnce(trune.getAccountBalance);
sandBox.assert.calledOnce(trune.getAccountDetails);
sandBox.assert.calledOnce(trune.getChainId);

const truneTxn = new CosmosTransaction(coin, testnetUtils);
truneTxn.enrichTransactionDetailsFromRawTransaction(res.serializedTx);
const truneTxnJson = truneTxn.toJson();
const sendMessage = truneTxnJson.sendMessages[0].value as SendMessage;
const balance = new BigNumber(testBalance);
const actualBalance = balance.minus(new BigNumber(GAS_AMOUNT));
should.equal(sendMessage.amount[0].amount, actualBalance.toFixed());
});
});

describe('Recover transaction: failure path', () => {
const sandBox = sinon.createSandbox();
const testZeroBalance = '0';
const testAccountNumber = '123';
const testSequenceNumber = '0';
const testChainId = 'thorchain-stagenet-2';

beforeEach(() => {
const accountBalance = sandBox.stub(Trune.prototype, 'getAccountBalance' as keyof Trune);
accountBalance.withArgs(wrwUser.senderAddress).resolves(testZeroBalance);

const accountDetails = sandBox.stub(Trune.prototype, 'getAccountDetails' as keyof Trune);
accountDetails.withArgs(wrwUser.senderAddress).resolves([testAccountNumber, testSequenceNumber]);

const chainId = sandBox.stub(Trune.prototype, 'getChainId' as keyof Trune);
chainId.withArgs().resolves(testChainId);
});

afterEach(() => {
sandBox.restore();
sinon.restore();
});

it('should throw error if backupkey is not present', async function () {
await trune
.recover({
userKey: wrwUser.userPrivateKey,
bitgoKey: wrwUser.bitgoPublicKey,
walletPassphrase: wrwUser.walletPassphrase,
recoveryDestination: wrwUser.destinationAddress,
})
.should.rejectedWith('missing backupKey');
});

it('should throw error if userkey is not present', async function () {
await trune
.recover({
backupKey: wrwUser.backupPrivateKey,
bitgoKey: wrwUser.bitgoPublicKey,
walletPassphrase: wrwUser.walletPassphrase,
recoveryDestination: wrwUser.destinationAddress,
})
.should.rejectedWith('missing userKey');
});

it('should throw error if wallet passphrase is not present', async function () {
await trune
.recover({
userKey: wrwUser.userPrivateKey,
backupKey: wrwUser.backupPrivateKey,
bitgoKey: wrwUser.bitgoPublicKey,
recoveryDestination: wrwUser.destinationAddress,
})
.should.rejectedWith('missing wallet passphrase');
});

it('should throw error if there is no balance', async function () {
await trune
.recover({
userKey: wrwUser.userPrivateKey,
backupKey: wrwUser.backupPrivateKey,
bitgoKey: wrwUser.bitgoPublicKey,
walletPassphrase: wrwUser.walletPassphrase,
recoveryDestination: wrwUser.destinationAddress,
})
.should.rejectedWith('Did not have enough funds to recover');
});
});
});
3 changes: 3 additions & 0 deletions modules/sdk-core/src/bitgo/environments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ interface EnvironmentTemplate {
beraNodeUrl: string;
zetaNodeUrl: string;
coreumNodeUrl: string;
runeNodeUrl: string;
islmNodeUrl: string;
dotNodeUrls: string[];
tronNodes: {
Expand Down Expand Up @@ -142,6 +143,7 @@ const mainnetBase: EnvironmentTemplate = {
beraNodeUrl: '', // TODO(WIN-693): update url when mainnet goes live
zetaNodeUrl: 'https://zetachain.blockpi.network', // reference https://www.zetachain.com/docs/reference/api/
coreumNodeUrl: 'https://full-node.mainnet-1.coreum.dev:1317',
runeNodeUrl: 'https://thornode.ninerealms.com',
islmNodeUrl: 'https://rest.cosmos.haqq.network',
dotNodeUrls: ['wss://rpc.polkadot.io'],
tronNodes: {
Expand Down Expand Up @@ -193,6 +195,7 @@ const testnetBase: EnvironmentTemplate = {
beraNodeUrl: '', // TODO(WIN-693): update url when testnet goes live
zetaNodeUrl: 'https://rest.nodejumper.io/zetachaintestnet', // reference : https://www.zetachain.com/docs/reference/api/
coreumNodeUrl: 'https://full-node.testnet-1.coreum.dev:1317',
runeNodeUrl: 'https://stagenet-thornode.ninerealms.com',
islmNodeUrl: 'https://rest.cosmos.testedge2.haqq.network ',
dotNodeUrls: ['wss://westend-rpc.polkadot.io'],
tronNodes: {
Expand Down

0 comments on commit f8db801

Please sign in to comment.