Skip to content

Commit 0f10503

Browse files
Merge pull request #5942 from BitGo/WIN-5187-wemix
feat: adding test cases for non bitgo recovery for Wemix
2 parents f9b19df + 096a27c commit 0f10503

File tree

3 files changed

+93
-2
lines changed

3 files changed

+93
-2
lines changed

modules/sdk-coin-wemix/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-wemix/test/resources.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,47 @@ export const mockDataUnsignedSweep = {
5454
getBalanceRequest: getBalanceRequestUnsignedSweep,
5555
getBalanceResponse: getBalanceResponseUnsignedSweep,
5656
};
57+
58+
const getTxListRequestNonBitGoRecovery: Record<string, string> = {
59+
module: 'account',
60+
action: 'txlist',
61+
address: '0xcf05f9c25579832d2237e52ffb4d16ca3153bb15',
62+
};
63+
64+
const getTxListResponseNonBitGoRecovery: Record<string, unknown> = {
65+
status: '1',
66+
result: [
67+
{
68+
hash: '0xede855d43d70ea1bb75db63d4f75113dae0845f0d4bdb0b2d8bda55249c70812',
69+
nonce: '23',
70+
from: '0xcf05f9c25579832d2237e52ffb4d16ca3153bb15',
71+
},
72+
],
73+
message: 'OK',
74+
};
75+
76+
const getBalanceRequestNonBitGoRecovery: Record<string, string> = {
77+
module: 'account',
78+
action: 'balance',
79+
address: '0xcf05f9c25579832d2237e52ffb4d16ca3153bb15',
80+
};
81+
82+
const getBalanceResponseNonBitGoRecovery: Record<string, unknown> = {
83+
status: '1',
84+
result: '100000000000000000',
85+
message: 'OK',
86+
};
87+
88+
export const mockDataNonBitGoRecovery = {
89+
recoveryDestination: '0x26efa259beeb4373aff0f0e37167a7b6255fe34e',
90+
userKeyData:
91+
'{"iv":"LkXud+OJjiSgFSz2GUF90g==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"qpjtz9Fp4u8=","ct":"syqUtFTqWy/itfdnwckTSSk8a2tYVQIApUP811rfWBth0ODZzjLzWs+pM0IYi9IM9boQ5E94/Kutk1HVNWC7q1vG88B/ZI5wVc5Scr2wgOJ62TifS6VNgmaGfAlMfke0tL+2icn/NqiEAPXlan4VpiSIzGV50V+BPW6x/zWOqzA8OiZ7WApsqpIMiNHal+27g1F41ALGnpVhuDBr/M67FLvzdCz38dZoqcbV67CncqXzGFvDmw4Z2h86DP4jJFhGQUkgJqwKjFVOFREnFClkg1VgPryYpWvx5liHZv4URTSlqTUj7VS/FtYoJFobilSnHz0tCKM8q81sJ4hz9mzxsQRL6xuV4SoM44TGSPutQfCTNWyXqq9PNe4er3BpRS4FGl6qrBFkyAkx4zF8NJDI3+miFlG1YmLSq7aLRuU5RAnQTTY+XnvbE7xsF9zhAzTsJk9zjZUQVDZDAC+kOiaYtZBC8wsJ26i1zbo9g6V9O+9X5tVFauCt47W9kodi+PNservj8tBYvG6YjjJ1SK/l2SQAffa+PZX4+b51Qf8FBawdcRkCfasZPjUYjYZ0KiiRQmSg3OMz3AqEw8yelxJ/lkbBOccrNcbVpYZh+OTB2Kjvvhk5aAs4WiaO+7PM3YrhjGhjln1eAvh4ABzXlOHV31f41p5/MeOgWwf0SH2aZocM1erCpk0+dk6Mu4Z46D9NTYY0JoaljKsvxpWidtRHp93YkuNjVI1qIaMyJj3O8pe6782JfT+sRQfJJxTvLThzm0ljy9hQGHK98GRejge4T1p66Jkhu94kmKpJJHOt9iVuU5mbc3kA0pi148B5HTRzH6/I0v2m25tcspsagvaiQeaU4+RAsoTrWiFtHG3UByCMaS6jiIU0b5zKKPbWqoQV85ywyZOi4xtIQoqFUte7v1ziTzaywGb3tG2iAHYRrJgAPg2wNYDYVOOIJWdhtxw8G/uKMq9EZ8+l2FLdXpUHDc1UJzNqf6ijYbixMv0RHDMXtPC+870ciyVjGAAfPwWrnXafgJewRsYpeUxiJvf1A9DEZ0IyVKT4TjohEmuHlUxT5d0QJ1e1Pxa0qaeLrNoU"}',
92+
backupKeyData:
93+
'{"iv":"j01iJ6D6yrIAvQG39rUK7A==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"FZhlN/ZL7EQ=","ct":"l8rWds8F0MUrnyvIkfoU9Pcf5rR9eJwZkyjzzrrQaor4oIYcqNl3+OfuXYFssSMhor3AuylZ85hLaovqndvfYtPBC2AZ1sM1AAMmwmptGWeuRuzIjd9bVUzGJdAljDZ3/ikcmMbV/drT7HSu6l2Z2tsc5XJwJujO2YobCOlBBGWM8lIqCcCORa+oliLXW2YxsRzEEM5b2H/RqqQKpZeJvYK3l5EX8aAyTIMqrIv2ZS9MaWXcY95/IYB5xO/a1zZRfxDv5WBu4RsVtS5uIH99PPNJIcAXAAFN+n58EsfZbtJ6aDWCDngtEaghiwlSUhcdwU59P6eUmzEjEvY4RJwDMX0Mq9C1kfwRxNn9+BwdaO24HaH4uWsJlHNp++onlTEb9pDp0nmMgWLQjh1n0CrF5XThSt9i5s2jMFNEE7LruwRT+TKzpN48If2L8IvwFiFWLuUtQDJ0jdl/8pRB0C0yc443DIxROBluh8hwmYqglK5YtaBZitXl++jSaXdRlgJ4wBfTuDp4Lg62wWgprPhaRFWfMJpXedDfzZEDjc2UFZvKKe7V1+f7kSB9ol18aE4xpEN5vta6L81ZMgVWkbWu7Ascu4P4vOl1M8tPWkLmg6SpPbbxYdp5Q52DMkhLz8zuAaUD5tbt6tVKTCd0USEus2s+r4VJd6WImdvNUsg9anSpWQp48jWx0ZcLHnACOyT1bRC/VcYwEB6XE81uyhWdZYrhly/MKcJNO9Auij/RxNPpELYNL1Ru+Vh7ZNSE3EotzoRba0+QkHCOq3xGi2tSzZlmJe329LZEjpiQyGM7tLV8ZnSngXXUEXGQXVDaCeQQz82VYhZpKeC9xCTPLCUMETWfiqU4XhFfRzyLjIAZKlzq6yOMsLrXFpsA85XpJciyYhO9MHd2/8yEyZfernqN3qLY0dl4dVR53E4UwWSwLSbXFV6dD1ZheB4G8tSp2oq/IRHw7ZuQlRcW0Bn5kaDr3gs5+7enQ9SSBLkPrAYfeloAVyz/ugKJ3+ZtEBFkTbobORUHtfsrjYqxb7fn6/n5kvrm8fZzy3Oq+SG//B1guuyElM/cJ8J+yHQvNv0AKQCm"}',
94+
walletPassphrase: 'prithvi-bitgo',
95+
walletRootAddress: '0xcf05f9c25579832d2237e52ffb4d16ca3153bb15',
96+
getTxListRequest: getTxListRequestNonBitGoRecovery,
97+
getTxListResponse: getTxListResponseNonBitGoRecovery,
98+
getBalanceRequest: getBalanceRequestNonBitGoRecovery,
99+
getBalanceResponse: getBalanceResponseNonBitGoRecovery,
100+
};

modules/sdk-coin-wemix/test/unit/wemix.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 { Wemix, Twemix } 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

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

0 commit comments

Comments
 (0)