Skip to content

Commit 7969a2c

Browse files
authored
Merge pull request #1 from matejdrazic/mdrazic/pause-effect
early draft of pause functionality
2 parents 6368c41 + 0c57136 commit 7969a2c

22 files changed

Lines changed: 150 additions & 26 deletions

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
GOERLI_RPC_URL=

README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,12 @@
1-
# maintenance-utils
1+
# maintenance-utils
2+
NodeCLI for various purposes
3+
4+
## Commands
5+
6+
```pause``` - Pause all transfers across all bridges on selected enviroment (devnet, testnet or mainnet)
7+
8+
Run with:
9+
10+
```
11+
node pause -pk "private-key" -m "mnemonic words" -e "environment"
12+
```

src/bridgePausing.ts

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,56 @@
1+
import 'dotenv/config';
12
import axios from 'axios';
2-
import {Command, Option} from 'commander';
3-
import {ConfigUrl} from "./constants";
4-
import {RawConfig} from "@buildwithsygma/sygma-sdk-core";
3+
import { ethers } from 'ethers';
4+
import { Command, Option } from 'commander';
5+
import { SharedConfig } from "./constants";
6+
import { getWalletsForDifferentProviders, deriveWalletsFromMnemonic, sendPauseTransactions } from "./utils";
7+
import { RawConfig, Domain } from '@buildwithsygma/sygma-sdk-core';
58

69
const program = new Command();
7-
console.log("pero");
810

911
program
1012
.name("pause-bridge")
1113
.description("Pauses all bridge instances across all networks")
12-
.argument("<string>", "mnemonic or private key of the wallet")
14+
.version("0.0.1")
15+
16+
program
17+
.command("pause")
1318
.addOption(
14-
new Option('--environment, -e', 'Environment on which to pause bridge instances')
19+
new Option('-e, --environment <environment>', 'Environment on which to pause bridge instances')
1520
.choices(['devnet', 'testnet', 'mainnet'])
1621
)
17-
.action(async (mnemonic: string, environment: keyof typeof ConfigUrl) => {
22+
.addOption(
23+
new Option('-pk, --private-key <privateKey>', 'Private key to use for signing transactions')
24+
)
25+
.addOption(
26+
new Option('-m, --mnemonic <mnemonic>', 'Mnemonic to use for signing transactions').conflicts('private-key')
27+
)
28+
.action(async (configs: any) => {
1829
try {
19-
console.log("pero");
20-
const response = await axios.get(ConfigUrl[environment]) as unknown as RawConfig;
21-
console.log(response)
30+
const network: keyof typeof SharedConfig = configs.environment;
31+
const {
32+
privateKey,
33+
mnemonic
34+
} = configs;
35+
36+
const {
37+
data
38+
} = await axios.get(SharedConfig[network]) as unknown as { data: RawConfig };
39+
40+
const networks: Array<Domain> = data.domains.filter((network: Domain) => network.name === "ethereum"); // just evms for now
41+
42+
let wallets: Array<ethers.Wallet | ethers.HDNodeWallet> = [];
43+
44+
if (mnemonic) {
45+
wallets = await deriveWalletsFromMnemonic(mnemonic, networks);
46+
} else if (privateKey) {
47+
wallets = await getWalletsForDifferentProviders(privateKey, networks);
48+
} else {
49+
throw new Error('Either mnemonic or private key must be provided');
50+
}
51+
52+
await sendPauseTransactions(networks, wallets);
53+
2254
} catch (err) {
2355
if (err instanceof Error) {
2456
throw new Error(`Failed to fetch shared config because of: ${err.message}`);
@@ -27,3 +59,5 @@ program
2759
}
2860
}
2961
})
62+
63+
program.parse(process.argv);

src/constants.ts

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

src/constants/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { chainIdToRpc } from "./rpc";
2+
export { SharedConfig } from "./sharedConfig";

src/constants/rpc.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// chain id -> provider url
2+
export const chainIdToRpc = {
3+
5: process.env.GOERLI_RPC_URL,
4+
}
5+

src/constants/sharedConfig.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export const SharedConfig = {
2+
devnet: "https://chainbridge-assets-stage.s3.us-east-2.amazonaws.com/shared-config-dev.json",
3+
testnet: "https://chainbridge-assets-stage.s3.us-east-2.amazonaws.com/shared-config-test.json",
4+
mainnet: "https://sygma-assets-mainnet.s3.us-east-2.amazonaws.com/shared-config-mainnet.json"
5+
};

src/utils.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { ethers } from 'ethers';
2+
import { chainIdToRpc } from "./constants";
3+
import { Bridge__factory } from "@buildwithsygma/sygma-contracts";
4+
import { Domain } from "@buildwithsygma/sygma-sdk-core";
5+
6+
export async function getWalletsForDifferentProviders(privateKey: string, networks: Array<Domain>) {
7+
const wallets = [];
8+
for (let i = 0; i < networks.length; i++) {
9+
const network = networks[i];
10+
const chainId = network.chainId;
11+
const rpc = chainIdToRpc[chainId as keyof typeof chainIdToRpc];
12+
if (rpc) {
13+
const provider = new ethers.JsonRpcProvider(rpc);
14+
const wallet = new ethers.Wallet(privateKey, provider); // add error handling for invalid private key
15+
wallets.push(wallet);
16+
}
17+
}
18+
return wallets;
19+
}
20+
21+
export async function deriveWalletsFromMnemonic(mnemonic: string, networks: Array<Domain>) {
22+
const wallets = [];
23+
for (let i = 0; i < networks.length; i++) {
24+
const network = networks[i];
25+
const chainId = network.chainId;
26+
const rpc = chainIdToRpc[chainId as keyof typeof chainIdToRpc];
27+
if (rpc) {
28+
const provider = new ethers.JsonRpcProvider(rpc);
29+
const wallet = ethers.Wallet.fromPhrase(mnemonic, provider);
30+
wallets.push(wallet);
31+
}
32+
}
33+
return wallets;
34+
}
35+
36+
export async function sendPauseTransactions(networks: Array<any>, wallets: Array<ethers.Wallet | ethers.HDNodeWallet>) {
37+
const receipts = [];
38+
for (let i = 0; i < networks.length; i++) {
39+
const network = networks[i];
40+
const wallet = wallets[i];
41+
const bridge = Bridge__factory.connect(network.bridge, wallet);
42+
const tx = await bridge.adminPauseTransfers();
43+
console.log(`Transaction no. ${i + 1} completed, bridge on ${network.name} paused`);
44+
receipts.push(tx);
45+
}
46+
return receipts;
47+
}

tsconfig.cjs.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
"declaration": true,
99
"esModuleInterop": true,
1010
"module": "commonjs",
11-
"outDir": "./dis-cjs"
11+
"outDir": "./dist-cjs"
1212
}
1313
}

types/bridgePausing.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
export {};
1+
import 'dotenv/config';
22
//# sourceMappingURL=bridgePausing.d.ts.map

0 commit comments

Comments
 (0)