1+ import requests
2+ import sys
3+
4+ def main ():
5+
6+ if len (sys .argv ) != 4 :
7+ print ('Usage: create-add-validator-batch.py ACCOUNT_ID STAKING_CONTRACT FEE_RECIPIENT_IMPLEMENTATION' )
8+ sys .exit (1 )
9+
10+ ACCOUNT_ID = sys .argv [1 ]
11+ STAKING_CONTRACT = sys .argv [2 ]
12+ FEE_RECIPIENT = sys .argv [3 ]
13+
14+ is_mainnet = input ('Are you using mainnet? (y/n): ' ).lower () == 'y'
15+ api_url = 'https://api.kiln.fi/v1/eth/onchain/v1/keys' if is_mainnet else 'https://api.testnet.kiln.fi/v1/eth/onchain/v1/keys'
16+
17+ api_token = input ('Enter the Kiln API token: ' )
18+
19+ total_count = input ('Enter the total number of validators to create: ' )
20+
21+ tx_batch_size = int (input ('Enter the transaction batch size: ' ))
22+
23+ batch_size = int (input ('Enter the API query batch size: ' ))
24+
25+ print ("" )
26+
27+ batch_count = int (total_count ) // batch_size
28+
29+ concatenated_public_keys = ''
30+ concatenated_signatures = ''
31+
32+ for i in range (batch_count ):
33+ print (f'Querying batch { i + 1 } of { batch_count } ' )
34+ # Create the request
35+ response = requests .post (
36+ api_url ,
37+ headers = {
38+ 'Content-Type' : 'application/json' ,
39+ 'Authorization' : f'Bearer { api_token } '
40+ },
41+ json = {
42+ 'account_id' : ACCOUNT_ID ,
43+ 'fee_recipient_contract_address' : FEE_RECIPIENT ,
44+ 'staking_contract_address' : STAKING_CONTRACT ,
45+ 'number' : batch_size ,
46+ 'format' : "cli_deposit"
47+ }
48+ )
49+
50+ # extract the json response
51+ data = response .json ()["data" ]
52+
53+ for item in data :
54+ concatenated_public_keys += item ['pubkey' ]
55+ concatenated_signatures += item ['signature' ]
56+
57+ # extract the data and concatenate the public keys and signatures
58+ print (f"Done with batch { i + 1 } " )
59+
60+ print ('All batches queried successfully' )
61+
62+ for i in range (0 , int (total_count ) // int (tx_batch_size )):
63+ pubkeys = concatenated_public_keys [i * tx_batch_size * 96 :(i + 1 )* tx_batch_size * 96 ]
64+ signatures = concatenated_signatures [i * tx_batch_size * 192 :(i + 1 )* tx_batch_size * 192 ]
65+
66+ # dirty way to create the transaction json
67+ transaction = '{"version":"1.0","chainId":"1","createdAt":1725982694510,"meta":{"name":"Transactions Batch","description":"","txBuilderVersion":"1.17.0","createdFromSafeAddress":"0xFafCba8F8F4282c4C629A6Bb4b98226A7C3E989f","createdFromOwnerAddress":"","checksum":"0x651d0ee6dc73fb8eb5bc170da82f9147e97267367af72e75cb38a05a27da26b7"},"transactions":[{"to":"' + STAKING_CONTRACT + '","value":"0","data":null,"contractMethod":{"inputs":[{"internalType":"uint256","name":"_operatorIndex","type":"uint256"},{"internalType":"uint256","name":"_keyCount","type":"uint256"},{"internalType":"bytes","name":"_publicKeys","type":"bytes"},{"internalType":"bytes","name":"_signatures","type":"bytes"}],"name":"addValidators","payable":false},"contractInputsValues":{"_operatorIndex":"0","_keyCount":"' + str (tx_batch_size )+ '","_publicKeys":"0x' + pubkeys + '","_signatures":"0x' + signatures + '"}}]}'
68+
69+ # save in file
70+ with open (f'add-validators{ i } .json' , 'w' ) as f :
71+ f .write (transaction )
72+
73+ print (f'Proposal saved in add-validators{ i } .json' )
74+
75+ print ('All proposals saved successfully' )
76+
77+
78+ if __name__ == "__main__" :
79+ """ This is executed when run from the command line """
80+ main ()
0 commit comments