jack há 6 meses atrás
pai
commit
8d38a5a1cf
30 ficheiros alterados com 2900 adições e 0 exclusões
  1. 73 0
      demo/balance_query/balance_query_eth.py
  2. 84 0
      demo/balance_query/balance_query_monad.py
  3. 84 0
      demo/balance_query/balance_query_somnia.py
  4. 76 0
      reference/demo/balance_query/balance_query_eth.mjs
  5. 78 0
      reference/demo/balance_query/balance_query_monad.mjs
  6. 75 0
      reference/demo/balance_query/balance_query_somnia.mjs
  7. 29 0
      reference/demo/balance_query/balance_query_sui.mjs
  8. 46 0
      reference/demo/contract_interaction/contract_monad.mjs
  9. 38 0
      reference/demo/get_nonce/nonce_monad.mjs
  10. 37 0
      reference/demo/get_nonce/nonce_somnia.mjs
  11. 38 0
      reference/demo/send_token/send_monad.mjs
  12. 39 0
      reference/demo/send_token/send_somnia.mjs
  13. 1512 0
      reference/package-lock.json
  14. 23 0
      reference/package.json
  15. 1 0
      reference/project/monad/AccountList.txt
  16. 0 0
      reference/project/monad/Contract.mjs
  17. 0 0
      reference/project/monad/SendToken.mjs
  18. 56 0
      reference/project/monad/SignIn.mjs
  19. 148 0
      reference/project/monad/Swap.mjs
  20. 47 0
      reference/project/monad/nonce.mjs
  21. 1 0
      reference/project/pharos/AccountList.txt
  22. 83 0
      reference/project/pharos/Contract.mjs
  23. 65 0
      reference/project/pharos/balanceAndNonce.mjs
  24. 66 0
      reference/test/test_balance_query_monad.mjs
  25. 58 0
      reference/test/test_contract_monad.mjs
  26. 33 0
      reference/test/test_nonce_monad.mjs
  27. 38 0
      reference/test/test_send_monad_token.mjs
  28. 1 0
      reference/tools/demoAccount.txt
  29. 23 0
      reference/tools/demoLoadAccountKey.mjs
  30. 48 0
      reference/tools/generateWallet.mjs

+ 73 - 0
demo/balance_query/balance_query_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()

+ 84 - 0
demo/balance_query/balance_query_monad.py

@@ -0,0 +1,84 @@
+# -*- 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():
+    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()

+ 84 - 0
demo/balance_query/balance_query_somnia.py

@@ -0,0 +1,84 @@
+# -*- 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():
+    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()

+ 76 - 0
reference/demo/balance_query/balance_query_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();

+ 78 - 0
reference/demo/balance_query/balance_query_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();

+ 75 - 0
reference/demo/balance_query/balance_query_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();

+ 29 - 0
reference/demo/balance_query/balance_query_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);

+ 46 - 0
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();

+ 38 - 0
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();

+ 37 - 0
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();

+ 38 - 0
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();

+ 39 - 0
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();

+ 1512 - 0
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"
+      }
+    }
+  }
+}

+ 23 - 0
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"
+  }
+}

+ 1 - 0
reference/project/monad/AccountList.txt

@@ -0,0 +1 @@
+0x618a59dcbbc05a38e10b9872f50855c1b52dd01baced785a7134876ba404be1b

+ 0 - 0
reference/project/monad/Contract.mjs


+ 0 - 0
reference/project/monad/SendToken.mjs


+ 56 - 0
reference/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();

+ 148 - 0
reference/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();

+ 47 - 0
reference/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();

+ 1 - 0
reference/project/pharos/AccountList.txt

@@ -0,0 +1 @@
+0x4b833cf91c19c4d9434ffed4b18714ef032d2acf44caec110a1c2c7db151eb65

+ 83 - 0
reference/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();

+ 65 - 0
reference/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();

+ 66 - 0
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();

+ 58 - 0
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();

+ 33 - 0
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();

+ 38 - 0
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();

+ 1 - 0
reference/tools/demoAccount.txt

@@ -0,0 +1 @@
+0x3991542110242368f4770716be904b0ca6d44a8dbe4501771833b1a3642198d1

+ 23 - 0
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();

+ 48 - 0
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);
+    });