Skip to content

Commit b321bcb

Browse files
feat: unsigned sweep for wemix
Ticket: WIN-4884 TICKET: WIN-4884
1 parent 7ffbfce commit b321bcb

File tree

4 files changed

+119
-2
lines changed

4 files changed

+119
-2
lines changed

modules/sdk-coin-wemix/src/lib/transactionBuilder.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { TransferBuilder } from './transferBuilder';
66

77
export class TransactionBuilder extends AbstractTransactionBuilder {
88
protected _transfer: TransferBuilder;
9+
private _signatures: any;
910

1011
constructor(_coinConfig: Readonly<CoinConfig>) {
1112
super(_coinConfig);
@@ -24,6 +25,11 @@ export class TransactionBuilder extends AbstractTransactionBuilder {
2425
return this._transfer;
2526
}
2627

28+
addSignature(publicKey, signature) {
29+
this._signatures = [];
30+
this._signatures.push({ publicKey, signature });
31+
}
32+
2733
protected getContractData(addresses: string[]): string {
2834
throw new Error('Method not implemented.');
2935
}

modules/sdk-coin-wemix/src/wemix.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@
88

99
import { BaseCoin, BitGoBase, common, MPCAlgorithm, MultisigType, multisigTypes } from '@bitgo/sdk-core';
1010
import { BaseCoin as StaticsBaseCoin, coins } from '@bitgo/statics';
11-
import { AbstractEthLikeNewCoins, recoveryBlockchainExplorerQuery } from '@bitgo/abstract-eth';
11+
import {
12+
AbstractEthLikeNewCoins,
13+
recoveryBlockchainExplorerQuery,
14+
UnsignedSweepTxMPCv2,
15+
RecoverOptions,
16+
OfflineVaultTxInfo,
17+
} from '@bitgo/abstract-eth';
1218
import { TransactionBuilder } from './lib';
1319

1420
export class Wemix extends AbstractEthLikeNewCoins {
@@ -39,6 +45,10 @@ export class Wemix extends AbstractEthLikeNewCoins {
3945
return 'ecdsa';
4046
}
4147

48+
protected async buildUnsignedSweepTxnTSS(params: RecoverOptions): Promise<OfflineVaultTxInfo | UnsignedSweepTxMPCv2> {
49+
return this.buildUnsignedSweepTxnMPCv2(params);
50+
}
51+
4252
async recoveryBlockchainExplorerQuery(query: Record<string, string>): Promise<Record<string, unknown>> {
4353
const apiToken = common.Environments[this.bitgo.getEnv()].wemixExplorerApiToken;
4454
const explorerUrl = common.Environments[this.bitgo.getEnv()].wemixExplorerBaseUrl;

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,48 @@ export const SEND_TX_BROADCAST_LEGACY =
99

1010
export const SEND_TX_AMOUNT_ZERO_BROADCAST =
1111
'0xf901cc02843b9aca0083b8a1a0948f977e912ef500548a0c3be6ddde9899f1199b8180b901643912521500000000000000000000000019645032c7f1533395d44a629462e751084d3e4c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000005ec67da8000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000411badc5af505b10ebf6bc80322567ac71af7970a9ac1ebdf33f656bbfa2b40f652239e4ecd9b7b391db68fb84467e11dacb5d54f38770d79f4c95c9c1d4eba0a21c000000000000000000000000000000000000000000000000000000000000008208d3a01c830bee5c43a339f4f6bec2e705045986482d72cf0c504183c121a4c246a57ba068b7460d6e0b0e5b354053c78cd412286adc79e21ec3bb9169930b47e455b071';
12+
13+
const getTxListRequestUnsignedSweep: Record<string, string> = {
14+
module: 'account',
15+
action: 'txlist',
16+
address: '0x742838193c4169f6b2ba7b0e03f723c3ba0928e1',
17+
};
18+
19+
const getTxListResponseUnsignedSweep: Record<string, unknown> = {
20+
status: '1',
21+
result: [
22+
{
23+
hash: '0xede855d43d70ea1bb75db63d4f75113dae0845f0d4bdb0b2d8bda55249c70812',
24+
nonce: '23',
25+
from: '0x742838193c4169f6b2ba7b0e03f723c3ba0928e1',
26+
},
27+
],
28+
message: 'OK',
29+
};
30+
31+
const getBalanceRequestUnsignedSweep: Record<string, string> = {
32+
module: 'account',
33+
action: 'balance',
34+
address: '0x742838193c4169f6b2ba7b0e03f723c3ba0928e1',
35+
};
36+
37+
const getBalanceResponseUnsignedSweep: Record<string, unknown> = {
38+
status: '1',
39+
result: '100000000000000000',
40+
message: 'OK',
41+
};
42+
43+
export const mockDataUnsignedSweep = {
44+
userKey:
45+
'029d2ded2d39ee7cd8d8bbba8b25e4c60bb09297936fa6b223de1f495b5ee20dcaf762367f9691f7719cb5e13e59d725669a18aad1e2522dd141fa4c7fd3d25c17',
46+
backupKey:
47+
'029d2ded2d39ee7cd8d8bbba8b25e4c60bb09297936fa6b223de1f495b5ee20dcaf762367f9691f7719cb5e13e59d725669a18aad1e2522dd141fa4c7fd3d25c17',
48+
derivationPath: 'm/0',
49+
derivationSeed: '',
50+
walletBaseAddress: '0x742838193c4169f6b2ba7b0e03f723c3ba0928e1',
51+
recoveryDestination: '0xd76b586901850f2c656db0cbef795c0851bbec35',
52+
getTxListRequest: getTxListRequestUnsignedSweep,
53+
getTxListResponse: getTxListResponseUnsignedSweep,
54+
getBalanceRequest: getBalanceRequestUnsignedSweep,
55+
getBalanceResponse: getBalanceResponseUnsignedSweep,
56+
};

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

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
import 'should';
1+
import * as should from 'should';
22

33
import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
44
import { BitGoAPI } from '@bitgo/sdk-api';
55

66
import { Wemix, Twemix } from '../../src/index';
7+
import { UnsignedSweepTxMPCv2 } from '@bitgo/abstract-eth';
8+
import { mockDataUnsignedSweep } from '../resources';
9+
import nock from 'nock';
10+
import { common } from '@bitgo/sdk-core';
711

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

@@ -40,3 +44,55 @@ describe('wemix', function () {
4044
});
4145
});
4246
});
47+
48+
describe('Build Unsigned Sweep for Self-Custody Cold Wallets (MPCv2)', function () {
49+
const bitgo = TestBitGo.decorate(BitGoAPI, { env: 'test' });
50+
const explorerUrl = common.Environments[bitgo.getEnv()].wemixExplorerBaseUrl as string;
51+
52+
it('should generate an unsigned sweep without derivation path', async () => {
53+
nock(explorerUrl)
54+
.get('/api')
55+
.twice()
56+
.query(mockDataUnsignedSweep.getTxListRequest)
57+
.reply(200, mockDataUnsignedSweep.getTxListResponse);
58+
nock(explorerUrl)
59+
.get('/api')
60+
.query(mockDataUnsignedSweep.getBalanceRequest)
61+
.reply(200, mockDataUnsignedSweep.getBalanceResponse);
62+
63+
const baseCoin: any = bitgo.coin('twemix');
64+
const transaction = (await baseCoin.recover({
65+
userKey: mockDataUnsignedSweep.userKey,
66+
backupKey: mockDataUnsignedSweep.backupKey,
67+
walletContractAddress: mockDataUnsignedSweep.walletBaseAddress,
68+
recoveryDestination: mockDataUnsignedSweep.recoveryDestination,
69+
isTss: true,
70+
eip1559: { maxFeePerGas: 20000000000, maxPriorityFeePerGas: 10000000000 },
71+
gasLimit: 500000,
72+
replayProtectionOptions: {
73+
chain: 1112,
74+
hardfork: 'london',
75+
},
76+
})) as UnsignedSweepTxMPCv2;
77+
should.exist(transaction);
78+
transaction.should.have.property('txRequests');
79+
transaction.txRequests.length.should.equal(1);
80+
const txRequest = transaction.txRequests[0];
81+
txRequest.should.have.property('walletCoin');
82+
txRequest.walletCoin.should.equal('twemix');
83+
txRequest.should.have.property('transactions');
84+
txRequest.transactions.length.should.equal(1);
85+
const tx = txRequest.transactions[0];
86+
tx.should.have.property('nonce');
87+
tx.should.have.property('unsignedTx');
88+
tx.unsignedTx.should.have.property('serializedTxHex');
89+
tx.unsignedTx.should.have.property('signableHex');
90+
tx.unsignedTx.should.have.property('derivationPath');
91+
tx.unsignedTx.should.have.property('feeInfo');
92+
tx.unsignedTx.feeInfo?.should.have.property('fee');
93+
tx.unsignedTx.feeInfo?.should.have.property('feeString');
94+
tx.unsignedTx.should.have.property('parsedTx');
95+
tx.unsignedTx.parsedTx?.should.have.property('spendAmount');
96+
tx.unsignedTx.parsedTx?.should.have.property('outputs');
97+
});
98+
});

0 commit comments

Comments
 (0)