Skip to content
This repository was archived by the owner on Feb 11, 2025. It is now read-only.

Commit 7542834

Browse files
committed
fix: multiple things
1 parent 037b61f commit 7542834

File tree

10 files changed

+179
-80
lines changed

10 files changed

+179
-80
lines changed

actions/transferAll/core.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,15 @@ import { Account } from "../../ui/pickAccounts";
1111
import TOKENS from "../../default-tokens.json";
1212
import { Ora } from "ora";
1313
import { oraLog } from "../../oraLog";
14-
import { getNonce } from "./getNonce";
14+
import { estimateFee, execute } from "../../execute";
1515

1616
export async function transferAll(acc: Account, newAddress: string, ora: Ora) {
1717
const { privateKey } = acc;
1818
if (!privateKey) {
1919
throw new Error("No private key for account to credit");
2020
}
21-
const keyPair = ec.getKeyPair(privateKey);
22-
const starkKey = ec.getStarkKey(keyPair);
23-
if (!BigNumber.from(acc.signer).eq(starkKey)) {
24-
throw new Error(
25-
"Account cant be controlled with the selected private key or seed"
26-
);
27-
}
2821

2922
const provider = new SequencerProvider({ network: acc.networkId as any });
30-
const account = new SNAccount(provider, acc.address.toLowerCase(), keyPair);
3123
const tokens = TOKENS.filter((t) => t.network === acc.networkId);
3224
const calls = Object.entries(acc.balances)
3325
.filter(([, balance]) => utils.parseEther(balance).gt(0))
@@ -53,8 +45,7 @@ export async function transferAll(acc: Account, newAddress: string, ora: Ora) {
5345
});
5446

5547
if (calls.length) {
56-
const nonce = await getNonce(acc.address, acc.networkId); // use this to get the nonce, as this covers old and new way of getting nonce
57-
const { suggestedMaxFee } = await account.estimateFee(calls, { nonce });
48+
const { suggestedMaxFee } = await estimateFee(acc, calls);
5849

5950
const callsWithFee = calls.map((c) => {
6051
const tokenDetails = tokens.find((t) => t.symbol === "ETH");
@@ -82,9 +73,7 @@ export async function transferAll(acc: Account, newAddress: string, ora: Ora) {
8273
});
8374

8475
// execute with suggested max fee substracted from a potential eth transfer
85-
const transaction = await account.execute(callsWithFee, undefined, {
86-
maxFee: suggestedMaxFee,
87-
});
76+
const transaction = await execute(acc, callsWithFee);
8877

8978
oraLog(ora, `Transaction ${transaction.transaction_hash} created`);
9079

actions/transferAll/getNonce.ts

Lines changed: 0 additions & 25 deletions
This file was deleted.

actions/transferAll/ui.ts

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
import ora from "ora";
22
import prompts from "prompts";
33
import { ValidationError } from "yup";
4-
import { detectAccountIssues, fixAccountIssues } from "../../issues";
54
import { addressSchema } from "../../schema";
65
import { Account } from "../../ui/pickAccounts";
76
import { transferAll } from "./core";
87

9-
export async function showTransferAll(
10-
accounts: Account[],
11-
networkId: "mainnet-alpha" | "goerli-alpha"
12-
) {
8+
export async function showTransferAll(accounts: Account[]) {
139
const { toAddress } = await prompts(
1410
{
1511
type: "text",
@@ -32,11 +28,7 @@ export async function showTransferAll(
3228
}
3329
);
3430

35-
const spinner = ora("Detecting potential issues").start();
36-
37-
const issues = await detectAccountIssues(accounts);
38-
39-
await fixAccountIssues(accounts, networkId, issues);
31+
const spinner = ora("Transfering tokens").start();
4032

4133
const transferResults = await Promise.allSettled(
4234
accounts.map(async (acc) => transferAll(acc, toAddress, spinner))
@@ -48,5 +40,11 @@ export async function showTransferAll(
4840
}
4941
});
5042

51-
spinner.succeed("All tokens transferred");
43+
if (transferResults.every((result) => result.status === "fulfilled")) {
44+
spinner.succeed("Transfers complete");
45+
} else if (transferResults.some((result) => result.status === "fulfilled")) {
46+
spinner.fail("Some transfers failed");
47+
} else {
48+
spinner.fail("All transfers failed");
49+
}
5250
}

execute.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import {
2+
SequencerProvider as NewProvider,
3+
Account as NewAccount,
4+
} from "starknet-490";
5+
import {
6+
Call,
7+
SequencerProvider as OldProvider,
8+
Account as OldAccount,
9+
ec,
10+
} from "starknet";
11+
import { BigNumber } from "ethers";
12+
import { Account } from "./ui/pickAccounts";
13+
14+
export async function estimateFee(account: Account, call: Call[] | Call) {
15+
const calls = Array.isArray(call) ? call : [call];
16+
const lowerCaseAddress = account.address.toLowerCase();
17+
const keyPair = ec.getKeyPair(account.privateKey);
18+
const starkKey = ec.getStarkKey(keyPair);
19+
if (!BigNumber.from(account.signer).eq(starkKey)) {
20+
throw new Error(
21+
"Account cant be controlled with the selected private key or seed"
22+
);
23+
}
24+
try {
25+
const oldProvider = new OldProvider({ network: account.networkId as any });
26+
const a = new OldAccount(oldProvider, lowerCaseAddress, keyPair);
27+
return await a.estimateFee(calls);
28+
} catch {
29+
const newProvider = new NewProvider({ network: account.networkId as any });
30+
const a = new NewAccount(newProvider, lowerCaseAddress, keyPair);
31+
return a.estimateFee(calls);
32+
}
33+
}
34+
35+
export async function execute(account: Account, call: Call[] | Call) {
36+
const calls = Array.isArray(call) ? call : [call];
37+
const lowerCaseAddress = account.address.toLowerCase();
38+
const keyPair = ec.getKeyPair(account.privateKey);
39+
const starkKey = ec.getStarkKey(keyPair);
40+
if (!BigNumber.from(account.signer).eq(starkKey)) {
41+
throw new Error(
42+
"Account cant be controlled with the selected private key or seed"
43+
);
44+
}
45+
try {
46+
const oldProvider = new OldProvider({ network: account.networkId as any });
47+
const a = new OldAccount(oldProvider, lowerCaseAddress, keyPair);
48+
return await a.execute(calls);
49+
} catch (e) {
50+
console.warn("old failed", e);
51+
const newProvider = new NewProvider({ network: account.networkId as any });
52+
const a = new NewAccount(newProvider, lowerCaseAddress, keyPair);
53+
return a.execute(calls).catch((e) => {
54+
console.warn("new failed", e);
55+
throw e;
56+
});
57+
}
58+
}

index.ts

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { unionWith } from "lodash";
99
import { showTransferAll } from "./actions/transferAll/ui";
1010
import { askForExtraAccounts, extraAccount } from "./ui/extraAccount";
1111
import { equalSigner, getDefaultSigners } from "./genSigners";
12+
import { detectAccountIssues, fixAccountIssues } from "./issues";
13+
import { ec } from "starknet";
1214

1315
program
1416
.name("Argent X CLI")
@@ -38,11 +40,11 @@ program.parse();
3840
spinner.succeed("Found " + accounts.length + " wallets");
3941

4042
if (accounts.length === 0) {
41-
accounts = await extraAccount(network, privateKey);
43+
accounts = await extraAccount(network);
4244
} else if (await askForExtraAccounts()) {
4345
accounts = unionWith(
4446
accounts,
45-
await extraAccount(network, privateKey),
47+
await extraAccount(network),
4648
(a, b) => a.address === b.address
4749
);
4850
}
@@ -59,25 +61,38 @@ program.parse();
5961
}));
6062

6163
// find missing signers
62-
if (seed && accountWithSigner.some((x) => !x.privateKey)) {
64+
if (accountWithSigner.some((x) => !x.privateKey)) {
6365
spinner.start("Trying to find missing private keys");
64-
const defaultSigners = getDefaultSigners(seed);
65-
accountWithSigner
66-
.filter((x) => !x.privateKey)
67-
.forEach((x) => {
68-
const signer = defaultSigners.find(
69-
(y) => x.signer && equalSigner(x.signer, y.signer)
70-
);
71-
if (signer) {
72-
x.privateKey = signer.privateKey;
73-
}
74-
});
66+
if (seed) {
67+
const defaultSigners = getDefaultSigners(seed);
68+
accountWithSigner
69+
.filter((x) => !x.privateKey)
70+
.forEach((x) => {
71+
const signer = defaultSigners.find(
72+
(y) => x.signer && equalSigner(x.signer, y.signer)
73+
);
74+
if (signer) {
75+
x.privateKey = signer.privateKey;
76+
}
77+
});
78+
}
79+
if (privateKey) {
80+
const defaultSigner = ec.getStarkKey(ec.getKeyPair(privateKey));
81+
spinner.info(`Public key: ${defaultSigner}`);
82+
accountWithSigner
83+
.filter((x) => !x.privateKey)
84+
.forEach((x) => {
85+
if (x.signer && equalSigner(x.signer, defaultSigner)) {
86+
x.privateKey = privateKey;
87+
}
88+
});
89+
}
7590
if (accountWithSigner.some((x) => !x.privateKey)) {
7691
spinner.warn(
7792
"Could not find all private keys. Continuing with missing private keys"
7893
);
7994
} else {
80-
spinner.succeed("Found all private keys");
95+
spinner.succeed("Found all signers");
8196
}
8297
}
8398

@@ -88,7 +103,11 @@ program.parse();
88103

89104
display(filteredAccountWithSigner);
90105

91-
await showTransferAll(filteredAccountWithSigner, network);
106+
const issues = await detectAccountIssues(filteredAccountWithSigner);
107+
108+
await fixAccountIssues(accountWithSigner, network, issues);
109+
110+
await showTransferAll(filteredAccountWithSigner);
92111
})().catch((e) => {
93112
console.error("An error occured", e);
94113
process.exit(1);

issues/index.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
import { uniqBy } from "lodash";
2-
import prompts from "prompts";
3-
import { truncateAddress } from "../addressFormatting";
41
import { Account } from "../ui/pickAccounts";
52
import { detect as detectOldHashAlgo } from "./oldHashAlgo/detect";
63
import { fix as fixOldHashAlgo } from "./oldHashAlgo/fix";
4+
import { detect as detectSigner0 } from "./signer0/detect";
5+
import { fix as fixSigner0 } from "./signer0/fix";
76

87
interface IssuesMap {
98
oldHashAlgo?: string[];
9+
signer0?: string[];
1010
}
1111

1212
export async function detectAccountIssues(
1313
accounts: Account[]
1414
): Promise<IssuesMap> {
1515
const oldHashAlgo = await detectOldHashAlgo(accounts);
16-
return { oldHashAlgo };
16+
const signer0 = await detectSigner0(accounts);
17+
return { oldHashAlgo, signer0 };
1718
}
1819

1920
export async function fixAccountIssues(
@@ -25,4 +26,7 @@ export async function fixAccountIssues(
2526
if (oldHashAlgo?.length && oldHashAlgo?.length > 0) {
2627
await fixOldHashAlgo(accounts, network, oldHashAlgo);
2728
}
29+
if (issues.signer0?.length && issues.signer0?.length > 0) {
30+
await fixSigner0(accounts, network, issues.signer0);
31+
}
2832
}

issues/oldHashAlgo/fix.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
import { BigNumber } from "ethers";
22
import ora from "ora";
3-
import { Account as SNAccount } from "starknet-390/dist/account";
4-
import { Provider } from "starknet-390/dist/provider";
5-
import ec from "starknet-390/dist/utils/ellipticCurve";
6-
import stark from "starknet-390/dist/utils/stark";
3+
import { ec, Provider, stark, Account as SNAccount } from "starknet-390";
74
import { oraLog } from "../../oraLog";
85
import { Account } from "../../ui/pickAccounts";
96

107
const LATEST_ACCOUNT_IMPLEMENTATION_ADDRESS =
11-
"0x01bd7ca87f139693e6681be2042194cf631c4e8d77027bf0ea9e6d55fc6018ac";
8+
"0x01bd7ca87f139693e6681be2042194cf631c4e8d77027bf0ea9e6d55fc6018ac"; // KEEP
129

1310
export const fix = async (
1411
accounts: Account[],
@@ -48,6 +45,9 @@ export const fix = async (
4845
});
4946
oraLog(spinner, `Transaction ${transaction.transaction_hash} created`);
5047
await provider.waitForTransaction(transaction.transaction_hash);
48+
49+
// wait 1 minute extra to make sure the transaction is mined
50+
await new Promise((resolve) => setTimeout(resolve, 60000));
5151
}
5252
}
5353
spinner.succeed(`Fixed oldHashAlgo issue`);

issues/signer0/detect.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { BigNumber } from "ethers";
2+
import { Account } from "../../ui/pickAccounts";
3+
4+
export const detect = async (accounts: Account[]): Promise<string[]> => {
5+
return accounts
6+
.filter(({ signer }) => BigNumber.from(signer).eq(0))
7+
.map(({ address }) => address);
8+
};

issues/signer0/fix.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import ora from "ora";
2+
import { ec, SequencerProvider } from "starknet";
3+
import { compileCalldata } from "starknet/dist/utils/stark";
4+
import { execute } from "../../execute";
5+
import { oraLog } from "../../oraLog";
6+
import { Account, pickAccounts } from "../../ui/pickAccounts";
7+
8+
export const fix = async (
9+
accounts: Account[],
10+
network: "mainnet-alpha" | "goerli-alpha",
11+
accountsToRecover: string[]
12+
): Promise<void> => {
13+
const [accountToCredit] = await pickAccounts(accounts, network, {
14+
single: true,
15+
accountsToRecoverMessage:
16+
"Select the account you want to use for the recovery",
17+
});
18+
if (!accountToCredit) {
19+
throw new Error("No account to credit");
20+
}
21+
const privateKey = accountToCredit.privateKey;
22+
if (!privateKey) {
23+
throw new Error("No private key for account to credit");
24+
}
25+
const spinner = ora(`Fixing 0signer issue (this may take some time)`).start();
26+
const provider = new SequencerProvider({ network });
27+
const keyPair = ec.getKeyPair(privateKey);
28+
const starkKey = ec.getStarkKey(keyPair);
29+
30+
for (const address of accountsToRecover) {
31+
const transaction = await execute(accountToCredit, {
32+
contractAddress: address,
33+
entrypoint: "initialize",
34+
calldata: compileCalldata({
35+
signer: starkKey,
36+
guardian: "0",
37+
}),
38+
});
39+
oraLog(spinner, `Transaction ${transaction.transaction_hash} created`);
40+
await provider.waitForTransaction(transaction.transaction_hash);
41+
42+
const accountToUpdate = accounts.find((a) => a.address === address);
43+
if (accountToUpdate) {
44+
accountToUpdate.signer = starkKey;
45+
accountToUpdate.privateKey = privateKey;
46+
}
47+
48+
// wait 1 minute extra to make sure the transaction is mined
49+
await new Promise((resolve) => setTimeout(resolve, 60000));
50+
}
51+
spinner.succeed(`Fixed 0signer issue`);
52+
};

0 commit comments

Comments
 (0)