Skip to content

Commit ffadfbc

Browse files
feat: adding test case for non-bitgo recovery for FLR
Ticket: WIN-5187 TICKET: WIN-5187
1 parent b6c1977 commit ffadfbc

File tree

3 files changed

+93
-2
lines changed

3 files changed

+93
-2
lines changed

modules/sdk-coin-flr/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
"@bitgo/abstract-eth": "^24.1.0",
4444
"@bitgo/sdk-core": "^32.1.0",
4545
"@bitgo/statics": "^51.7.0",
46-
"@ethereumjs/common": "^2.6.5"
46+
"@ethereumjs/common": "^2.6.5",
47+
"@ethereumjs/tx": "^3.3.0"
4748
},
4849
"devDependencies": {
4950
"@bitgo/sdk-api": "^1.61.5",

modules/sdk-coin-flr/test/resources.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,47 @@ export const mockDataUnsignedSweep = {
4242
getBalanceRequest: getBalanceRequestUnsignedSweep,
4343
getBalanceResponse: getBalanceResponseUnsignedSweep,
4444
};
45+
46+
const getTxListRequestNonBitGoRecovery: Record<string, string> = {
47+
module: 'account',
48+
action: 'txlist',
49+
address: '0xfeffc77a7b7e4921484e9af3fd5602b5a2c9018e',
50+
};
51+
52+
const getTxListResponseNonBitGoRecovery: Record<string, unknown> = {
53+
status: '1',
54+
result: [
55+
{
56+
hash: '0xede855d43d70ea1bb75db63d4f75113dae0845f0d4bdb0b2d8bda55249c70812',
57+
nonce: '23',
58+
from: '0xfeffc77a7b7e4921484e9af3fd5602b5a2c9018e',
59+
},
60+
],
61+
message: 'OK',
62+
};
63+
64+
const getBalanceRequestNonBitGoRecovery: Record<string, string> = {
65+
module: 'account',
66+
action: 'balance',
67+
address: '0xfeffc77a7b7e4921484e9af3fd5602b5a2c9018e',
68+
};
69+
70+
const getBalanceResponseNonBitGoRecovery: Record<string, unknown> = {
71+
status: '1',
72+
result: '100000000000000000',
73+
message: 'OK',
74+
};
75+
76+
export const mockDataNonBitGoRecovery = {
77+
recoveryDestination: '0xc97d9c8d769aefcc7c32857b5cc583f30ad68ecb',
78+
userKeyData:
79+
'{"iv":"/bk/xK76bHfCug3ko8pvKg==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"Q84QpUq1ybI=","ct":"c5LT7X2W6DQyj4OQv3IdGdaphbupQKviqHuOEr9coVoB0MNVSBbo5PuWoVWUe1CK/2GLZpXKXcpii6pUEYA+RgHKLCvNXN1jmSW/QwePQjHTKLC5yjL4huLkmxKTYBpNz2FttuvkdjNVMUMmBAyv0lWhq2hQf2VAq+7XfzXRyhm8f8CuYvFNp3M0NrxZmphMayg2WPd3ONymZKjTwxNak9DzZ0duWqeGaT+tSAbBLQp9Y3s8qVMEHj8to/gJGXxRaWYT2Zxb5OLR6qkjRYwwP8E8ywllgYxn5diSPkS/2QFLqRVoT1WxmJT2P9nwfhabiZi7U1owwvFBp27eF4efpx+bXoH89eqldSJGGOV8rwR3MUuAdLx5cNYqsC3h4biiam5cz7uuN7NVuOlE+46qqWekQlxgWmJrGi8dmbxrbcpVoerLl1ozU4DbIbrzuFfm9ncwy3tsKiALNyXmYTwOl505Knb7zCkHRFAauNSTiHvF1syPgixwNWV4J+dSFHjdWjoldwvoRsggS85u5qxk738aTc9umFVo9mOIQmHZUYZA22PocvzUW1EchSulbVDHPbQVZ1DrRDVMJ+MzhT+t+ePlXP2RBxL69zTnK+2L2Xa9doRhVnbOCFA/lEx2WMhiV2c95gakkucs0YGcwmqQZ/6ttc1wdkIKf27hsyAiUP8HczzgogwXIzSss2WilMxXV+VBmNFxuAACC6fGSKwAaqbBm5XdI51KO+A3V24ImfzZPNvnsJ21TkZQ3hlUf6Mznii/lV0bR+zG9mQ6riWyDKunMzl5zNy/eDh0vUJQrz5OxOxCghME9bem4aV4Wy4qt7L58N9Sh3GcV1CmgeQJXS3gB1YtjD8RFUG2dwGqLNhbJ4N8V6B441mF6ZdswoJcUbTqQWOL1QP20XWwhcxV97FTGsHfYZT/jqG36eFMDzLInkSYzmhgm+Cc0esqdwxJ+rFhahvKUlGxVJ9SZmu2m9Y9FwCdtMlHcETK+00iVuZfZscDfBMgGeMcBhDzu6PRCB4nBohztTZbzSjr3x2AS5Aoe9KZUxr2DzCVWmOT9LU9bQ8dnec0Dj8hgLdzPpi0XtV4UttGQnuCv7awRWmHIg=="}',
80+
backupKeyData:
81+
'{"iv":"o/6M84s9QYg6J4qBFPnT1g==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"TXOYiG8qw5A=","ct":"4u6DPzyq1G8uvsrbOcTLOPpP8ITMZkDnh/sVlneLOxjHy6TELzgL1+XmO+SLqY+BPA7lX/kmWVnyEPX/Wy+SHAufr4gA9N6GHio9wPLQ0fnN59VYgB1px9405wW+JMo2e1gtGF4Gr2rLXdbSncIfw2V5dJ4SeHlHtiQZyc2JTy+PFHsrtfHcilBlf/5P4otEhf9RY5cAL05WvyGuFiap+u9LCMCWzlSdS8qdi0Tk8ci6FQ7ku/0aOOHvG2bikeKVMraarngYIHEmEIgKdutCNqWTlqnBi+aTI8GUdwc/Gb2aKg1pfdmhqujlDfsSs4e54UqjNACo4vAtolAhPdTtZHosJ90F5BUSlxvDeMURA6LnkCZ2sMVOaegEXGfU3EnmL+92mYzlwENpjaKQaTqHWCJYm1LCOtgAItXNAfRqqENNWMsoZBd/16Rf8LjePMvUXbzBDJ7/CYPkuMusNBga9gjbp1H/YcH29oJmKQyZOh7dNzshpmiyi3B/IzgxZxD9VbJER3/0mzgAa8dIx884UUOIOEeTbomx0HIJyTnLBL8xhT/5oiWO6bINWx0Mm9dLnnQH4hKdNGpx0VKRMhAh38axiRgGg52HZ3zOatOHXfoTmY50+JWcX+nDGOdxdHsLBJvTU+FEgVtFlrGw36cdePcc8BeHFmMuOFZ3gIer+PBxtoUsfcW6Yxs0ieRSlpx6kNjX38wMBRSmOeGtLy9PmBf7Uzi1/qkPUXATkT7+t6J+E3uEcdoG2Pu+7djv7esATFXpG7dDZXKXm7B3eRRDrWehzL/y2ZHbyQwG5konCtWx+rTzjSh6veAQ1MkbNtC8RQV391KPvhcDrCy4Tb0USjLgLjstaR51EOUKK5M6bX0E0n5gLN53JE25SPLgrWQrs43wGs/zEbGzq+ZuTbQRNldJPhiln4+Q1MrxE9ZZ9sVDRDqmQ41nWn1+doEo0gsB93H9LkZCRq+zAuaWyyWmMs2tyNOXQFQL5zEV8Fd4tlPCIwjmAv6oyZlwHAU3A3lqi4Up/pBmy5UcxJ+5Q2a1Bci5wjRCNxrM1QFY10thMqFU+w6w1OzEdzCrp45VbG2fKiUkMC7ZF8Qv3qPB"}',
82+
walletPassphrase: 'prithvishet2503',
83+
walletRootAddress: '0xfeffc77a7b7e4921484e9af3fd5602b5a2c9018e',
84+
getTxListRequest: getTxListRequestNonBitGoRecovery,
85+
getTxListResponse: getTxListResponseNonBitGoRecovery,
86+
getBalanceRequest: getBalanceRequestNonBitGoRecovery,
87+
getBalanceResponse: getBalanceResponseNonBitGoRecovery,
88+
};

modules/sdk-coin-flr/test/unit/flr.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import { BitGoAPI } from '@bitgo/sdk-api';
55

66
import { Flr, Tflr } from '../../src/index';
77
import { UnsignedSweepTxMPCv2 } from '@bitgo/abstract-eth';
8-
import { mockDataUnsignedSweep } from '../resources';
8+
import { mockDataUnsignedSweep, mockDataNonBitGoRecovery } from '../resources';
99
import nock from 'nock';
1010
import { common } from '@bitgo/sdk-core';
11+
import { FeeMarketEIP1559Transaction } from '@ethereumjs/tx';
12+
import { stripHexPrefix } from '@ethereumjs/util';
1113

1214
const bitgo: TestBitGoAPI = TestBitGo.decorate(BitGoAPI, { env: 'test' });
1315

@@ -100,3 +102,47 @@ describe('Build Unsigned Sweep for Self-Custody Cold Wallets - (MPCv2)', functio
100102
tx.unsignedTx.parsedTx?.should.have.property('outputs');
101103
});
102104
});
105+
106+
describe('Non Bitgo Recovery for Hot Wallets', function () {
107+
const bitgo = TestBitGo.decorate(BitGoAPI, { env: 'test' });
108+
const explorerUrl = common.Environments[bitgo.getEnv()].flrExplorerBaseUrl as string;
109+
const maxFeePerGasvalue = 30000000000;
110+
const maxPriorityFeePerGasValue = 15000000000;
111+
const chain_id = 114;
112+
const gasLimitvalue = 500000;
113+
114+
it('should generate a signed non-bitgo recovery tx', async () => {
115+
nock(explorerUrl)
116+
.get('/api')
117+
.twice()
118+
.query(mockDataNonBitGoRecovery.getTxListRequest)
119+
.reply(200, mockDataNonBitGoRecovery.getTxListResponse);
120+
nock(explorerUrl)
121+
.get('/api')
122+
.query(mockDataNonBitGoRecovery.getBalanceRequest)
123+
.reply(200, mockDataNonBitGoRecovery.getBalanceResponse);
124+
125+
const baseCoin: any = bitgo.coin('tflr');
126+
const transaction = await baseCoin.recover({
127+
userKey: mockDataNonBitGoRecovery.userKeyData,
128+
backupKey: mockDataNonBitGoRecovery.backupKeyData,
129+
walletContractAddress: mockDataNonBitGoRecovery.walletRootAddress,
130+
walletPassphrase: mockDataNonBitGoRecovery.walletPassphrase,
131+
recoveryDestination: mockDataNonBitGoRecovery.recoveryDestination,
132+
isTss: true,
133+
eip1559: { maxFeePerGas: maxFeePerGasvalue, maxPriorityFeePerGas: maxPriorityFeePerGasValue },
134+
gasLimit: gasLimitvalue,
135+
replayProtectionOptions: {
136+
chain: chain_id,
137+
hardfork: 'london',
138+
},
139+
});
140+
should.exist(transaction);
141+
transaction.should.have.property('id');
142+
transaction.should.have.property('tx');
143+
const tx = FeeMarketEIP1559Transaction.fromSerializedTx(Buffer.from(stripHexPrefix(transaction.tx), 'hex'));
144+
tx.getSenderAddress().toString().should.equal(mockDataNonBitGoRecovery.walletRootAddress);
145+
const jsonTx = tx.toJSON();
146+
jsonTx.to?.should.equal(mockDataNonBitGoRecovery.recoveryDestination);
147+
});
148+
});

0 commit comments

Comments
 (0)