Skip to content

Commit 44ce73c

Browse files
committed
Add withdrawals collector script
1 parent 48623bb commit 44ce73c

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: Run Collect Withdrawals Script
2+
3+
on:
4+
schedule:
5+
# Every 15 minutes (UTC)
6+
- cron: "*/15 * * * *"
7+
workflow_dispatch: # allow manual trigger from Actions tab
8+
9+
jobs:
10+
run-script:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout repo
15+
uses: actions/checkout@v4
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v5
19+
with:
20+
python-version: "3.11"
21+
22+
- name: Install dependencies
23+
run: |
24+
python -m pip install --upgrade pip
25+
pip install -r requirements.txt
26+
27+
- name: Run Collect Withdrawals Script
28+
env:
29+
PK: ${{ secrets.MN_COLLECTOR_PK }}
30+
INFURA_KEY: ${{ secrets.INFURA_KEY }}
31+
run: python scripts/ticker.py
32+

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ requests
77
pathlib
88
pytest-xdist
99
git+https://github.com/starkware-libs/starkware-starknet-utils.git@main#egg=test_utils&subdirectory=python
10+
web3==5.31.3

scripts/tikcer.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/usr/bin/env python3.9
2+
3+
import os
4+
import argparse
5+
from web3 import Web3, Account, HTTPProvider, eth
6+
from web3.middleware import (
7+
buffered_gas_estimate_middleware,
8+
construct_sign_and_send_raw_middleware,
9+
)
10+
11+
node_uri_pat = "https://{chain}.infura.io/v3/{infura_key}"
12+
batcher_abi = [
13+
{
14+
"inputs": [],
15+
"name": "tick",
16+
"outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
17+
"stateMutability": "nonpayable",
18+
"type": "function",
19+
}
20+
]
21+
22+
default_batcher_address = "0x613d088F2e5a2ED91635016483dAFa3cd47a8964"
23+
24+
25+
def new_wallet_account(w3: Web3, eth_private_key):
26+
return new_wallet_account_list(w3, [eth_private_key])[0]
27+
28+
29+
def new_wallet_account_list(w3: Web3, eth_private_keys, name=None):
30+
"""
31+
Creates new eth accounts and registers them (including the private keys).
32+
The new accounts may have no funds.
33+
This function is more efficient than calling new_wallet_account() many times
34+
as it creates only one middleware layer.
35+
"""
36+
accounts = [Account.from_key(eth_private_key) for eth_private_key in eth_private_keys]
37+
38+
w3.middleware_onion.add(construct_sign_and_send_raw_middleware(accounts), name=name)
39+
w3.middleware_onion.remove("gas_estimate")
40+
w3.middleware_onion.add(buffered_gas_estimate_middleware, name="gas_estimate")
41+
return [account.address for account in accounts]
42+
43+
44+
def parse_args():
45+
parser = argparse.ArgumentParser(
46+
description="Collect pending withdrawals waiting for l1_recipient"
47+
)
48+
parser.add_argument(
49+
"--chain",
50+
type=str,
51+
choices=["mainnet", "sepolia"],
52+
default="mainnet",
53+
help="Select Ethereum chain (default: mainnet)",
54+
)
55+
parser.add_argument(
56+
"--batcher_contract",
57+
type=str,
58+
default=default_batcher_address,
59+
help="L1 withdrawal batching contract",
60+
)
61+
args = parser.parse_args()
62+
args.batcher_contract = Web3.toChecksumAddress(args.batcher_contract)
63+
return args
64+
65+
66+
def main():
67+
args = parse_args()
68+
account = Account.from_key(os.environ["PK"])
69+
node_uri = node_uri_pat.format(chain=args.chain, infura_key=os.environ["INFURA_KEY"])
70+
w3 = Web3(HTTPProvider(node_uri))
71+
72+
assert w3.isConnected()
73+
w3.eth.default_account = new_wallet_account(w3, account.key)
74+
batcher = w3.eth.contract(address=args.batcher_contract, abi=batcher_abi)
75+
print(w3.eth.default_account, batcher.address)
76+
77+
pending_funds = batcher.functions.tick().call()
78+
if pending_funds:
79+
print(f"Awaiting {pending_funds//10**6} withdrawal waiting.")
80+
th = batcher.functions.tick().transact()
81+
print(f"Pending withdrawal collected, tx hash: {th.hex()}")
82+
else:
83+
print("nothing to tick")
84+
85+
86+
if __name__ == "__main__":
87+
main()

0 commit comments

Comments
 (0)