Skip to content

Commit d50d402

Browse files
committed
feat(abstract-eth): update the derive address logic for recovery
ticket: WIN-5700
1 parent cc16eb8 commit d50d402

File tree

1 file changed

+65
-49
lines changed

1 file changed

+65
-49
lines changed

modules/abstract-eth/src/abstractEthLikeNewCoins.ts

Lines changed: 65 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,40 +1243,57 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
12431243
return calculateForwarderV1Address(forwarderFactoryAddress, calculationSalt, initCode);
12441244
}
12451245

1246-
deriveAddressFromPublicKey(publicKey: string): string {
1246+
deriveAddressFromPublicKey(commonKeychain: string, index: number): string {
1247+
const derivationPath = `m/${index}`;
1248+
const pubkeySize = 33;
1249+
1250+
const ecdsaMpc = new Ecdsa();
1251+
const derivedPublicKey = Buffer.from(ecdsaMpc.deriveUnhardened(commonKeychain, derivationPath), 'hex')
1252+
.subarray(0, pubkeySize)
1253+
.toString('hex');
1254+
1255+
const publicKey = Buffer.from(derivedPublicKey, 'hex').slice(0, 66).toString('hex');
1256+
12471257
const keyPair = new KeyPairLib({ pub: publicKey });
12481258
const address = keyPair.getAddress();
12491259
return address;
12501260
}
12511261

1252-
getConsolidationAddress(params: EthConsolidationRecoveryOptions, index: number): string {
1262+
getConsolidationAddress(params: EthConsolidationRecoveryOptions, index: number): string[] {
1263+
const possibleConsolidationAddresses: string[] = [];
12531264
if (params.walletContractAddress && params.bitgoFeeAddress) {
12541265
const ethNetwork = this.getNetwork();
12551266
const forwarderFactoryAddress = ethNetwork?.walletV4ForwarderFactoryAddress as string;
12561267
const forwarderImplementationAddress = ethNetwork?.walletV4ForwarderImplementationAddress as string;
12571268
try {
1258-
return this.generateForwarderAddress(
1269+
const forwarderAddress = this.generateForwarderAddress(
12591270
params.walletContractAddress,
12601271
params.bitgoFeeAddress,
12611272
forwarderFactoryAddress,
12621273
forwarderImplementationAddress,
12631274
index
12641275
);
1276+
possibleConsolidationAddresses.push(forwarderAddress);
12651277
} catch (e) {
12661278
console.log(`Failed to generate forwarder address: ${e.message}`);
12671279
}
12681280
}
12691281

12701282
if (params.userKey) {
12711283
try {
1272-
return this.deriveAddressFromPublicKey(params.userKey);
1284+
const derivedAddress = this.deriveAddressFromPublicKey(params.userKey, index);
1285+
possibleConsolidationAddresses.push(derivedAddress);
12731286
} catch (e) {
1274-
console.log(`Failed to generate derived address: ${e.message}`);
1287+
console.log(`Failed to generate derived address: ${e}`);
12751288
}
12761289
}
1277-
throw new Error(
1278-
'Unable to generate consolidation address. Check that wallet contract address, fee address, or user key is valid.'
1279-
);
1290+
1291+
if (possibleConsolidationAddresses.length === 0) {
1292+
throw new Error(
1293+
'Unable to generate consolidation address. Check that wallet contract address, fee address, or user key is valid.'
1294+
);
1295+
}
1296+
return possibleConsolidationAddresses;
12801297
}
12811298

12821299
async recoverConsolidations(params: EthConsolidationRecoveryOptions): Promise<Record<string, unknown> | undefined> {
@@ -1303,50 +1320,49 @@ export abstract class AbstractEthLikeNewCoins extends AbstractEthLikeCoin {
13031320

13041321
for (let i = startIdx; i < endIdx; i++) {
13051322
const consolidationAddress = this.getConsolidationAddress(params, i);
1306-
1307-
const recoverParams = {
1308-
apiKey: params.apiKey,
1309-
backupKey: params.backupKey,
1310-
gasLimit: params.gasLimit,
1311-
recoveryDestination: params.recoveryDestination,
1312-
userKey: params.userKey,
1313-
walletContractAddress: consolidationAddress,
1314-
derivationSeed: '',
1315-
isTss: params.isTss,
1316-
eip1559: {
1317-
maxFeePerGas: params.eip1559?.maxFeePerGas || 20,
1318-
maxPriorityFeePerGas: params.eip1559?.maxPriorityFeePerGas || 200000,
1319-
},
1320-
replayProtectionOptions: {
1321-
chain: params.replayProtectionOptions?.chain || 0,
1322-
hardfork: params.replayProtectionOptions?.hardfork || 'london',
1323-
},
1324-
bitgoKey: '',
1325-
ignoreAddressTypes: [],
1326-
};
1327-
1328-
let recoveryTransaction;
1329-
try {
1330-
recoveryTransaction = await this.recover(recoverParams);
1331-
} catch (e) {
1332-
if (
1333-
e.message === 'Did not find address with funds to recover' ||
1334-
e.message === 'Did not find token account to recover tokens, please check token account' ||
1335-
e.message === 'Not enough token funds to recover'
1336-
) {
1337-
lastScanIndex = i;
1338-
continue;
1323+
for (const address of consolidationAddress) {
1324+
const recoverParams = {
1325+
apiKey: params.apiKey,
1326+
backupKey: params.backupKey,
1327+
gasLimit: params.gasLimit,
1328+
recoveryDestination: params.recoveryDestination,
1329+
userKey: params.userKey,
1330+
walletContractAddress: address,
1331+
derivationSeed: '',
1332+
isTss: params.isTss,
1333+
eip1559: {
1334+
maxFeePerGas: params.eip1559?.maxFeePerGas || 20,
1335+
maxPriorityFeePerGas: params.eip1559?.maxPriorityFeePerGas || 200000,
1336+
},
1337+
replayProtectionOptions: {
1338+
chain: params.replayProtectionOptions?.chain || 0,
1339+
hardfork: params.replayProtectionOptions?.hardfork || 'london',
1340+
},
1341+
bitgoKey: '',
1342+
ignoreAddressTypes: [],
1343+
};
1344+
let recoveryTransaction;
1345+
try {
1346+
recoveryTransaction = await this.recover(recoverParams);
1347+
} catch (e) {
1348+
if (
1349+
e.message === 'Did not find address with funds to recover' ||
1350+
e.message === 'Did not find token account to recover tokens, please check token account' ||
1351+
e.message === 'Not enough token funds to recover'
1352+
) {
1353+
lastScanIndex = i;
1354+
continue;
1355+
}
1356+
throw e;
1357+
}
1358+
if (isUnsignedSweep) {
1359+
consolidationTransactions.push((recoveryTransaction as MPCSweepTxs).txRequests[0]);
1360+
} else {
1361+
consolidationTransactions.push(recoveryTransaction);
13391362
}
1340-
throw e;
1341-
}
1342-
1343-
if (isUnsignedSweep) {
1344-
consolidationTransactions.push((recoveryTransaction as MPCSweepTxs).txRequests[0]);
1345-
} else {
1346-
consolidationTransactions.push(recoveryTransaction);
13471363
}
13481364

1349-
lastScanIndex = i;
1365+
// lastScanIndex = i;
13501366
}
13511367

13521368
if (consolidationTransactions.length === 0) {

0 commit comments

Comments
 (0)