-
Notifications
You must be signed in to change notification settings - Fork 292
/
Copy pathwithdrawFunds.js
95 lines (84 loc) · 3.6 KB
/
withdrawFunds.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
const { ethers } = require('hardhat');
const { providers, Wallet } = require('ethers');
const {
arbLog,
requireEnvVariables,
addCustomNetworkFromFile,
} = require('arb-shared-dependencies');
const { getArbitrumNetwork, InboxTools } = require('@arbitrum/sdk');
const { ARB_SYS_ADDRESS } = require('@arbitrum/sdk/dist/lib/dataEntities/constants');
const { ArbSys__factory } = require('@arbitrum/sdk/dist/lib/abi/factories/ArbSys__factory');
require('dotenv').config();
requireEnvVariables(['PRIVATE_KEY', 'CHAIN_RPC', 'PARENT_CHAIN_RPC']);
/**
* Set up: instantiate wallets connected to providers
*/
const walletPrivateKey = process.env.PRIVATE_KEY;
const parentChainProvider = new providers.JsonRpcProvider(process.env.PARENT_CHAIN_RPC);
const childChainProvider = new providers.JsonRpcProvider(process.env.CHAIN_RPC);
const parentChainWallet = new Wallet(walletPrivateKey, parentChainProvider);
const childChainWallet = new Wallet(walletPrivateKey, childChainProvider);
const main = async () => {
await arbLog('DelayedInbox withdraw funds from the parent chain (L2MSG_signedTx)');
/**
* Add the custom network configuration to the SDK if present
*/
addCustomNetworkFromFile();
/**
* Use childChainNetwork to create an Arbitrum SDK InboxTools instance
*/
const childChainNetwork = await getArbitrumNetwork(childChainProvider);
const inboxTools = new InboxTools(parentChainWallet, childChainNetwork);
/**
* Here we use the ArbSys precompile to withdraw our funds;
* we'll be setting it by sending it as a message from delayed inbox on the parent chain!!!
*/
const arbSys = ArbSys__factory.connect(ARB_SYS_ADDRESS, childChainProvider);
const arbsysIface = arbSys.interface;
const calldata = arbsysIface.encodeFunctionData('withdrawEth', [parentChainWallet.address]);
const transactionRequest = {
data: calldata,
to: ARB_SYS_ADDRESS,
value: 1, // Only set 1 wei since it just a test tutorial, but you can set any amount
};
/**
* We need to extract the transaction hash in the child chain first so we can check later if it was executed
*/
const signedTransaction = await inboxTools.signChildTx(transactionRequest, childChainWallet);
const transactionHash = ethers.utils.parseTransaction(signedTransaction).hash;
/**
* We now send the transaction through the Delayed Inbox on the parent chain
*/
const sendMessageParentChainTransactionRequest = await inboxTools.sendChildSignedTx(
signedTransaction,
);
const sendMessageParentChainTransactionReceipt =
await sendMessageParentChainTransactionRequest.wait();
console.log(
`Withdraw txn initiated on the parent chain! 🙌 ${sendMessageParentChainTransactionReceipt.transactionHash}`,
);
/**
* Now we successfully send the transaction to the delayed inbox on the parent chain
* We wait for the transaction to be executed on the child chain
*/
console.log(
`Now we need to wait tx: ${transactionHash} to be executed on the child chain (may take ~15 minutes) ... `,
);
const transactionReceipt = await childChainProvider.waitForTransaction(transactionHash);
const status = transactionReceipt.status;
if (status == true) {
console.log(
`Transaction executed on the child chain!!! 🥳 After a challenge period has passed, you can go to https://bridge.arbitrum.io/ to execute your withdrawal and receive your funds!`,
);
} else {
throw new Error(
`The transaction failed to execute on the child chain. Please verify if the gas provided was enough`,
);
}
};
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});