Skip to content

Commit f9b19df

Browse files
Merge pull request #5941 from BitGo/WIN-5187-xdc-nonbg
feat: adding test case for non bitgo recovery for xdc
2 parents 58f9888 + 5cc707d commit f9b19df

File tree

3 files changed

+93
-2
lines changed

3 files changed

+93
-2
lines changed

modules/sdk-coin-xdc/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-xdc/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: '0x4477bc3e2472b2c5580c010526dfc5614871952d',
50+
};
51+
52+
const getTxListResponseNonBitGoRecovery: Record<string, unknown> = {
53+
status: '1',
54+
result: [
55+
{
56+
hash: '0xede855d43d70ea1bb75db63d4f75113dae0845f0d4bdb0b2d8bda55249c70812',
57+
nonce: '23',
58+
from: '0x4477bc3e2472b2c5580c010526dfc5614871952d',
59+
},
60+
],
61+
message: 'OK',
62+
};
63+
64+
const getBalanceRequestNonBitGoRecovery: Record<string, string> = {
65+
module: 'account',
66+
action: 'balance',
67+
address: '0x4477bc3e2472b2c5580c010526dfc5614871952d',
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: '0xd76b586901850f2c656db0cbef795c0851bbec35',
78+
userKeyData:
79+
'{"iv":"XeXwD5B465wYvao9WFZC7A==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"caDtzBCF3IA=","ct":"0qr0YV2DgN68F9luNpjFQhwDTIXwyTTYdQirvbgITHqIDmITmV1IMgkKIdzSZBfmLkB6bG46oVF4snVG7lXEJz2twrutI01g59xjw88ULgR5wV5ZdFrGcmNZvOQ1H5imoWGS8bVKONmeF55TBgi49r9x3dsmgWvJ/EHeApj/FrAP1BLX/Rgl57kZqnNoryl55P8L2cJtJE1weDBD+/GsggdrO/dYBmihKTWyTBVa7UBIIgV5wOd4RXbZN1Hg2Vc0bY56KrpZbY1CsdQiIwH3tkKFPdqthlHVEfS8XViaYVl0Go3C/mUMYZH7CTg/s4LMpdlWzh3iRnmGercvIFZBfcehgNVv9H/OctYZnKfUdI5mZsVGxQRIMWr8oFbmjR3pYJ94oxS8assAzl7hNI4RJi/u4N9/5VJIi//069zsMsgA+k4b3u3xvivkTjO5sscAPs/Sp0mb5QLQhP48D/sHIYwhQiThJaH+flSoUQu5LNWmucmYr08lRRiI07O7DZAY2pplLSvBfkrBtgTgi+rLN95lKkxi7PYTGWuek1Sd/XiXit6EJ5FImYH2eKEVgatYvKfj/BdNJ2iHmeaykajtjpr21lt0Iqk98iZLZfCp5w4hfHHHB4QCrBzCAeG2MEPqmrAN67z4gMxUbkI+j9lYp5SyvlFmDIm78SyQ60371Wfr+7b4+wFqPq9fumXBZ4i0xYbcWTrKjYrn5bO5o3LWiRoh7EW8mzbMIC2m/DwIwdCHodbz4g31Psnk6Yk6UqEMq5JhOoUJYuVhYthNmbRlI59UDg+rz/HO9nYnZqsUgubSKcZArqM1J4T4+EDKuHtgnCQm2hqHlsJu+/n73jU33GEm86pDdcb8udHsfPCvhEIuLw6ZyThiX8JEOCi8Ueb0GPL31MSkJ7L7cOizgp6lHgs4nZorZfUIKjDd3twcpBNXjT15KEQbrW8RQChXmVl0b5N8BAom6e9Xpz2kDRGbvbYfBOdiht5Vr5Sm7prAQVVCZTWq6/qOZFWr7LJ+Cdw1qYt64UFcBHNtaX3d5WOMNNMqesrglVTW7w2Gscu7XaxoA4cTOKvMemG1cWTag3kr8oNgtz5gXsfbSo7CJrN8vw=="}',
80+
backupKeyData:
81+
'{"iv":"J32VIJhO9Cbf5bqcv75Kag==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"ZQ5VsHdXM4Q=","ct":"XTgAUy8TZALKtt/PtJGAWbHfuExH5C5yw3y8EryrcY3uZdektl3WkL4KHHGTtL9yzssCTOWUMTemoAKipd+W/3mpZuQ88p+lloIgU7Tce3RLBG+gu665bsvTUuVpfMrpZHxDXXVMzwoUVHaxwfvu2tgduDnpkD/BX2RN5qfI6P6zz5r8UuWbiDPKEaqpcAHQ+RBitBQiOxNAlRNYexnUx1pCqcK08hqrqdQvx7elXXdCI3TwepGW7QwRzWa9pxvM9d85AWESueJ2B4JrZ5bkrIzXixGJcoUAJVvGfD69zoLUH9einnMafpocETBUDQyevC/j/1FwgZUCeGcb4U9N9tQJtR0fozzgpAo91nWA5UfkD2+hzRvz2p1Dmc+4bNb6s/7vK+BIOdpe4blzI43PxMLoBGkEQHlGHYCrOUnbV7dcxlyPv0qfom8K4f6/74YEKiMPjwA3sCcntWboW8gUPHF2xx/WAgmHI9DOiXsCJZMHx4GiZmY/pR9RVe/OeFAqPLWJoT6KaizTJD3So4/G5oHKPgTQbMIPi1lYtqKdOuhycISsaEgnkG1a8Tq5CN0tk5VywSmj4kSrqqjcp7kbAW+ViaNkZLuSibomK9AvuOGkEZBqDEuyFJnS4oayQTLxnstzO1JJGhmrCskH9B/QIIrUVl1IOv/IVyPg4M7T1g0+YfHdAXduLXu9bjHkqzGaSQZu35bs5QKy0bKEhAwoj+zgYAF/gZBH0/iPzrWM2xu/HMeQKwI0KFLOiBx3cMmNYE+Fb6vCjpVXBTYYUCBOjRnrAuR/lc3AnjAefCMAD89+FQ+QW5IzZv97lrSw0Rb+DIctfXddUKK7yyBe8CcZWU1dGAYsb/hk+H5lTZJBur5M3a1vzPMi68HKnRt7XZmyBsvPA8t0JVJmlc0RejqDrcps4uKjKdMaDNOvBzmEijdVv8N5q0Ng+yHwq3BolqoYn4mVJOrMuRlZt4pODkI8uOU1Ha/VStLzhT2HFexZ+Y0JzM0DS5hsygHt4Dz6/RfZTKHYvxzuRiHNLbmNcOBvVbBOL2Lm+Dlo3fFuVD3fS08vJuafc/uAfatpRwRqgE/EzvZOpnZyHcr4lUVEhRrDYw=="}',
82+
walletPassphrase: 'prithvishet2503',
83+
walletRootAddress: '0x4477bc3e2472b2c5580c010526dfc5614871952d',
84+
getTxListRequest: getTxListRequestNonBitGoRecovery,
85+
getTxListResponse: getTxListResponseNonBitGoRecovery,
86+
getBalanceRequest: getBalanceRequestNonBitGoRecovery,
87+
getBalanceResponse: getBalanceResponseNonBitGoRecovery,
88+
};

modules/sdk-coin-xdc/test/unit/xdc.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 { Xdc, Txdc } 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()].xdcExplorerBaseUrl as string;
109+
const maxFeePerGasvalue = 20000000000;
110+
const maxPriorityFeePerGasValue = 10000000000;
111+
const chain_id = 51;
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('txdc');
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)