commit 266ba871a4f981f01ccfda89bd9f9865adce2c27 Author: jack Date: Wed Nov 12 16:47:21 2025 +0800 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cf7c11e --- /dev/null +++ b/.gitignore @@ -0,0 +1,65 @@ +.DS_Store +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg +.idea/* +xml_files/ + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*,cover + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +other/split_clash_config/split_config +ai_news/save_data +daily/*.txt diff --git a/demo/query_balance/query_balance_eth.py b/demo/query_balance/query_balance_eth.py new file mode 100644 index 0000000..c24f6e8 --- /dev/null +++ b/demo/query_balance/query_balance_eth.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +from web3 import Web3 +import time + +# 设置 RPC URL +rpc_url = "rpc" + +# 初始化 web3.py 提供器 +w3 = Web3(Web3.HTTPProvider(rpc_url)) + + +# 检查是否连接成功 +def check_connection(): + try: + network_id = w3.eth.chain_id + print(f"已成功连接到链节点,网络ID为: {network_id}。正在查询钱包余额...") + return True + except Exception as e: + print("无法连接到链节点,请检查 URL 是否正确") + return False + + +# 钱包地址列表 +wallet_addresses = [ + 'key' +] + + +def query_balances(): + if not check_connection(): + return + + wallet_num = 1 + for wallet_address in wallet_addresses: + retry_count = 0 + max_retries = 3 + delay = 2 # 延迟时间,单位为秒 + + result_message = "" + result_balance = -1 + + # 转换为校验和地址 + try: + checksum_address = w3.to_checksum_address(wallet_address) + except Exception as e: + print(f"钱包 {wallet_address} 地址格式无效: {str(e)}") + wallet_num += 1 + continue + + while retry_count < max_retries: + try: + # 查询余额 + balance = w3.eth.get_balance(checksum_address) + # 将余额从 Wei 转换为 Ether + balance_eth = w3.from_wei(balance, 'ether') + result_message = f"Wallet address: {checksum_address} {wallet_num}, balance: {balance_eth} Token" + result_balance = balance_eth + print(result_message) + wallet_num += 1 + break + except Exception as e: + print(f"查询钱包 {checksum_address} {wallet_num} 余额时发生错误: {str(e)}") + retry_count += 1 + print(f"正在重试...(第 {retry_count} 次)") + time.sleep(delay) + + if retry_count == max_retries: + result_message = f"钱包 {checksum_address} 查询余额失败,已达到最大重试次数。" + print(result_message) + + +if __name__ == "__main__": + query_balances() diff --git a/demo/query_balance/query_balance_monad.py b/demo/query_balance/query_balance_monad.py new file mode 100644 index 0000000..18ebb4f --- /dev/null +++ b/demo/query_balance/query_balance_monad.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +from web3 import Web3 +import time + +# 设置 RPC URL +rpc_url = "https://testnet-rpc.monad.xyz" + +# 初始化 web3.py 提供器 +w3 = Web3(Web3.HTTPProvider(rpc_url)) + + +# 检查是否连接成功 +def check_connection(): + try: + network_id = w3.eth.chain_id + print(f"已成功连接到链节点,网络ID为: {network_id}。正在查询钱包余额...") + return True + except Exception as e: + print("无法连接到链节点,请检查 URL 是否正确") + return False + + +# 钱包地址列表 +wallet_addresses = [ + '0xe50B77Cd771243b8Ae1d6ce33b4E13ECC5Fa28a6', + '0x9ea2ECAD4090E32916e03b77d7C75CbF6C8E0A55', + '0xE8A4b0C04300154DC9B1D0e565Ba70F996614690', + '0x1b623c5d70c93b437d93c305bf2cfa389095f636', + '0x06D25c3e0E1F753ac0486a3f8aaD7259149656cB', + '0x15cFEE34Ca4541CAc9a1c4B6F6aB47A65877E240', + '0x7aBF0dA8Ac07B6dE7206e467988455E1AD0b60B5', + '0xF736f45d4663a8D8DfF7EFA55b1Cf6Fe38D026c8', + '0x83173eECf3a6d9ABB79682568e16c2eAd361620e', + '0xa401b85B4849Fc7610Bd180cc937859C78528F47', + '0x10A43E7Fe77E2D84adBeC26cF0bFc6f403841266', + '0x70D5EE1DfddD3726f0D71F4CD5a8Ef43aC651a75' +] + + +def query_balances(wallet_num, wallet_address): + retry_count = 0 + max_retries = 3 + delay = 2 # 延迟时间,单位为秒 + + result_message = "" + result_balance = -1 + + # 转换为校验和地址 + try: + checksum_address = w3.to_checksum_address(wallet_address) + except Exception as e: + print(f"钱包 {wallet_address} 地址格式无效: {str(e)}") + return wallet_num + + while retry_count < max_retries: + try: + # 查询余额 + balance = w3.eth.get_balance(checksum_address) + # 将余额从 Wei 转换为 Ether + balance_eth = w3.from_wei(balance, 'ether') + result_message = f"Wallet {wallet_num}: {checksum_address}\nbalance: {balance_eth} Token" + result_balance = balance_eth + print(result_message) + wallet_num += 1 + break + except Exception as e: + print(f"查询钱包 {checksum_address} {wallet_num} 余额时发生错误: {str(e)}") + retry_count += 1 + print(f"正在重试...(第 {retry_count} 次)") + time.sleep(delay) + + if retry_count == max_retries: + result_message = f"钱包 {checksum_address} 查询余额失败,已达到最大重试次数。" + print(result_message) + + return wallet_num + + +def query_nonce(wallet_num, wallet_address): + try: + checksum_address = w3.to_checksum_address(wallet_address) + except Exception as e: + print(f"钱包 {wallet_address} 地址格式无效: {str(e)}") + return + + try: + nonce_latest = w3.eth.get_transaction_count(checksum_address, "latest") + nonce_pending = w3.eth.get_transaction_count(checksum_address, "pending") + print(f'pending nonce: {nonce_pending} ; latest nonce: {nonce_latest}') + except Exception as e: + print(f"查询钱包 {checksum_address} {wallet_num} nonce时发生错误: {str(e)}") + + +def main(): + if not check_connection(): + return + + wallet_num = 1 + for wallet_address in wallet_addresses: + wallet_num = query_balances(wallet_num, wallet_address) + query_nonce(wallet_num - 1, wallet_address) + print('------------') + + +if __name__ == "__main__": + main() diff --git a/demo/query_balance/query_balance_somnia.py b/demo/query_balance/query_balance_somnia.py new file mode 100644 index 0000000..2d831f3 --- /dev/null +++ b/demo/query_balance/query_balance_somnia.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +from web3 import Web3 +import time + +# 设置 RPC URL +rpc_url = "https://dream-rpc.somnia.network" + +# 初始化 web3.py 提供器 +w3 = Web3(Web3.HTTPProvider(rpc_url)) + + +# 检查是否连接成功 +def check_connection(): + try: + network_id = w3.eth.chain_id + print(f"已成功连接到链节点,网络ID为: {network_id}。正在查询钱包余额...") + return True + except Exception as e: + print("无法连接到链节点,请检查 URL 是否正确") + return False + + +# 钱包地址列表 +wallet_addresses = [ + '0xe50B77Cd771243b8Ae1d6ce33b4E13ECC5Fa28a6', + '0x9ea2ECAD4090E32916e03b77d7C75CbF6C8E0A55', + '0xE8A4b0C04300154DC9B1D0e565Ba70F996614690', + '0x1b623c5d70c93b437d93c305bf2cfa389095f636', + '0x06D25c3e0E1F753ac0486a3f8aaD7259149656cB', + '0x15cFEE34Ca4541CAc9a1c4B6F6aB47A65877E240', + '0x7aBF0dA8Ac07B6dE7206e467988455E1AD0b60B5', + '0xF736f45d4663a8D8DfF7EFA55b1Cf6Fe38D026c8', + '0x83173eECf3a6d9ABB79682568e16c2eAd361620e', + '0xa401b85B4849Fc7610Bd180cc937859C78528F47', + '0x10A43E7Fe77E2D84adBeC26cF0bFc6f403841266', + '0x70D5EE1DfddD3726f0D71F4CD5a8Ef43aC651a75' +] + + +def query_balances(wallet_num, wallet_address): + retry_count = 0 + max_retries = 3 + delay = 2 # 延迟时间,单位为秒 + + result_message = "" + result_balance = -1 + + # 转换为校验和地址 + try: + checksum_address = w3.to_checksum_address(wallet_address) + except Exception as e: + print(f"钱包 {wallet_address} 地址格式无效: {str(e)}") + return wallet_num + + while retry_count < max_retries: + try: + # 查询余额 + balance = w3.eth.get_balance(checksum_address) + # 将余额从 Wei 转换为 Ether + balance_eth = w3.from_wei(balance, 'ether') + result_message = f"Wallet {wallet_num}: {checksum_address}\nbalance: {balance_eth} Token" + result_balance = balance_eth + print(result_message) + wallet_num += 1 + break + except Exception as e: + print(f"查询钱包 {checksum_address} {wallet_num} 余额时发生错误: {str(e)}") + retry_count += 1 + print(f"正在重试...(第 {retry_count} 次)") + time.sleep(delay) + + if retry_count == max_retries: + result_message = f"钱包 {checksum_address} 查询余额失败,已达到最大重试次数。" + print(result_message) + + return wallet_num + + +def query_nonce(wallet_num, wallet_address): + try: + checksum_address = w3.to_checksum_address(wallet_address) + except Exception as e: + print(f"钱包 {wallet_address} 地址格式无效: {str(e)}") + return + + try: + nonce_latest = w3.eth.get_transaction_count(checksum_address, "latest") + nonce_pending = w3.eth.get_transaction_count(checksum_address, "pending") + print(f'pending nonce: {nonce_pending} ; latest nonce: {nonce_latest}') + except Exception as e: + print(f"查询钱包 {checksum_address} {wallet_num} nonce时发生错误: {str(e)}") + + +def main(): + if not check_connection(): + return + + wallet_num = 1 + for wallet_address in wallet_addresses: + wallet_num = query_balances(wallet_num, wallet_address) + query_nonce(wallet_num - 1, wallet_address) + print('------------') + + +if __name__ == "__main__": + main() diff --git a/demo/query_balance/query_balance_sui.py b/demo/query_balance/query_balance_sui.py new file mode 100644 index 0000000..89d2a6a --- /dev/null +++ b/demo/query_balance/query_balance_sui.py @@ -0,0 +1,25 @@ +from pysui import SuiConfig, SyncClient +from pysui.sui.sui_types.scalars import SuiString +from pysui.sui.sui_clients.common import SuiRpcResult + +private_key = "suiprivkey1qrtls98pk6frpzzuajf5a53klnhd0hdtx6fwwrk65ghregk5np4j2yehv7y" # 替换为你的私钥 +sui_config = SuiConfig.user_config( + rpc_url="https://fullnode.testnet.sui.io:443", # SUI 测试网节点地址 + prv_keys=[private_key] # 添加私钥 +) + +client = SyncClient(sui_config) + +# 获取当前活跃地址 +address = sui_config.active_address +print(f"Active Address: {address}") + +# 使用 sui_getBalance RPC 方法查询余额 +response: SuiRpcResult = client._client.balance(SuiString(address)) + +if response.is_ok(): + balance_data = response.result_data + total_balance = balance_data.get("totalBalance", 0) + print(f"Balance: {total_balance} MIST") +else: + print(f"Error: {response.error}") diff --git a/project/CheckBalance/checkBalance b/project/CheckBalance/checkBalance new file mode 100755 index 0000000..f03775f Binary files /dev/null and b/project/CheckBalance/checkBalance differ diff --git a/project/CheckBalance/go.mod b/project/CheckBalance/go.mod new file mode 100644 index 0000000..bd2ec6f --- /dev/null +++ b/project/CheckBalance/go.mod @@ -0,0 +1,34 @@ +module gethereum + +go 1.23.0 + +toolchain go1.24.6 + +require ( + github.com/ethereum/go-ethereum v1.16.3 + github.com/therecipe/qt v0.0.0-20200904063919-c0c124a5770d +) + +require ( + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/StackExchange/wmi v1.2.1 // indirect + github.com/bits-and-blooms/bitset v1.20.0 // indirect + github.com/consensys/gnark-crypto v0.18.0 // indirect + github.com/crate-crypto/go-eth-kzg v1.3.0 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/ethereum/c-kzg-4844/v2 v2.1.0 // indirect + github.com/ethereum/go-verkle v0.2.2 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/gopherjs/gopherjs v0.0.0-20190411002643-bd77b112433e // indirect + github.com/gorilla/websocket v1.4.2 // indirect + github.com/holiman/uint256 v1.3.2 // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect + github.com/supranational/blst v0.3.14 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect +) diff --git a/project/CheckBalance/go.sum b/project/CheckBalance/go.sum new file mode 100644 index 0000000..6ea0e95 --- /dev/null +++ b/project/CheckBalance/go.sum @@ -0,0 +1,204 @@ +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= +github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw= +github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/consensys/gnark-crypto v0.18.0 h1:vIye/FqI50VeAr0B3dx+YjeIvmc3LWz4yEfbWBpTUf0= +github.com/consensys/gnark-crypto v0.18.0/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= +github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= +github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg/0E3OOdI= +github.com/crate-crypto/go-eth-kzg v1.3.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= +github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA= +github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A= +github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= +github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= +github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= +github.com/ethereum/go-ethereum v1.16.3 h1:nDoBSrmsrPbrDIVLTkDQCy1U9KdHN+F2PzvMbDoS42Q= +github.com/ethereum/go-ethereum v1.16.3/go.mod h1:Lrsc6bt9Gm9RyvhfFK53vboCia8kpF9nv+2Ukntnl+8= +github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= +github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= +github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= +github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gopherjs/gopherjs v0.0.0-20190411002643-bd77b112433e h1:XWcjeEtTFTOVA9Fs1w7n2XBftk5ib4oZrhzWk0B+3eA= +github.com/gopherjs/gopherjs v0.0.0-20190411002643-bd77b112433e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= +github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0= +github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ= +github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/supranational/blst v0.3.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo= +github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/therecipe/qt v0.0.0-20200904063919-c0c124a5770d h1:T+d8FnaLSvM/1BdlDXhW4d5dr2F07bAbB+LpgzMxx+o= +github.com/therecipe/qt v0.0.0-20200904063919-c0c124a5770d/go.mod h1:SUUR2j3aE1z6/g76SdD6NwACEpvCxb3fvG82eKbD6us= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= +github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190420063019-afa5a82059c6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/project/CheckBalance/keys.txt b/project/CheckBalance/keys.txt new file mode 100644 index 0000000..6bd9693 --- /dev/null +++ b/project/CheckBalance/keys.txt @@ -0,0 +1,12 @@ +f6ba92eb503641312b88ae9cebde70b034fddc4f0ea421d6ff2b4b2a22ab35a9 +2a185eae14ca82ac934a5f952e12e0d4a64043c911c33a19afd48ef1a1d70c46 +df5d009c711475b8f9987f235b373cfdbd93c858063efa9eebd9188dbc534097 +64f548051325022a7aa9e32c5756161d227fd5fb641c3f4623558cb574775254 +aa6fc003745793d7c192b2c404e332770b501ac0b81879d7538d6659ca84b7cf +e92637de4029ae6397c18ff62cab0460e6caee1f166a0e710d52d46556c16627 +1741e24dd3a1a5cecf39dea82ba6ba62506d7a07ebcc7998b9b66eb8423e93db +b898cf63a5ec89105ba755ef3b7533c25ea9130ab50fb0db14779fb6efd4f9c6 +f139f86b139f92070b6e6139177e59d85532c867dda6a8833e479fd60a8d37b7 +399ec8a9a9fcbb3118f993351c7624bdffc9b93d31e6576ebe69e9b24a2ecab3 +3991542110242368f4770716be904b0ca6d44a8dbe4501771833b1a3642198d1 +618a59dcbbc05a38e10b9872f50855c1b52dd01baced785a7134876ba404be1b \ No newline at end of file diff --git a/project/CheckBalance/main.go b/project/CheckBalance/main.go new file mode 100644 index 0000000..00ed11e --- /dev/null +++ b/project/CheckBalance/main.go @@ -0,0 +1,198 @@ +package main + +import ( + "bufio" + "context" + "crypto/ecdsa" + "fmt" + "math/big" + "os" + "strings" + "sync" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/therecipe/qt/core" + "github.com/therecipe/qt/widgets" +) + +const ( + keyFileName = "keys.txt" + nodeURLTxtName = "nodeURL.txt" +) + +type window struct { + *widgets.QMainWindow + chainCB *widgets.QComboBox + outputTE *widgets.QTextEdit +} + +type queryResult struct { + index int + message string +} + +func main() { + app := widgets.NewQApplication(len(os.Args), os.Args) + + // 1.5 倍全局放大 + app.SetStyleSheet(` + * { + font-size: 15pt; + padding: 6px; + } + QPushButton { + min-height: 34px; + } + `) + + win := &window{QMainWindow: widgets.NewQMainWindow(nil, 0)} + win.SetWindowTitle("区块链多链余额查询器") + win.SetMinimumSize2(1050, 750) // 700*1.5 , 500*1.5 + + central := widgets.NewQWidget(nil, 0) + layout := widgets.NewQVBoxLayout2(central) + + // ---- 1. 读取节点列表 ---- + nodeURLs, err := readLinesNoBlank(nodeURLTxtName) + if err != nil { + popupFatal(fmt.Sprintf("读取 %s 失败: %v", nodeURLTxtName, err)) + } + if len(nodeURLs) == 0 { + popupFatal(fmt.Sprintf("%s 为空,请至少填一个节点 URL", nodeURLTxtName)) + } + + // ---- 2. 下拉框 ---- + layout.AddWidget(widgets.NewQLabel2("选择节点:", nil, 0), 0, 0) + win.chainCB = widgets.NewQComboBox(nil) + for _, u := range nodeURLs { + win.chainCB.AddItem(u, core.NewQVariant1(u)) + } + layout.AddWidget(win.chainCB, 0, 0) + + // ---- 3. 按钮区域 ---- + btnLayout := widgets.NewQHBoxLayout() + queryBtn := widgets.NewQPushButton2("查询余额", nil) + queryBtn.ConnectClicked(func(bool) { win.query() }) + btnLayout.AddWidget(queryBtn, 0, 0) + + clearBtn := widgets.NewQPushButton2("清除输出", nil) + clearBtn.ConnectClicked(func(bool) { win.outputTE.Clear() }) + btnLayout.AddWidget(clearBtn, 0, 0) + + layout.AddLayout(btnLayout, 0) + + // ---- 4. 输出框 ---- + win.outputTE = widgets.NewQTextEdit(nil) + win.outputTE.SetReadOnly(true) + layout.AddWidget(win.outputTE, 0, 0) + + win.SetCentralWidget(central) + win.Show() + widgets.QApplication_Exec() +} + +// ============ 查询逻辑 ============ +func (w *window) query() { + w.outputTE.Clear() + + // 当前选中节点 + idx := w.chainCB.CurrentIndex() + if idx < 0 { + w.log("未选择节点") + return + } + nodeURL := w.chainCB.CurrentText() + w.log("当前节点: %s", nodeURL) + + // 读取 keys + keys, err := readLinesNoBlank(keyFileName) + if err != nil { + w.log("读取 %s 失败: %v", keyFileName, err) + return + } + if len(keys) == 0 { + w.log("%s 为空,请先填入私钥(每行一个)", keyFileName) + return + } + + // 连接 + client, err := ethclient.Dial(nodeURL) + if err != nil { + w.log("连接节点失败: %v", err) + return + } + defer client.Close() + + var wg sync.WaitGroup + results := make([]string, len(keys)) + for i, hexKey := range keys { + wg.Add(1) + go func(i int, hexKey string) { + defer wg.Done() + + privateKey, err := crypto.HexToECDSA(hexKey) + if err != nil { + results[i] = fmt.Sprintf("钱包 %d: 私钥解析失败,跳过。err=%v", i+1, err) + return + } + publicKey, ok := privateKey.Public().(*ecdsa.PublicKey) + if !ok { + results[i] = fmt.Sprintf("钱包 %d: 公钥转换失败,跳过", i+1) + return + } + addr := crypto.PubkeyToAddress(*publicKey) + + balance, err := client.BalanceAt(context.Background(), addr, nil) + if err != nil { + results[i] = fmt.Sprintf("钱包 %d (%s): 查余额失败,err=%v", i+1, addr.Hex(), err) + return + } + nonce, err := client.PendingNonceAt(context.Background(), addr) + if err != nil { + results[i] = fmt.Sprintf("钱包 %d (%s): 查 nonce 失败,err=%v", i+1, addr.Hex(), err) + return + } + + ether := new(big.Float).Quo(new(big.Float).SetInt(balance), big.NewFloat(1e18)) + results[i] = fmt.Sprintf("钱包 %d %s \n余额(wei): %s\n余额Token %.6f\nNonce: %d", + i+1, addr.Hex(), balance.String(), ether, nonce) + }(i, hexKey) + } + + wg.Wait() + + // 全部结束后按顺序输出 + for _, res := range results { + w.log(res) + } +} + +// ============ 工具函数 ============ +func readLinesNoBlank(filename string) ([]string, error) { + f, err := os.Open(filename) + if err != nil { + return nil, err + } + defer f.Close() + + var out []string + sc := bufio.NewScanner(f) + for sc.Scan() { + line := strings.TrimSpace(sc.Text()) + if line != "" { + out = append(out, line) + } + } + return out, sc.Err() +} + +func (w *window) log(format string, a ...interface{}) { + s := fmt.Sprintf(format, a...) + w.outputTE.Append(s + "\n") +} + +func popupFatal(msg string) { + widgets.QMessageBox_Critical(nil, "错误", msg, widgets.QMessageBox__Ok, widgets.QMessageBox__Ok) + os.Exit(1) +} diff --git a/project/CheckBalance/nodeURL.txt b/project/CheckBalance/nodeURL.txt new file mode 100644 index 0000000..06eccc5 --- /dev/null +++ b/project/CheckBalance/nodeURL.txt @@ -0,0 +1,2 @@ +https://testnet-rpc.monad.xyz +https://testnet.dplabs-internal.com \ No newline at end of file diff --git a/project/CheckBalance/qtbox b/project/CheckBalance/qtbox new file mode 100755 index 0000000..d58eea3 Binary files /dev/null and b/project/CheckBalance/qtbox differ diff --git a/project/monad/AccountList.txt b/project/monad/AccountList.txt new file mode 100644 index 0000000..0f36e14 --- /dev/null +++ b/project/monad/AccountList.txt @@ -0,0 +1 @@ +0x618a59dcbbc05a38e10b9872f50855c1b52dd01baced785a7134876ba404be1b \ No newline at end of file diff --git a/project/monad/Contract.mjs b/project/monad/Contract.mjs new file mode 100644 index 0000000..e69de29 diff --git a/project/monad/SendToken.mjs b/project/monad/SendToken.mjs new file mode 100644 index 0000000..e69de29 diff --git a/project/monad/SignIn.mjs b/project/monad/SignIn.mjs new file mode 100644 index 0000000..b40bd42 --- /dev/null +++ b/project/monad/SignIn.mjs @@ -0,0 +1,56 @@ +import { ethers } from 'ethers'; + +const providerUrl = 'https://testnet-rpc.monad.xyz'; +const provider = new ethers.JsonRpcProvider(providerUrl); +const privateKeyList = [ + '0x3991542110242368f4770716be904b0ca6d44a8dbe4501771833b1a3642198d1' +]; +const stakingContractAddress = '0xcBE623D259261FFa0CFAff44484bFF46c1b7D6c2'; + +// Function to generate random delay between 5-10 seconds +const getRandomDelay = () => { + return Math.floor(Math.random() * (10000 - 5000 + 1)) + 5000; +}; + +// Function to handle staking for a single wallet +async function stakeMon(wallet) { + try { + const balance = await provider.getBalance(wallet.address); + console.log(`Wallet ${wallet.address} balance:`, ethers.formatEther(balance)); + // 签到合约, 金额设置 0 + const amountToStake = ethers.parseEther('0'); + if (balance < amountToStake) { + throw new Error(`Insufficient balance for staking in wallet ${wallet.address}`); + } + + const tx = await wallet.sendTransaction({ + to: stakingContractAddress, + value: amountToStake, + data: '0x7ab71841', + gasLimit: 1000000, + gasPrice: ethers.parseUnits('52', 'gwei') + }); + console.log(`Stake transaction hash for ${wallet.address}:`, tx.hash); + const receipt = await tx.wait(); + console.log(`Stake transaction receipt for ${wallet.address}:`, receipt); + } catch (error) { + console.error(`Error staking $MON for ${wallet.address}:`, error); + } +} + +// Function to process all wallets with delay +async function processAllWallets() { + for (const privateKey of privateKeyList) { + const wallet = new ethers.Wallet(privateKey, provider); + await stakeMon(wallet); + + // Add random delay between 5-10 seconds, except for the last wallet + if (privateKey !== privateKeyList[privateKeyList.length - 1]) { + const delay = getRandomDelay(); + console.log(`Waiting ${delay/1000} seconds before next wallet...`); + await new Promise(resolve => setTimeout(resolve, delay)); + } + } +} + +processAllWallets(); diff --git a/project/monad/Swap.mjs b/project/monad/Swap.mjs new file mode 100644 index 0000000..e555854 --- /dev/null +++ b/project/monad/Swap.mjs @@ -0,0 +1,148 @@ +import {ethers} from "ethers"; +import fs from 'fs/promises'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +// Monad 测试网 RPC URL +const providerUrl = "https://testnet-rpc.monad.xyz"; +const provider = new ethers.JsonRpcProvider(providerUrl); + +// 合约地址、合约方法哈希值及描述 +const contractData = [ + { + address: "0x2c9c959516e9aaedb2c748224a41249202ca8be7", + dataHash: "0xd5575982", + description: "Magmastaking" + }, + { + address: "0x760AfE86e5de5fa0Ee542fc7B7B713e1c5425701", + dataHash: "0xd5575982", + description: "ApeBond" + }, + { + address: "0x760AfE86e5de5fa0Ee542fc7B7B713e1c5425701", + dataHash: "0xd0e30db0", + description: "OctoSwap - WMON" + } +]; + +// 读取私钥文件 +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const filePath = path.join(__dirname, './AccountList.txt'); + +function sleep(min_delay, max_delay) { + // 随机睡眠 + const delay = Math.floor(Math.random() * (max_delay * 1000 - min_delay * 1000 + 1)) + min_delay * 1000; + return new Promise((resolve) => setTimeout(resolve, delay)); +} + +function getRandomAmount() { + // 生成随机交易金额 0.00000000****(最后4位随机数) + const randomTail = Math.floor(1000 + Math.random() * 2000); // 生成1000-9999的随机4位数 + return ethers.parseEther(`0.00000000${randomTail}`); +} + +function getRandomContractData() { + // 随机获取合约地址、合约方法哈希值及描述 + if (contractData.length === 0) { + console.error("The contract data array is empty, the contract cannot be selected, and the program exits."); + process.exit(1); + } + const randomIndex = Math.floor(Math.random() * contractData.length); + return contractData[randomIndex]; +} + +function checkWalletBalance(balance) { + if (balance <= ethers.parseEther("5")) { + console.error("The wallet balance is invalid."); + process.exit(1); + } +} + +async function executeContract(wallet) { + try { + // 随机选择一个合约地址、合约方法哈希值及描述 + const {address, dataHash, description} = getRandomContractData(); + console.log(`Selected contract: ${description}`); + console.log("Selected contract address:", address); + console.log("Selected contract dataHash:", dataHash); + + // 检查原生代币余额 + const balance = await provider.getBalance(wallet.address); + const beforeBalance = ethers.formatEther(balance); + console.log("Native balance:", beforeBalance); + + // 检查钱包余额,不能小于 0.2 + checkWalletBalance(balance); + + // 质押金额 + const amountToStake = getRandomAmount(); + console.log("Amount to contract:", ethers.formatEther(amountToStake)); + if (balance < amountToStake) { + throw new Error("Insufficient balance for contract execution."); + } + + // 低级调用,发送交易 + const tx = await wallet.sendTransaction({ + to: address, + value: amountToStake, + data: dataHash, + gasLimit: 100000, + gasPrice: ethers.parseUnits("50", "gwei") + }); + console.log("Contract Execution hash:", tx.hash); + + // 等待交易确认 + const receipt = await tx.wait(); + console.log("Contract Execution status:", "ok"); + + // 检查交易后的余额 + const balanceStaking = await provider.getBalance(wallet.address); + const afterBalance = ethers.formatEther(balanceStaking); + console.log("Native balance after transaction:", afterBalance); + console.log("The cost of this transaction:", parseFloat(beforeBalance) - parseFloat(afterBalance)); + } catch (error) { + console.error("Error executing contract:", error); + } +} + +async function runMultipleStaking(privateKeys) { + const last_times = 1000; + const min_delay = 10; + const max_delay = 20; + + for (const privateKey of privateKeys) { + const wallet = new ethers.Wallet(privateKey, provider); + console.log(`Processing wallet with address: ${wallet.address}`); + + for (let i = 0; i < last_times; i++) { + if (last_times > 1) { + console.log(`Starting Contract attempt ${i + 1}`); + } + await executeContract(wallet); + console.log(`Completed Contract attempt ${i + 1}`); + if (i < last_times - 1) { + // 最后一次循环不等待 + const delay = Math.floor(Math.random() * (max_delay * 1000 - min_delay * 1000 + 1)) + min_delay * 1000; + console.log(`Waiting for ${delay / 1000} seconds...`); + console.log('------------------------------------------------------------') + await sleep(min_delay, max_delay); + } + } + } +} + +async function main() { + + try { + const data = await fs.readFile(filePath, 'utf8'); + const privateKeys = data.split('\n').filter(line => line.trim() !== ''); + await runMultipleStaking(privateKeys); + } catch (err) { + console.error('读取文件时发生错误:', err); + process.exit(1); + } +} + +main(); \ No newline at end of file diff --git a/project/monad/nonce.mjs b/project/monad/nonce.mjs new file mode 100644 index 0000000..75d7bbb --- /dev/null +++ b/project/monad/nonce.mjs @@ -0,0 +1,47 @@ +import {ethers} from "ethers"; +import fs from 'fs/promises'; +import path from 'path'; +import {fileURLToPath} from 'url'; + +// 使用 ethers.js 的 Provider +const rpcUrl = 'https://testnet-rpc.monad.xyz'; +const provider = new ethers.JsonRpcProvider(rpcUrl); + +// 读取私钥文件 +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const filePath = path.join(__dirname, './AccountList.txt'); + +async function getNonces(privateKeys) { + let countNum = 1; + for (const privateKey of privateKeys) { + try { + const wallet = new ethers.Wallet(privateKey, provider); + + //获取最新的 nonce + const nonceLatest = await provider.getTransactionCount(wallet, 'latest'); + const noncePending = await provider.getTransactionCount(wallet, 'pending'); + const countNumStr = String(countNum).padStart(2, '0'); + console.log(`${countNumStr} address: ${wallet.address}`); + console.log(`pending nonce: ${noncePending} ; latest nonce: ${nonceLatest}`); + console.log('-----------------------------'); + countNum++; + } catch (error) { + console.error('获取 nonce 时发生错误:', error.message); + } + } +} + +async function main() { + + try { + const data = await fs.readFile(filePath, 'utf8'); + const privateKeys = data.split('\n').filter(line => line.trim() !== ''); + await getNonces(privateKeys); + } catch (err) { + console.error('读取文件时发生错误:', err); + process.exit(1); + } +} + +main(); diff --git a/project/pharos/AccountList.txt b/project/pharos/AccountList.txt new file mode 100644 index 0000000..ed8b517 --- /dev/null +++ b/project/pharos/AccountList.txt @@ -0,0 +1 @@ +0x4b833cf91c19c4d9434ffed4b18714ef032d2acf44caec110a1c2c7db151eb65 \ No newline at end of file diff --git a/project/pharos/Contract.mjs b/project/pharos/Contract.mjs new file mode 100644 index 0000000..1bf8c96 --- /dev/null +++ b/project/pharos/Contract.mjs @@ -0,0 +1,83 @@ +import {ethers} from "ethers"; + +// 配置 provider,明确指定 chainId 并禁用 ENS +const provider = new ethers.JsonRpcProvider("https://testnet.dplabs-internal.com"); + +const privateKey = "0x4b833cf91c19c4d9434ffed4b18714ef032d2acf44caec110a1c2c7db151eb65"; +const wallet = new ethers.Wallet(privateKey, provider); + +const contractAddress = "0x76aaada469d23216be5f7c596fa25f282ff9b364"; + +const contractABI = [ + "function deposit() public" +]; + +async function validateSetup() { + try { + // 验证钱包地址 + if (!ethers.isAddress(wallet.address)) { + throw new Error("Invalid wallet address derived from private key"); + } + console.log("Wallet address:", wallet.address); + + // 检查账户余额 + const balance = await provider.getBalance(wallet.address); + console.log("Wallet balance:", ethers.formatEther(balance), "PHRS"); + if (balance === 0n) { + throw new Error("Wallet has no balance to pay for gas"); + } + + // 验证合约地址 + if (!ethers.isAddress(contractAddress)) { + throw new Error("Invalid contract address"); + } + + // 检查合约是否部署 + const code = await provider.getCode(contractAddress); + if (code === "0x") { + throw new Error("No contract deployed at the specified address"); + } + console.log("Contract is deployed at:", contractAddress); + + // 检查网络连接 + const network = await provider.getNetwork(); + console.log("Connected to network:", network); + } catch (error) { + console.error("Validation failed:", error.message); + process.exit(1); + } +} + +// 发送交易 +async function deposit() { + try { + // 验证设置 + await validateSetup(); + + // 初始化合约 + const contract = new ethers.Contract(contractAddress, contractABI, wallet); + + // 获取交易参数 + const nonce = await provider.getTransactionCount(wallet.address, "pending"); + const gasPrice = (await provider.getFeeData()).gasPrice; + + // 发送交易 + const tx = await contract.deposit({ + nonce, + gasPrice, + gasLimit: 100000 // 根据合约需求调整 + }); + + console.log("Transaction sent:", tx.hash); + + // 等待交易确认 + const receipt = await tx.wait(); + console.log("Transaction confirmed in block:", receipt.blockNumber); + } catch (error) { + console.error("Error sending transaction:", error); + process.exit(1); + } +} + +// 执行 deposit 函数 +deposit(); diff --git a/project/pharos/balanceAndNonce.mjs b/project/pharos/balanceAndNonce.mjs new file mode 100644 index 0000000..8b2d74c --- /dev/null +++ b/project/pharos/balanceAndNonce.mjs @@ -0,0 +1,65 @@ +import {ethers} from "ethers"; +import fs from 'fs/promises'; +import path from 'path'; +import {fileURLToPath} from 'url'; + +// 使用 ethers.js 的 Provider +const rpcUrl = 'https://testnet.dplabs-internal.com'; +const provider = new ethers.JsonRpcProvider(rpcUrl); + +// 读取私钥文件 +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const filePath = path.join(__dirname, './AccountList.txt'); + +async function getBalance(privateKey) { + try { + const wallet = new ethers.Wallet(privateKey, provider); + + // 获取账户余额 + const balance = await provider.getBalance(wallet.address); + + // 将余额从 wei 转换为 ether + const balanceInEther = ethers.formatEther(balance); + + console.log(`Address: ${wallet.address}`); + console.log(`Balance: ${balanceInEther} PHRS`); + } catch (error) { + console.error(`Error getting balance for private key: ${privateKey}`); + console.error(error); + } +} + +async function getNonces(privateKey, countNum) { + try { + const wallet = new ethers.Wallet(privateKey, provider); + + // 获取最新的 nonce + const nonceLatest = await provider.getTransactionCount(wallet.address, 'latest'); + const noncePending = await provider.getTransactionCount(wallet.address, 'pending'); + console.log(`pending nonce: ${noncePending} ; latest nonce: ${nonceLatest}`); + } catch (error) { + console.error('获取 nonce 时发生错误:', error.message); + } +} + +async function main() { + let privateKeys; + try { + const data = await fs.readFile(filePath, 'utf8'); + privateKeys = data.split('\n').filter(line => line.trim() !== ''); + } catch (err) { + console.error('读取文件时发生错误:', err); + process.exit(1); + } + + let countNum = 1; + for (const privateKey of privateKeys) { + await getBalance(privateKey); + await getNonces(privateKey); + console.log('-----------------------------'); + countNum++; + } +} + +main(); diff --git a/reference/demo/balance_query/query_balance_eth.mjs b/reference/demo/balance_query/query_balance_eth.mjs new file mode 100644 index 0000000..c0dc6f9 --- /dev/null +++ b/reference/demo/balance_query/query_balance_eth.mjs @@ -0,0 +1,76 @@ +import { ethers } from "ethers"; + +// 设置 RPC URL +const rpcUrl = ''; + +// 初始化 ethers.js 提供器 +const provider = new ethers.JsonRpcProvider(rpcUrl); + +// 检查是否连接成功 +async function checkConnection() { + try { + const network = await provider.getNetwork(); + console.log(`已成功连接到链节点,网络ID为: ${network.chainId}。正在查询钱包余额...`); + return true; + } catch (error) { + console.log("无法连接到链节点,请检查 URL 是否正确"); + return false; + } +} + +// 替换为实际的钱包地址列表 +const walletAddresses = [ + '0xe50B77Cd771243b8Ae1d6ce33b4E13ECC5Fa28a6', + '0x9ea2ECAD4090E32916e03b77d7C75CbF6C8E0A55', + '0xE8A4b0C04300154DC9B1D0e565Ba70F996614690', + '0x1b623c5d70c93b437d93c305bf2cfa389095f636', + '0x06D25c3e0E1F753ac0486a3f8aaD7259149656cB', + '0x15cFEE34Ca4541CAc9a1c4B6F6aB47A65877E240', + '0x7aBF0dA8Ac07B6dE7206e467988455E1AD0b60B5', + '0xF736f45d4663a8D8DfF7EFA55b1Cf6Fe38D026c8', + '0x83173eECf3a6d9ABB79682568e16c2eAd361620e', + '0xa401b85B4849Fc7610Bd180cc937859C78528F47' +]; + +async function queryBalances() { + const isConnected = await checkConnection(); + if (!isConnected) { + return; + } + + let walletNum = 1; + for (const walletAddress of walletAddresses) { + let retryCount = 0; + const maxRetries = 3; + const delay = 2000; // 延迟时间,单位为毫秒 + + let resultMessage = ""; + let resultBalance = -1; + + while (retryCount < maxRetries) { + try { + // 查询余额 + const balance = await provider.getBalance(walletAddress); + // 将余额从 Wei 转换为 Ether + const balanceEth = ethers.formatUnits(balance, 18); + resultMessage = `Wallet address: ${walletAddress} ${walletNum}, balance: ${balanceEth} Token`; + resultBalance = balanceEth; + console.log(resultMessage); + walletNum += 1; + break; + } catch (e) { + console.log(`查询钱包 ${walletAddress} ${walletNum} 余额时发生错误: ${e.message}`); + retryCount += 1; + console.log(`正在重试...(第 ${retryCount} 次)`); + await new Promise((resolve) => setTimeout(resolve, delay)); + } + } + + if (retryCount === maxRetries) { + resultMessage = `钱包 ${walletAddress} 查询余额失败,已达到最大重试次数。`; + console.log(resultMessage); + } + } +} + +queryBalances(); \ No newline at end of file diff --git a/reference/demo/balance_query/query_balance_monad.mjs b/reference/demo/balance_query/query_balance_monad.mjs new file mode 100644 index 0000000..194ba0e --- /dev/null +++ b/reference/demo/balance_query/query_balance_monad.mjs @@ -0,0 +1,78 @@ +import { ethers } from "ethers"; + +// 设置 RPC URL +const rpcUrl = "https://testnet-rpc.monad.xyz"; + +// 初始化 ethers.js 提供器 +const provider = new ethers.JsonRpcProvider(rpcUrl); + +// 检查是否连接成功 +async function checkConnection() { + try { + const network = await provider.getNetwork(); + console.log(`已成功连接到链节点,网络ID为: ${network.chainId}。正在查询钱包余额...`); + return true; + } catch (error) { + console.log("无法连接到链节点,请检查 URL 是否正确"); + return false; + } +} + +// 替换为实际的钱包地址列表 +const walletAddresses = [ + '0xe50B77Cd771243b8Ae1d6ce33b4E13ECC5Fa28a6', + '0x9ea2ECAD4090E32916e03b77d7C75CbF6C8E0A55', + '0xE8A4b0C04300154DC9B1D0e565Ba70F996614690', + '0x1b623c5d70c93b437d93c305bf2cfa389095f636', + '0x06D25c3e0E1F753ac0486a3f8aaD7259149656cB', + '0x15cFEE34Ca4541CAc9a1c4B6F6aB47A65877E240', + '0x7aBF0dA8Ac07B6dE7206e467988455E1AD0b60B5', + '0xF736f45d4663a8D8DfF7EFA55b1Cf6Fe38D026c8', + '0x83173eECf3a6d9ABB79682568e16c2eAd361620e', + '0xa401b85B4849Fc7610Bd180cc937859C78528F47', + '0x10A43E7Fe77E2D84adBeC26cF0bFc6f403841266', + '0x70D5EE1DfddD3726f0D71F4CD5a8ef43aC651a75' +]; + +async function queryBalances() { + const isConnected = await checkConnection(); + if (!isConnected) { + return; + } + + let walletNum = 1; + for (const walletAddress of walletAddresses) { + let retryCount = 0; + const maxRetries = 3; + const delay = 2000; // 延迟时间,单位为毫秒 + + let resultMessage = ""; + let resultBalance = -1; + + while (retryCount < maxRetries) { + try { + // 查询余额 + const balance = await provider.getBalance(walletAddress); + // 将余额从 Wei 转换为 Ether + const balanceEth = ethers.formatUnits(balance, 18); + resultMessage = `Wallet address: ${walletAddress} ${walletNum}, balance: ${balanceEth} Token`; + resultBalance = balanceEth; + console.log(resultMessage); + walletNum += 1; + break; + } catch (e) { + console.log(`查询钱包 ${walletAddress} ${walletNum} 余额时发生错误: ${e.message}`); + retryCount += 1; + console.log(`正在重试...(第 ${retryCount} 次)`); + await new Promise((resolve) => setTimeout(resolve, delay)); + } + } + + if (retryCount === maxRetries) { + resultMessage = `钱包 ${walletAddress} 查询余额失败,已达到最大重试次数。`; + console.log(resultMessage); + } + } +} + +queryBalances(); \ No newline at end of file diff --git a/reference/demo/balance_query/query_balance_somnia.mjs b/reference/demo/balance_query/query_balance_somnia.mjs new file mode 100644 index 0000000..6caa6e4 --- /dev/null +++ b/reference/demo/balance_query/query_balance_somnia.mjs @@ -0,0 +1,75 @@ +import { ethers } from "ethers"; + +// 设置 RPC URL +const rpcUrl = 'https://dream-rpc.somnia.network'; + +// 初始化 ethers.js 提供器 +const provider = new ethers.JsonRpcProvider(rpcUrl); + +// 检查是否连接成功 +async function checkConnection() { + try { + const network = await provider.getNetwork(); + console.log(`已成功连接到链节点,网络ID为: ${network.chainId}。正在查询钱包余额...`); + return true; + } catch (error) { + console.log("无法连接到链节点,请检查 URL 是否正确"); + return false; + } +} + +// 替换为实际的钱包地址列表 +const walletAddresses = [ + '0xe50B77Cd771243b8Ae1d6ce33b4E13ECC5Fa28a6', + '0x9ea2ECAD4090E32916e03b77d7C75CbF6C8E0A55', + '0xE8A4b0C04300154DC9B1D0e565Ba70F996614690', + '0x1b623c5d70c93b437d93c305bf2cfa389095f636', + '0x06D25c3e0E1F753ac0486a3f8aaD7259149656cB', + '0x15cFEE34Ca4541CAc9a1c4B6F6aB47A65877E240', + '0x7aBF0dA8Ac07B6dE7206e467988455E1AD0b60B5', + '0xF736f45d4663a8D8DfF7EFA55b1Cf6Fe38D026c8', + '0x83173eECf3a6d9ABB79682568e16c2eAd361620e', + '0xa401b85B4849Fc7610Bd180cc937859C78528F47' +]; + +async function queryBalances() { + const isConnected = await checkConnection(); + if (!isConnected) { + return; + } + + let walletNum = 1; + for (const walletAddress of walletAddresses) { + let retryCount = 0; + const maxRetries = 3; + const delay = 2000; // 延迟时间,单位为毫秒 + + let resultMessage = ""; + let resultBalance = -1; + + while (retryCount < maxRetries) { + try { + // 查询余额 + const balance = await provider.getBalance(walletAddress); + const balanceEth = ethers.formatUnits(balance, 18); + resultMessage = `Wallet address: ${walletAddress} ${walletNum}, balance: ${balanceEth} Token`; + resultBalance = balanceEth; + console.log(resultMessage); + walletNum += 1; + break; + } catch (e) { + console.log(`查询钱包 ${walletAddress} ${walletNum} 余额时发生错误: ${e.message}`); + retryCount += 1; + console.log(`正在重试...(第 ${retryCount} 次)`); + await new Promise((resolve) => setTimeout(resolve, delay)); + } + } + + if (retryCount === maxRetries) { + resultMessage = `钱包 ${walletAddress} 查询余额失败,已达到最大重试次数。`; + console.log(resultMessage); + } + } +} + +queryBalances(); \ No newline at end of file diff --git a/reference/demo/balance_query/query_balance_sui.mjs b/reference/demo/balance_query/query_balance_sui.mjs new file mode 100644 index 0000000..437a6ea --- /dev/null +++ b/reference/demo/balance_query/query_balance_sui.mjs @@ -0,0 +1,29 @@ +import { SuiClient } from '@mysten/sui.js/client'; + +async function getBalances(addresses) { + const client = new SuiClient({ url: 'https://fullnode.mainnet.sui.io:443' }); + + let n = 1; + + for (const address of addresses) { + const balance = await client.getCoins({ owner: address }); + + if (balance.data.length > 0) { + const suiBalance = balance.data[0].balance; + const balanceInSUI = suiBalance / 1e9; // 将 MIST 转换为 SUI + console.log(`Address${n}: ${address}, Balance in SUI: ${balanceInSUI}`); + } else { + console.log(`Address${n}: ${address}, No SUI balance found.`); + } + n++; + } +} + +// 替换为你的SUI钱包地址数组 +const addresses = [ + '0x32ec84aca7c2e7be65ea1a72dad58ae7d8a1ac3b5d64a84118e4aafca44b6d1a', + '0x1b9f4bd38af84e4a05d97a3609512d6aa3da2ad1792a24c30b9acddec3993fd5', + '0xd3f63fadfffd4f0230712b6e66af903cba6937a8e751d6b1306158eaa91fdd18' +]; + +getBalances(addresses); \ No newline at end of file diff --git a/reference/demo/contract_interaction/contract_monad.mjs b/reference/demo/contract_interaction/contract_monad.mjs new file mode 100644 index 0000000..b3fe7ed --- /dev/null +++ b/reference/demo/contract_interaction/contract_monad.mjs @@ -0,0 +1,46 @@ +import { ethers } from 'ethers'; + +// Monad 测试网 RPC URL +const providerUrl = 'https://testnet-rpc.monad.xyz'; +const provider = new ethers.JsonRpcProvider(providerUrl); + +// 钱包私钥 +const privateKey = '0x3991542110242368f4770716be904b0ca6d44a8dbe4501771833b1a3642198d1'; +const wallet = new ethers.Wallet(privateKey, provider); + +// 质押合约地址 +const stakingContractAddress = '0x2c9c959516e9aaedb2c748224a41249202ca8be7'; + +// 质押 $MON +async function stakeMon() { + try { + // 检查原生代币余额 + const balance = await provider.getBalance(wallet.address); + console.log('Native balance:', ethers.formatEther(balance)); + + // 质押金额 + const amountToStake = ethers.parseEther('0.0001'); // 0.0001 原生代币 + if (balance < amountToStake) { + throw new Error('Insufficient balance for staking'); + } + + // 低级调用,发送交易 + const tx = await wallet.sendTransaction({ + to: stakingContractAddress, + value: amountToStake, + data: '0xd5575982', // 函数选择器 + gasLimit: 100000, + gasPrice: ethers.parseUnits('50', 'gwei') + }); + console.log('Stake transaction hash:', tx.hash); + + // 等待交易确认 + const receipt = await tx.wait(); + console.log('Stake transaction receipt:', receipt); + } catch (error) { + console.error('Error staking $MON:', error); + } +} + +// 调用质押函数 +stakeMon(); diff --git a/reference/demo/get_nonce/nonce_monad.mjs b/reference/demo/get_nonce/nonce_monad.mjs new file mode 100644 index 0000000..c6eae27 --- /dev/null +++ b/reference/demo/get_nonce/nonce_monad.mjs @@ -0,0 +1,38 @@ +import { ethers } from 'ethers'; + +// 使用 ethers.js 的 Provider +const rpcUrl = 'https://testnet-rpc.monad.xyz'; +const provider = new ethers.JsonRpcProvider(rpcUrl); + +const addresses = [ + '0xe50B77Cd771243b8Ae1d6ce33b4E13ECC5Fa28a6', + '0x9ea2ECAD4090E32916e03b77d7C75CbF6C8E0A55', + '0xE8A4b0C04300154DC9B1D0e565Ba70F996614690', + '0x1b623c5d70c93b437d93c305bf2cfa389095f636', + '0x06D25c3e0E1F753ac0486a3f8aaD7259149656cB', + '0x15cFEE34Ca4541CAc9a1c4B6F6aB47A65877E240', + '0x7aBF0dA8Ac07B6dE7206e467988455E1AD0b60B5', + '0xF736f45d4663a8D8DfF7EFA55b1Cf6Fe38D026c8', + '0x83173eECf3a6d9ABB79682568e16c2eAd361620e', + '0xa401b85B4849Fc7610Bd180cc937859C78528F47' +]; + +async function getNonces() { + try { + let countNum = 1; + for (const address of addresses) { + // 获取最新的 nonce + const nonceLatest = await provider.getTransactionCount(address, 'latest'); + const noncePending = await provider.getTransactionCount(address, 'pending'); + const countNumStr = String(countNum).padStart(2, '0'); + console.log(`${countNumStr} address: ${address}`); + console.log(`pending nonce: ${noncePending} ; latest nonce: ${nonceLatest}`); + console.log('-----------------------------'); + countNum++; + } + } catch (error) { + console.error('获取 nonce 时发生错误:', error.message); + } +} + +getNonces(); diff --git a/reference/demo/get_nonce/nonce_somnia.mjs b/reference/demo/get_nonce/nonce_somnia.mjs new file mode 100644 index 0000000..c27fb82 --- /dev/null +++ b/reference/demo/get_nonce/nonce_somnia.mjs @@ -0,0 +1,37 @@ +import { ethers } from 'ethers'; + +const rpcUrl = 'https://dream-rpc.somnia.network'; +const provider = new ethers.JsonRpcProvider(rpcUrl); + +const addresses = [ + '0xe50B77Cd771243b8Ae1d6ce33b4E13ECC5Fa28a6', + '0x9ea2ECAD4090E32916e03b77d7C75CbF6C8E0A55', + '0xE8A4b0C04300154DC9B1D0e565Ba70F996614690', + '0x1b623c5d70c93b437d93c305bf2cfa389095f636', + '0x06D25c3e0E1F753ac0486a3f8aaD7259149656cB', + '0x15cFEE34Ca4541CAc9a1c4B6F6aB47A65877E240', + '0x7aBF0dA8Ac07B6dE7206e467988455E1AD0b60B5', + '0xF736f45d4663a8D8DfF7EFA55b1Cf6Fe38D026c8', + '0x83173eECf3a6d9ABB79682568e16c2eAd361620e', + '0xa401b85B4849Fc7610Bd180cc937859C78528F47' +]; + +async function getNonces() { + try { + let countNum = 1; + for (const address of addresses) { + // 获取最新的 nonce + const nonceLatest = await provider.getTransactionCount(address, 'latest'); + const noncePending = await provider.getTransactionCount(address, 'pending'); + const countNumStr = String(countNum).padStart(2, '0'); + console.log(`${countNumStr} address: ${address}`); + console.log(`pending nonce: ${noncePending} ; latest nonce: ${nonceLatest}`); + console.log('-----------------------------'); + countNum++; + } + } catch (error) { + console.error('获取 nonce 时发生错误:', error.message); + } +} + +getNonces(); diff --git a/reference/demo/send_token/send_monad.mjs b/reference/demo/send_token/send_monad.mjs new file mode 100644 index 0000000..2e985b6 --- /dev/null +++ b/reference/demo/send_token/send_monad.mjs @@ -0,0 +1,38 @@ +import { ethers } from 'ethers'; + +// 替换为您的节点URL +const providerUrl = 'https://testnet-rpc.monad.xyz'; +const provider = new ethers.JsonRpcProvider(providerUrl); + +// 替换为您的钱包私钥(发送方钱包) +const privateKey = '0x3991542110242368f4770716be904b0ca6d44a8dbe4501771833b1a3642198d1'; // 私钥 +const wallet = new ethers.Wallet(privateKey, provider); + +// 接收方钱包地址 +const recipientAddress = '0x70D5EE1DfddD3726f0D71F4CD5a8ef43aC651a75'; + +// 发送代币的函数 +async function sendToken() { + try { + const amountToSend = ethers.parseEther('0.0000000000001'); // 发送数量 + + // 构造交易对象 + const tx = { + to: recipientAddress, + value: amountToSend + }; + + // 发送交易 + const txResponse = await wallet.sendTransaction(tx); + console.log('Transaction hash:', txResponse.hash); + + // 等待交易确认 + const receipt = await txResponse.wait(); + console.log('Transaction receipt:', receipt); + } catch (error) { + console.error('Error sending Token:', error); + } +} + +// 调用发送Token的函数 +sendToken(); \ No newline at end of file diff --git a/reference/demo/send_token/send_somnia.mjs b/reference/demo/send_token/send_somnia.mjs new file mode 100644 index 0000000..3003e1f --- /dev/null +++ b/reference/demo/send_token/send_somnia.mjs @@ -0,0 +1,39 @@ +// import { ethers } from 'ethers'; +import { ethers } from "https://cdn-cors.ethers.io/lib/ethers-5.6.9.esm.min.js"; + +// 设置 RPC URL +const providerUrl = 'https://dream-rpc.somnia.network'; +const provider = new ethers.JsonRpcProvider(providerUrl); + +// 替换为您的钱包私钥(发送方钱包) +const privateKey = '0x3991542110242368f4770716be904b0ca6d44a8dbe4501771833b1a3642198d1'; // 私钥 +const wallet = new ethers.Wallet(privateKey, provider); + +// 接收方钱包地址 +const recipientAddress = '0x70D5EE1DfddD3726f0D71F4CD5a8ef43aC651a75'; + +// 发送代币的函数 +async function sendToken() { + try { + const amountToSend = ethers.parseEther('0.0000000000001'); // 发送数量 + + // 构造交易对象 + const tx = { + to: recipientAddress, + value: amountToSend + }; + + // 发送交易 + const txResponse = await wallet.sendTransaction(tx); + console.log('Transaction hash:', txResponse.hash); + + // 等待交易确认 + const receipt = await txResponse.wait(); + console.log('Transaction receipt:', receipt); + } catch (error) { + console.error('Error sending Token:', error); + } +} + +// 调用发送Token的函数 +sendToken(); \ No newline at end of file diff --git a/reference/package-lock.json b/reference/package-lock.json new file mode 100644 index 0000000..3a500fd --- /dev/null +++ b/reference/package-lock.json @@ -0,0 +1,1512 @@ +{ + "name": "walletoperation", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "walletoperation", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@mysten/sui.js": "^0.54.1", + "axios": "^1.9.0", + "ethers": "^6.14.3", + "web3": "^4.16.0" + } + }, + "node_modules/@0no-co/graphql.web": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@0no-co/graphql.web/-/graphql.web-1.1.2.tgz", + "integrity": "sha512-N2NGsU5FLBhT8NZ+3l2YrzZSHITjNXNuDhC4iDiikv0IujaJ0Xc6xIxQZ/Ek3Cb+rgPjnLHYyJm11tInuJn+cw==", + "license": "MIT", + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + }, + "peerDependenciesMeta": { + "graphql": { + "optional": true + } + } + }, + "node_modules/@0no-co/graphqlsp": { + "version": "1.12.16", + "resolved": "https://registry.npmjs.org/@0no-co/graphqlsp/-/graphqlsp-1.12.16.tgz", + "integrity": "sha512-B5pyYVH93Etv7xjT6IfB7QtMBdaaC07yjbhN6v8H7KgFStMkPvi+oWYBTibMFRMY89qwc9H8YixXg8SXDVgYWw==", + "license": "MIT", + "dependencies": { + "@gql.tada/internal": "^1.0.0", + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0" + }, + "peerDependencies": { + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0", + "typescript": "^5.0.0" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz", + "integrity": "sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==", + "license": "MIT" + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@gql.tada/cli-utils": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@gql.tada/cli-utils/-/cli-utils-1.6.3.tgz", + "integrity": "sha512-jFFSY8OxYeBxdKi58UzeMXG1tdm4FVjXa8WHIi66Gzu9JWtCE6mqom3a8xkmSw+mVaybFW5EN2WXf1WztJVNyQ==", + "license": "MIT", + "dependencies": { + "@0no-co/graphqlsp": "^1.12.13", + "@gql.tada/internal": "1.0.8", + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0" + }, + "peerDependencies": { + "@0no-co/graphqlsp": "^1.12.13", + "@gql.tada/svelte-support": "1.0.1", + "@gql.tada/vue-support": "1.0.1", + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0", + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "@gql.tada/svelte-support": { + "optional": true + }, + "@gql.tada/vue-support": { + "optional": true + } + } + }, + "node_modules/@gql.tada/internal": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@gql.tada/internal/-/internal-1.0.8.tgz", + "integrity": "sha512-XYdxJhtHC5WtZfdDqtKjcQ4d7R1s0d1rnlSs3OcBEUbYiPoJJfZU7tWsVXuv047Z6msvmr4ompJ7eLSK5Km57g==", + "license": "MIT", + "dependencies": { + "@0no-co/graphql.web": "^1.0.5" + }, + "peerDependencies": { + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0", + "typescript": "^5.0.0" + } + }, + "node_modules/@graphql-typed-document-node/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", + "license": "MIT", + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + } + }, + "node_modules/@mysten/bcs": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@mysten/bcs/-/bcs-0.11.1.tgz", + "integrity": "sha512-xP85isNSYUCHd3O/g+TmZYmg4wK6cU8q/n/MebkIGP4CYVJZz2wU/G24xIZ3wI+0iTop4dfgA5kYrg/DQKCUzA==", + "license": "Apache-2.0", + "dependencies": { + "bs58": "^5.0.0" + } + }, + "node_modules/@mysten/sui.js": { + "version": "0.54.1", + "resolved": "https://registry.npmjs.org/@mysten/sui.js/-/sui.js-0.54.1.tgz", + "integrity": "sha512-TSmGIX7U9O/uS9EKIQdv7/S69KTbBhMJVelXCafJE6IJw8iB9cN9uLu0+uklkBSDrbRmLSEY70jMr3uRFjReIg==", + "deprecated": "This package has been renamed to @mysten/sui, please update to use the renamed package.", + "license": "Apache-2.0", + "dependencies": { + "@graphql-typed-document-node/core": "^3.2.0", + "@mysten/bcs": "0.11.1", + "@noble/curves": "^1.1.0", + "@noble/hashes": "^1.3.1", + "@scure/bip32": "^1.3.1", + "@scure/bip39": "^1.2.1", + "@suchipi/femver": "^1.0.0", + "bech32": "^2.0.0", + "gql.tada": "^1.7.0", + "graphql": "^16.8.1", + "superstruct": "^1.0.3", + "tweetnacl": "^1.0.3" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@noble/curves": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", + "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", + "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.9.0", + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", + "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@suchipi/femver": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@suchipi/femver/-/femver-1.0.0.tgz", + "integrity": "sha512-bprE8+K5V+DPX7q2e2K57ImqNBdfGHDIWaGI5xHxZoxbKOuQZn4wzPiUxOAHnsUr3w3xHrWXwN7gnG/iIuEMIg==", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.15.29", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.29.tgz", + "integrity": "sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/abitype": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-0.7.1.tgz", + "integrity": "sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ==", + "license": "MIT", + "peerDependencies": { + "typescript": ">=4.9.4", + "zod": "^3 >=3.19.1" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/base-x": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.1.tgz", + "integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==", + "license": "MIT" + }, + "node_modules/bech32": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", + "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==", + "license": "MIT" + }, + "node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "license": "MIT", + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/cross-fetch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.1.0.tgz", + "integrity": "sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "license": "MIT", + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/ethereum-cryptography/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers": { + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.14.3.tgz", + "integrity": "sha512-qq7ft/oCJohoTcsNPFaXSQUm457MA5iWqkf1Mb11ujONdg7jBI6sAOrHaTi3j0CBqIGFSCeR/RMc+qwRRub7IA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "22.7.5", + "aes-js": "4.0.0-beta.5", + "tslib": "2.7.0", + "ws": "8.17.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers/node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", + "license": "MIT" + }, + "node_modules/ethers/node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers/node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers/node_modules/@types/node": { + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/ethers/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "license": "MIT" + }, + "node_modules/ethers/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/form-data": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", + "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gql.tada": { + "version": "1.8.10", + "resolved": "https://registry.npmjs.org/gql.tada/-/gql.tada-1.8.10.tgz", + "integrity": "sha512-FrvSxgz838FYVPgZHGOSgbpOjhR+yq44rCzww3oOPJYi0OvBJjAgCiP6LEokZIYND2fUTXzQAyLgcvgw1yNP5A==", + "license": "MIT", + "dependencies": { + "@0no-co/graphql.web": "^1.0.5", + "@0no-co/graphqlsp": "^1.12.13", + "@gql.tada/cli-utils": "1.6.3", + "@gql.tada/internal": "1.0.8" + }, + "bin": { + "gql-tada": "bin/cli.js", + "gql.tada": "bin/cli.js" + }, + "peerDependencies": { + "typescript": "^5.0.0" + } + }, + "node_modules/graphql": { + "version": "16.11.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.11.0.tgz", + "integrity": "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, + "node_modules/superstruct": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-1.0.4.tgz", + "integrity": "sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "license": "0BSD" + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==", + "license": "Unlicense" + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/web3": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/web3/-/web3-4.16.0.tgz", + "integrity": "sha512-SgoMSBo6EsJ5GFCGar2E/pR2lcR/xmUSuQ61iK6yDqzxmm42aPPxSqZfJz2z/UCR6pk03u77pU8TGV6lgMDdIQ==", + "license": "LGPL-3.0", + "dependencies": { + "web3-core": "^4.7.1", + "web3-errors": "^1.3.1", + "web3-eth": "^4.11.1", + "web3-eth-abi": "^4.4.1", + "web3-eth-accounts": "^4.3.1", + "web3-eth-contract": "^4.7.2", + "web3-eth-ens": "^4.4.0", + "web3-eth-iban": "^4.0.7", + "web3-eth-personal": "^4.1.0", + "web3-net": "^4.1.0", + "web3-providers-http": "^4.2.0", + "web3-providers-ws": "^4.0.8", + "web3-rpc-methods": "^1.3.0", + "web3-rpc-providers": "^1.0.0-rc.4", + "web3-types": "^1.10.0", + "web3-utils": "^4.3.3", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-core": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-4.7.1.tgz", + "integrity": "sha512-9KSeASCb/y6BG7rwhgtYC4CvYY66JfkmGNEYb7q1xgjt9BWfkf09MJPaRyoyT5trdOxYDHkT9tDlypvQWaU8UQ==", + "license": "LGPL-3.0", + "dependencies": { + "web3-errors": "^1.3.1", + "web3-eth-accounts": "^4.3.1", + "web3-eth-iban": "^4.0.7", + "web3-providers-http": "^4.2.0", + "web3-providers-ws": "^4.0.8", + "web3-types": "^1.10.0", + "web3-utils": "^4.3.3", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + }, + "optionalDependencies": { + "web3-providers-ipc": "^4.0.7" + } + }, + "node_modules/web3-errors": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/web3-errors/-/web3-errors-1.3.1.tgz", + "integrity": "sha512-w3NMJujH+ZSW4ltIZZKtdbkbyQEvBzyp3JRn59Ckli0Nz4VMsVq8aF1bLWM7A2kuQ+yVEm3ySeNU+7mSRwx7RQ==", + "license": "LGPL-3.0", + "dependencies": { + "web3-types": "^1.10.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-4.11.1.tgz", + "integrity": "sha512-q9zOkzHnbLv44mwgLjLXuyqszHuUgZWsQayD2i/rus2uk0G7hMn11bE2Q3hOVnJS4ws4VCtUznlMxwKQ+38V2w==", + "license": "LGPL-3.0", + "dependencies": { + "setimmediate": "^1.0.5", + "web3-core": "^4.7.1", + "web3-errors": "^1.3.1", + "web3-eth-abi": "^4.4.1", + "web3-eth-accounts": "^4.3.1", + "web3-net": "^4.1.0", + "web3-providers-ws": "^4.0.8", + "web3-rpc-methods": "^1.3.0", + "web3-types": "^1.10.0", + "web3-utils": "^4.3.3", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-abi": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-4.4.1.tgz", + "integrity": "sha512-60ecEkF6kQ9zAfbTY04Nc9q4eEYM0++BySpGi8wZ2PD1tw/c0SDvsKhV6IKURxLJhsDlb08dATc3iD6IbtWJmg==", + "license": "LGPL-3.0", + "dependencies": { + "abitype": "0.7.1", + "web3-errors": "^1.3.1", + "web3-types": "^1.10.0", + "web3-utils": "^4.3.3", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-accounts": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-4.3.1.tgz", + "integrity": "sha512-rTXf+H9OKze6lxi7WMMOF1/2cZvJb2AOnbNQxPhBDssKOllAMzLhg1FbZ4Mf3lWecWfN6luWgRhaeSqO1l+IBQ==", + "license": "LGPL-3.0", + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "crc-32": "^1.2.2", + "ethereum-cryptography": "^2.0.0", + "web3-errors": "^1.3.1", + "web3-types": "^1.10.0", + "web3-utils": "^4.3.3", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-contract": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-4.7.2.tgz", + "integrity": "sha512-3ETqs2pMNPEAc7BVY/C3voOhTUeJdkf2aM3X1v+edbngJLHAxbvxKpOqrcO0cjXzC4uc2Q8Zpf8n8zT5r0eLnA==", + "license": "LGPL-3.0", + "dependencies": { + "@ethereumjs/rlp": "^5.0.2", + "web3-core": "^4.7.1", + "web3-errors": "^1.3.1", + "web3-eth": "^4.11.1", + "web3-eth-abi": "^4.4.1", + "web3-types": "^1.10.0", + "web3-utils": "^4.3.3", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-contract/node_modules/@ethereumjs/rlp": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-5.0.2.tgz", + "integrity": "sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==", + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp.cjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/web3-eth-ens": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-4.4.0.tgz", + "integrity": "sha512-DeyVIS060hNV9g8dnTx92syqvgbvPricE3MerCxe/DquNZT3tD8aVgFfq65GATtpCgDDJffO2bVeHp3XBemnSQ==", + "license": "LGPL-3.0", + "dependencies": { + "@adraffy/ens-normalize": "^1.8.8", + "web3-core": "^4.5.0", + "web3-errors": "^1.2.0", + "web3-eth": "^4.8.0", + "web3-eth-contract": "^4.5.0", + "web3-net": "^4.1.0", + "web3-types": "^1.7.0", + "web3-utils": "^4.3.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-iban": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-4.0.7.tgz", + "integrity": "sha512-8weKLa9KuKRzibC87vNLdkinpUE30gn0IGY027F8doeJdcPUfsa4IlBgNC4k4HLBembBB2CTU0Kr/HAOqMeYVQ==", + "license": "LGPL-3.0", + "dependencies": { + "web3-errors": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7", + "web3-validator": "^2.0.3" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-eth-personal": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-4.1.0.tgz", + "integrity": "sha512-RFN83uMuvA5cu1zIwwJh9A/bAj0OBxmGN3tgx19OD/9ygeUZbifOL06jgFzN0t+1ekHqm3DXYQM8UfHpXi7yDQ==", + "license": "LGPL-3.0", + "dependencies": { + "web3-core": "^4.6.0", + "web3-eth": "^4.9.0", + "web3-rpc-methods": "^1.3.0", + "web3-types": "^1.8.0", + "web3-utils": "^4.3.1", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-net": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-4.1.0.tgz", + "integrity": "sha512-WWmfvHVIXWEoBDWdgKNYKN8rAy6SgluZ0abyRyXOL3ESr7ym7pKWbfP4fjApIHlYTh8tNqkrdPfM4Dyi6CA0SA==", + "license": "LGPL-3.0", + "dependencies": { + "web3-core": "^4.4.0", + "web3-rpc-methods": "^1.3.0", + "web3-types": "^1.6.0", + "web3-utils": "^4.3.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-providers-http": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-4.2.0.tgz", + "integrity": "sha512-IPMnDtHB7dVwaB7/mMxAZzyq7d5ezfO1+Vw0bNfAeIi7gaDlJiggp85SdyAfOgov8AMUA/dyiY72kQ0KmjXKvQ==", + "license": "LGPL-3.0", + "dependencies": { + "cross-fetch": "^4.0.0", + "web3-errors": "^1.3.0", + "web3-types": "^1.7.0", + "web3-utils": "^4.3.1" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-providers-ipc": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-4.0.7.tgz", + "integrity": "sha512-YbNqY4zUvIaK2MHr1lQFE53/8t/ejHtJchrWn9zVbFMGXlTsOAbNoIoZWROrg1v+hCBvT2c9z8xt7e/+uz5p1g==", + "license": "LGPL-3.0", + "optional": true, + "dependencies": { + "web3-errors": "^1.1.3", + "web3-types": "^1.3.0", + "web3-utils": "^4.0.7" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-providers-ws": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-4.0.8.tgz", + "integrity": "sha512-goJdgata7v4pyzHRsg9fSegUG4gVnHZSHODhNnn6J93ykHkBI1nz4fjlGpcQLUMi4jAMz6SHl9Ibzs2jj9xqPw==", + "license": "LGPL-3.0", + "dependencies": { + "@types/ws": "8.5.3", + "isomorphic-ws": "^5.0.0", + "web3-errors": "^1.2.0", + "web3-types": "^1.7.0", + "web3-utils": "^4.3.1", + "ws": "^8.17.1" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-rpc-methods": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/web3-rpc-methods/-/web3-rpc-methods-1.3.0.tgz", + "integrity": "sha512-/CHmzGN+IYgdBOme7PdqzF+FNeMleefzqs0LVOduncSaqsppeOEoskLXb2anSpzmQAP3xZJPaTrkQPWSJMORig==", + "license": "LGPL-3.0", + "dependencies": { + "web3-core": "^4.4.0", + "web3-types": "^1.6.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-rpc-providers": { + "version": "1.0.0-rc.4", + "resolved": "https://registry.npmjs.org/web3-rpc-providers/-/web3-rpc-providers-1.0.0-rc.4.tgz", + "integrity": "sha512-PXosCqHW0EADrYzgmueNHP3Y5jcSmSwH+Dkqvn7EYD0T2jcsdDAIHqk6szBiwIdhumM7gv9Raprsu/s/f7h1fw==", + "license": "LGPL-3.0", + "dependencies": { + "web3-errors": "^1.3.1", + "web3-providers-http": "^4.2.0", + "web3-providers-ws": "^4.0.8", + "web3-types": "^1.10.0", + "web3-utils": "^4.3.3", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-types": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/web3-types/-/web3-types-1.10.0.tgz", + "integrity": "sha512-0IXoaAFtFc8Yin7cCdQfB9ZmjafrbP6BO0f0KT/khMhXKUpoJ6yShrVhiNpyRBo8QQjuOagsWzwSK2H49I7sbw==", + "license": "LGPL-3.0", + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-4.3.3.tgz", + "integrity": "sha512-kZUeCwaQm+RNc2Bf1V3BYbF29lQQKz28L0y+FA4G0lS8IxtJVGi5SeDTUkpwqqkdHHC7JcapPDnyyzJ1lfWlOw==", + "license": "LGPL-3.0", + "dependencies": { + "ethereum-cryptography": "^2.0.0", + "eventemitter3": "^5.0.1", + "web3-errors": "^1.3.1", + "web3-types": "^1.10.0", + "web3-validator": "^2.0.6" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/web3-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/web3-validator/-/web3-validator-2.0.6.tgz", + "integrity": "sha512-qn9id0/l1bWmvH4XfnG/JtGKKwut2Vokl6YXP5Kfg424npysmtRLe9DgiNBM9Op7QL/aSiaA0TVXibuIuWcizg==", + "license": "LGPL-3.0", + "dependencies": { + "ethereum-cryptography": "^2.0.0", + "util": "^0.12.5", + "web3-errors": "^1.2.0", + "web3-types": "^1.6.0", + "zod": "^3.21.4" + }, + "engines": { + "node": ">=14", + "npm": ">=6.12.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ws": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/zod": { + "version": "3.25.49", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.49.tgz", + "integrity": "sha512-JMMPMy9ZBk3XFEdbM3iL1brx4NUSejd6xr3ELrrGEfGb355gjhiAWtG3K5o+AViV/3ZfkIrCzXsZn6SbLwTR8Q==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/reference/package.json b/reference/package.json new file mode 100644 index 0000000..8a16343 --- /dev/null +++ b/reference/package.json @@ -0,0 +1,23 @@ +{ + "name": "walletoperation", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://gogs.erhe.top/toor/WalletOperation.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "dependencies": { + "@mysten/sui.js": "^0.54.1", + "axios": "^1.9.0", + "ethers": "^6.14.3", + "web3": "^4.16.0" + } +} diff --git a/reference/test/test_balance_query_monad.mjs b/reference/test/test_balance_query_monad.mjs new file mode 100644 index 0000000..dfafe8e --- /dev/null +++ b/reference/test/test_balance_query_monad.mjs @@ -0,0 +1,66 @@ +import { ethers } from "ethers"; + +// 设置 RPC URL +const rpcUrl = "https://testnet-rpc.monad.xyz"; + +// 初始化 ethers.js 提供器 +const provider = new ethers.JsonRpcProvider(rpcUrl); + +// 检查是否连接成功 +async function checkConnection() { + try { + const network = await provider.getNetwork(); + console.log(`已成功连接到链节点,网络ID为: ${network.chainId}。正在查询钱包余额...`); + return true; + } catch (error) { + console.log("无法连接到链节点,请检查 URL 是否正确"); + return false; + } +} + +// 替换为实际的钱包地址列表 +const walletAddresses = [ + "0x10A43E7Fe77E2D84adBeC26cF0bFc6f403841266", + "0x70D5EE1DfddD3726f0D71F4CD5a8ef43aC651a75" +]; + +async function queryBalances() { + const isConnected = await checkConnection(); + if (!isConnected) { + return; + } + + for (const walletAddress of walletAddresses) { + let retryCount = 0; + const maxRetries = 3; + const delay = 2000; // 延迟时间,单位为毫秒 + + let resultMessage = ""; + let resultBalance = -1; + + while (retryCount < maxRetries) { + try { + // 查询余额 + const balance = await provider.getBalance(walletAddress); + // 将余额从 Wei 转换为 Ether + const balanceEth = ethers.formatUnits(balance, 18); + resultMessage = `Wallet address: ${walletAddress}, balance: ${balanceEth} Token`; + resultBalance = balanceEth; + console.log(resultMessage); + break; + } catch (e) { + console.log(`查询钱包 ${walletAddress} 余额时发生错误: ${e.message}`); + retryCount += 1; + console.log(`正在重试...(第 ${retryCount} 次)`); + await new Promise((resolve) => setTimeout(resolve, delay)); + } + } + + if (retryCount === maxRetries) { + resultMessage = `钱包 ${walletAddress} 查询余额失败,已达到最大重试次数。`; + console.log(resultMessage); + } + } +} + +queryBalances(); \ No newline at end of file diff --git a/reference/test/test_contract_monad.mjs b/reference/test/test_contract_monad.mjs new file mode 100644 index 0000000..aaeaa97 --- /dev/null +++ b/reference/test/test_contract_monad.mjs @@ -0,0 +1,58 @@ +import { ethers } from 'ethers'; + +const providerUrl = 'https://testnet-rpc.monad.xyz'; +const provider = new ethers.JsonRpcProvider(providerUrl); +const privateKeyList = [ + '2a185eae14ca82ac934a5f952e12e0d4a64043c911c33a19afd48ef1a1d70c46', + // Add more private keys here + // 'your_second_private_key', + // 'your_third_private_key', +]; +const stakingContractAddress = '0xcBE623D259261FFa0CFAff44484bFF46c1b7D6c2'; + +// Function to generate random delay between 5-10 seconds +const getRandomDelay = () => { + return Math.floor(Math.random() * (10000 - 5000 + 1)) + 5000; +}; + +// Function to handle staking for a single wallet +async function stakeMon(wallet) { + try { + const balance = await provider.getBalance(wallet.address); + console.log(`Wallet ${wallet.address} balance:`, ethers.formatEther(balance)); + const amountToStake = ethers.parseEther('0'); + if (balance < amountToStake) { + throw new Error(`Insufficient balance for staking in wallet ${wallet.address}`); + } + + const tx = await wallet.sendTransaction({ + to: stakingContractAddress, + value: amountToStake, + data: '0x7ab71841', + gasLimit: 1000000, + gasPrice: ethers.parseUnits('52', 'gwei') + }); + console.log(`Stake transaction hash for ${wallet.address}:`, tx.hash); + const receipt = await tx.wait(); + console.log(`Stake transaction receipt for ${wallet.address}:`, receipt); + } catch (error) { + console.error(`Error staking $MON for ${wallet.address}:`, error); + } +} + +// Function to process all wallets with delay +async function processAllWallets() { + for (const privateKey of privateKeyList) { + const wallet = new ethers.Wallet(privateKey, provider); + await stakeMon(wallet); + + // Add random delay between 5-10 seconds, except for the last wallet + if (privateKey !== privateKeyList[privateKeyList.length - 1]) { + const delay = getRandomDelay(); + console.log(`Waiting ${delay/1000} seconds before next wallet...`); + await new Promise(resolve => setTimeout(resolve, delay)); + } + } +} + +processAllWallets(); diff --git a/reference/test/test_nonce_monad.mjs b/reference/test/test_nonce_monad.mjs new file mode 100644 index 0000000..56843f0 --- /dev/null +++ b/reference/test/test_nonce_monad.mjs @@ -0,0 +1,33 @@ +import { ethers } from 'ethers'; + +// 使用 ethers.js 的 Provider +const rpcUrl = 'https://testnet-rpc.monad.xyz'; +const provider = new ethers.JsonRpcProvider(rpcUrl); + +const addresses = [ + '0x10A43E7Fe77E2D84adBeC26cF0bFc6f403841266', + '0x70D5EE1DfddD3726f0D71F4CD5a8ef43aC651a75' +]; + +// 测试钱包 +// const addresses = ['0x10A43E7Fe77E2D84adBeC26cF0bFc6f403841266'] + +async function getNonces() { + try { + let countNum = 1; + for (const address of addresses) { + // 获取最新的 nonce + const nonceLatest = await provider.getTransactionCount(address, 'latest'); + const noncePending = await provider.getTransactionCount(address, 'pending'); + const countNumStr = String(countNum).padStart(2, '0'); + console.log(`${countNumStr} address: ${address}`); + console.log(`pending nonce: ${noncePending} ; latest nonce: ${nonceLatest}`); + console.log('-----------------------------'); + countNum++; + } + } catch (error) { + console.error('获取 nonce 时发生错误:', error.message); + } +} + +getNonces(); diff --git a/reference/test/test_send_monad_token.mjs b/reference/test/test_send_monad_token.mjs new file mode 100644 index 0000000..e248a84 --- /dev/null +++ b/reference/test/test_send_monad_token.mjs @@ -0,0 +1,38 @@ +import { ethers } from 'ethers'; + +// 替换为您的节点URL +const providerUrl = 'https://testnet-rpc.monad.xyz'; +const provider = new ethers.JsonRpcProvider(providerUrl); + +// 替换为您的钱包私钥(发送方钱包) +const privateKey = '0x3991542110242368f4770716be904b0ca6d44a8dbe4501771833b1a3642198d1'; // 私钥 +const wallet = new ethers.Wallet(privateKey, provider); + +// 接收方钱包地址 +const recipientAddress = '0x70D5EE1DfddD3726f0D71F4CD5a8ef43aC651a75'; + +// 发送代币的函数 +async function sendToken() { + try { + const amountToSend = ethers.parseEther('0.0000001'); // 发送数量 + + // 构造交易对象 + const tx = { + to: recipientAddress, + value: amountToSend + }; + + // 发送交易 + const txResponse = await wallet.sendTransaction(tx); + console.log('Transaction hash:', txResponse.hash); + + // 等待交易确认 + const receipt = await txResponse.wait(); + console.log('Transaction receipt:', receipt); + } catch (error) { + console.error('Error sending Token:', error); + } +} + +// 调用发送Token的函数 +sendToken(); \ No newline at end of file diff --git a/reference/tools/demoAccount.txt b/reference/tools/demoAccount.txt new file mode 100644 index 0000000..ed3d838 --- /dev/null +++ b/reference/tools/demoAccount.txt @@ -0,0 +1 @@ +0x3991542110242368f4770716be904b0ca6d44a8dbe4501771833b1a3642198d1 \ No newline at end of file diff --git a/reference/tools/demoLoadAccountKey.mjs b/reference/tools/demoLoadAccountKey.mjs new file mode 100644 index 0000000..1a5610b --- /dev/null +++ b/reference/tools/demoLoadAccountKey.mjs @@ -0,0 +1,23 @@ +import fs from 'fs/promises'; + +const filePath = './demoAccount.txt'; + +// 返回一个 Promise +async function loadData() { + try { + const data = await fs.readFile(filePath, 'utf8'); + const privateKeyList = data.split('\n'); + return privateKeyList; + } catch (err) { + console.error('读取文件时发生错误:', err); + process.exit(1); + } +} + +// 调用 loadData 并等待结果 +async function main() { + const privateKeyList = await loadData(); + console.log(privateKeyList); +} + +main(); \ No newline at end of file diff --git a/reference/tools/generateWallet.mjs b/reference/tools/generateWallet.mjs new file mode 100644 index 0000000..7aa0a03 --- /dev/null +++ b/reference/tools/generateWallet.mjs @@ -0,0 +1,48 @@ +// generateWallet.mjs +import { ethers } from "ethers"; + +async function generateWallets(mnemonic, numWallets) { + const wallets = []; + + // 验证助记词是否有效 + if (!ethers.Mnemonic.isValidMnemonic(mnemonic)) { + throw new Error("Invalid mnemonic phrase"); + } + + for (let i = 0; i < numWallets; i++) { + // 使用 BIP-44 派生路径生成钱包 + const path = `m/44'/60'/0'/0/${i}`; + // 显式创建 HD 节点并派生钱包 + const hdNode = ethers.HDNodeWallet.fromPhrase(mnemonic, undefined, path); + const wallet = new ethers.Wallet(hdNode.privateKey); + const address = wallet.address; + const privateKey = wallet.privateKey; + + wallets.push({ address, privateKey, mnemonic, path }); // 包含路径以便调试 + } + + const addresses = new Set(wallets.map(w => w.address)); + if (addresses.size !== numWallets) { + throw new Error(`Duplicate wallets detected! Generated ${addresses.size} unique addresses instead of ${numWallets}`); + } + + return wallets; +} + +const mnemonic = "need rare control glove luxury punch orbit beef antique return average appear trumpet cattle hundred unknown unable exist rotate village produce address guilt naive"; +const numWallets = 100; + +generateWallets(mnemonic, numWallets) + .then(wallets => { + wallets.forEach((wallet, index) => { + console.log(`Wallet ${index + 1}:`); + console.log(` Address: ${wallet.address}`); + console.log(` Private Key: ${wallet.privateKey}`); + console.log(` Mnemonic: ${wallet.mnemonic}`); + console.log(` Path: ${wallet.path}`); + console.log("---"); + }); + }) + .catch(error => { + console.error("Error generating wallets:", error.message); + }); diff --git a/test/load_key_to_wallet.py b/test/load_key_to_wallet.py new file mode 100644 index 0000000..bc1c3bf --- /dev/null +++ b/test/load_key_to_wallet.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from web3 import Web3 + +privateKeyList = [ + '0x3991542110242368f4770716be904b0ca6d44a8dbe4501771833b1a3642198d1' +] \ No newline at end of file diff --git a/test/test_contract.py b/test/test_contract.py new file mode 100644 index 0000000..b74a4b6 --- /dev/null +++ b/test/test_contract.py @@ -0,0 +1,88 @@ +from web3 import Web3 +import json + +# Monad 测试网 RPC URL +rpc_url = "https://testnet-rpc.monad.xyz" + +# 连接到 Monad 测试网 +w3 = Web3(Web3.HTTPProvider(rpc_url)) + +# 检查是否成功连接 +if not w3.is_connected(): + raise Exception("无法连接到 Monad 测试网") + +# 合约地址和 ABI(仅保留 transfer 和 decimals) +contract_address = w3.to_checksum_address("0x760AfE86e5de5fa0Ee542fc7B7B713e1c5425701") +abi = json.loads('''[ + {"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}, + {"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"} +]''') + +# 初始化合约 +contract = w3.eth.contract(address=contract_address, abi=abi) + +# 你的钱包私钥和地址 +private_key = "b898cf63a5ec89105ba755ef3b7533c25ea9130ab50fb0db14779fb6efd4f9c6" # 替换为你的私钥 +account = w3.eth.account.from_key(private_key) +wallet_address = account.address + +# 辅助函数:签名并发送交易 +def send_transaction(tx): + """ + 签名并发送交易 + 参数: + tx: 交易字典 + 返回: + 交易回执 + """ + try: + tx['from'] = wallet_address + tx['nonce'] = w3.eth.get_transaction_count(wallet_address) + tx['gas'] = 100000 # Gas 限额,适用于简单的 transfer + tx['gasPrice'] = w3.eth.gas_price + signed_tx = w3.eth.account.sign_transaction(tx, private_key) + tx_hash = w3.eth.send_raw_transaction(signed_tx.raw_transaction) + return w3.eth.wait_for_transaction_receipt(tx_hash) + except Exception as e: + raise Exception(f"发送交易失败: {str(e)}") + +# 转账代币 +def transfer(recipient, amount): + """ + 转账代币给指定地址 + 参数: + recipient: 接收者地址 + amount: 转账的代币数量(以代币单位为准,例如 10 表示 10 个代币) + """ + try: + # 验证接收者地址 + if not w3.is_address(recipient): + raise ValueError("接收者地址无效") + recipient = w3.to_checksum_address(recipient) + + # 获取小数位并转换金额 + decimals = contract.functions.decimals().call() + if not isinstance(amount, (int, float)) or amount < 0: + raise ValueError("转账金额必须是非负数") + amount_wei = int(amount * 10**decimals) # 转换为最小单位 + + # 构建交易 + tx = contract.functions.transfer(recipient, amount_wei).build_transaction({ + 'chainId': w3.eth.chain_id, + 'gas': 100000, # 显式指定 Gas 限额 + 'gasPrice': w3.eth.gas_price, + 'nonce': w3.eth.get_transaction_count(wallet_address), + }) + + # 发送交易 + receipt = send_transaction(tx) + print(f"转账成功,交易哈希: {receipt.transactionHash.hex()}") + + except Exception as e: + print(f"转账失败: {str(e)}") + +# 示例用法 +if __name__ == "__main__": + # 转账 10 个代币给指定地址 + recipient_address = "0x760AfE86e5de5fa0Ee542fc7B7B713e1c5425701" # 0x904d6CEf48D78448E332B90f66e23a5aAedC1A47 + transfer(recipient_address, 0.000000005231854) # 修改此处的 10 为你想要转账的代币数量 diff --git a/test/test_contract1.py b/test/test_contract1.py new file mode 100644 index 0000000..f029906 --- /dev/null +++ b/test/test_contract1.py @@ -0,0 +1,144 @@ +# -*- coding: utf-8 -*- +from web3 import Web3 +import random +import time +import os + +# Monad 测试网 RPC URL +provider_url = "https://testnet-rpc.monad.xyz" +w3 = Web3(Web3.HTTPProvider(provider_url)) + +# 合约地址、合约方法哈希值及描述 +contract_data = [ + { + "address": "0x64Aff7245EbdAAECAf266852139c67E4D8DBa4de", + "data_hash": "0x7ff36ab5", + "description": "TEST" + } +] + +# 读取私钥文件 +file_path = os.path.join(os.path.dirname(__file__), 'AccountList.txt') + + +def get_random_amount(): + # 生成随机交易金额 例如 0.00000000****(最后4位随机数) + # 小数位数也是随机, 14 - 18 位 + + random_tail = str(random.randint(1000, 9999)) + random_bit = random.randint(14, 18) + random_balance = f"0.{random_tail.zfill(random_bit)}" + return Web3.to_wei(random_balance, "ether") + + +def get_random_contract_data(): + # 随机获取合约地址、合约方法哈希值及描述 + if not contract_data: + print("The contract data array is empty, the contract cannot be selected, and the program exits.") + exit(1) + return random.choice(contract_data) + + +def check_wallet_balance(balance, minimum_balance): + # 如果钱包余额小于等于最小余额 + if balance <= Web3.to_wei(minimum_balance, "ether"): + print("The wallet balance is invalid.") + exit(1) + + +async def execute_contract(account, minimum_balance): + try: + # 随机选择一个合约地址、合约方法哈希值及描述 + contract_info = get_random_contract_data() + address = contract_info["address"] + data_hash = contract_info["data_hash"] + description = contract_info["description"] + print(f"Selected contract: {description}") + print(f"Selected contract address: {address}") + print(f"Selected contract dataHash: {data_hash}") + + # 检查原生代币余额 + balance = w3.eth.get_balance(account.address) + before_balance = Web3.from_wei(balance, "ether") + print(f"Native balance: {before_balance}") + + # 检查钱包余额,不能小于 minimum_balance + check_wallet_balance(balance, minimum_balance) + + amount_to_stake = get_random_amount() + print(f"Amount to contract: {Web3.from_wei(amount_to_stake, 'ether')}") + + if balance < amount_to_stake: + raise Exception("Insufficient balance for contract execution.") + + # 构建交易 + nonce = w3.eth.get_transaction_count(account.address) + tx = { + "to": Web3.to_checksum_address(address), + "value": amount_to_stake, + "data": data_hash, + "gas": 100000, + "gasPrice": w3.eth.gas_price, + "nonce": nonce, + "chainId": w3.eth.chain_id + } + + # 签名并发送交易 + signed_tx = w3.eth.account.sign_transaction(tx, account.key) + tx_hash = w3.eth.send_raw_transaction(signed_tx.raw_transaction) + print(f"Contract Execution hash: {tx_hash.hex()}") + + # 等待交易确认 + receipt = w3.eth.wait_for_transaction_receipt(tx_hash) + execute_status = receipt["status"] + if execute_status == 1: + print("Contract Execution status: seccessful") + elif execute_status == 0: + print("Contract Execution status: failed") + else: + print("Contract Execution status: unknown") + + # 检查交易后的余额 + balance_staking = w3.eth.get_balance(account.address) + after_balance = Web3.from_wei(balance_staking, "ether") + print(f"Native balance after transaction: {after_balance}") + print(f"The cost of this transaction: {float(before_balance) - float(after_balance)}") + + except Exception as e: + print(f"Error executing contract: {e}") + + +async def run_multiple_staking(private_keys): + last_times = 9999 + min_delay = 10 + max_delay = 20 + minimum_balance = 0.01 + + for private_key in private_keys: + account = w3.eth.account.from_key(private_key.strip()) + print(f"Processing wallet with address: {account.address}") + + for i in range(last_times): + if last_times > 1: + print(f"Starting Contract attempt {i + 1}") + await execute_contract(account, minimum_balance) + print(f"Completed Contract attempt {i + 1}") + if i < last_times - 1: + delay = random.uniform(min_delay, max_delay) + print(f"Waiting for {delay} seconds...") + print('------------------------------------------------------------') + time.sleep(random.uniform(min_delay, max_delay)) + + +async def main(): + try: + await run_multiple_staking(['3991542110242368f4770716be904b0ca6d44a8dbe4501771833b1a3642198d1']) + except Exception as err: + print(f'读取文件时发生错误: {err}') + exit(1) + + +if __name__ == "__main__": + import asyncio + + asyncio.run(main()) diff --git a/tools/generateWallet.py b/tools/generateWallet.py new file mode 100644 index 0000000..1caf8f9 --- /dev/null +++ b/tools/generateWallet.py @@ -0,0 +1,25 @@ +from web3 import Web3 +from eth_account import Account +from bip44 import Wallet + +mnemonic = "morning cool cake surface state crucial stool rocket lobster medal fossil talent" +w = Wallet(mnemonic) + +private_keys = [] +addresses = [] + +for i in range(20): + private_key, address = w.derive_account("eth", i) + account = Account.from_key(private_key) + # print(f"Private Key {i+1}: {private_key.hex()}") + # print(f"Address {i+1}: {account.address}") + private_keys.append(private_key.hex()) + addresses.append(account.address) + +print('private_keys:\n--------------------------\n') +for pk in private_keys: + print(pk) +print() +print('addresses:\n--------------------------\n') +for addr in addresses: + print(addr) \ No newline at end of file