xflows 1.0.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -0
- package/dist/index.js +183 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,9 +15,17 @@ A command-line interface for the [Wanchain XFlows](https://docs.wanchain.org/dev
|
|
|
15
15
|
- [RPC Endpoints](#rpc-endpoints)
|
|
16
16
|
- [Commands](#commands)
|
|
17
17
|
- [Wallet Management](#wallet-management)
|
|
18
|
+
- [`wallet create`](#wallet-create----create-a-new-wallet)
|
|
19
|
+
- [`wallet list`](#wallet-list----list-all-saved-wallets)
|
|
20
|
+
- [`wallet show`](#wallet-show----show-wallet-details)
|
|
21
|
+
- [`wallet balance`](#wallet-balance----check-native-token-balance)
|
|
22
|
+
- [`wallet token-balance`](#wallet-token-balance----check-erc20-token-balance)
|
|
23
|
+
- [`wallet delete`](#wallet-delete----delete-a-wallet)
|
|
18
24
|
- [Query Commands](#query-commands)
|
|
19
25
|
- [Quote](#quote)
|
|
20
26
|
- [Send Transaction](#send-transaction)
|
|
27
|
+
- [Transfer (Native Token)](#transfer-native-token)
|
|
28
|
+
- [Transfer Token (ERC20)](#transfer-token-erc20)
|
|
21
29
|
- [Transaction Status](#transaction-status)
|
|
22
30
|
- [RPC List](#rpc-list)
|
|
23
31
|
- [Complete Workflow Example](#complete-workflow-example)
|
|
@@ -333,6 +341,32 @@ xflows wallet balance --name alice --chain-id 1 --rpc https://my-rpc.example.com
|
|
|
333
341
|
| `--password <pw>` | No | Password for encrypted wallets |
|
|
334
342
|
| `--rpc <url>` | No | Override default RPC endpoint |
|
|
335
343
|
|
|
344
|
+
#### `wallet token-balance` -- Check ERC20 token balance
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
# Check USDC balance on Ethereum
|
|
348
|
+
xflows wallet token-balance --name alice --chain-id 1 \
|
|
349
|
+
--token 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
|
|
350
|
+
|
|
351
|
+
# Check USDT balance on BSC (auto-detect decimals)
|
|
352
|
+
xflows wallet token-balance --name alice --chain-id 56 \
|
|
353
|
+
--token 0x55d398326f99059fF775485246999027B3197955
|
|
354
|
+
|
|
355
|
+
# Check with explicit decimals and custom RPC
|
|
356
|
+
xflows wallet token-balance --name alice --chain-id 1 \
|
|
357
|
+
--token 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
|
|
358
|
+
--decimals 6 --rpc https://my-rpc.example.com
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
| Flag | Required | Description |
|
|
362
|
+
|------|----------|-------------|
|
|
363
|
+
| `--name <name>` | Yes | Wallet name |
|
|
364
|
+
| `--chain-id <id>` | Yes | Chain ID to query balance on |
|
|
365
|
+
| `--token <addr>` | Yes | ERC20 token contract address |
|
|
366
|
+
| `--decimals <n>` | No | Token decimals (auto-detected if omitted) |
|
|
367
|
+
| `--password <pw>` | No | Password for encrypted wallets |
|
|
368
|
+
| `--rpc <url>` | No | Override default RPC endpoint |
|
|
369
|
+
|
|
336
370
|
#### `wallet delete` -- Delete a wallet
|
|
337
371
|
|
|
338
372
|
```bash
|
|
@@ -511,6 +545,76 @@ xflows send \
|
|
|
511
545
|
7. Waits for on-chain confirmation
|
|
512
546
|
8. Prints the transaction hash and a ready-to-use `xflows status` command for tracking
|
|
513
547
|
|
|
548
|
+
### Transfer (Native Token)
|
|
549
|
+
|
|
550
|
+
Send native tokens (ETH, BNB, WAN, etc.) on the same chain. This is a simple transfer, not a cross-chain bridge operation.
|
|
551
|
+
|
|
552
|
+
```bash
|
|
553
|
+
# Send 0.1 ETH on Ethereum
|
|
554
|
+
xflows transfer --wallet alice --chain-id 1 --to 0xRecipient --amount 0.1
|
|
555
|
+
|
|
556
|
+
# Send 1.5 BNB on BSC with encrypted wallet
|
|
557
|
+
xflows transfer --wallet alice --password mysecret --chain-id 56 --to 0xRecipient --amount 1.5
|
|
558
|
+
|
|
559
|
+
# Dry run (preview without sending)
|
|
560
|
+
xflows transfer --wallet alice --chain-id 1 --to 0xRecipient --amount 0.1 --dry-run
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
| Flag | Required | Description |
|
|
564
|
+
|------|----------|-------------|
|
|
565
|
+
| `--wallet <name>` | Yes | Wallet name to use for signing |
|
|
566
|
+
| `--chain-id <id>` | Yes | Chain ID to send on |
|
|
567
|
+
| `--to <address>` | Yes | Recipient address |
|
|
568
|
+
| `--amount <amount>` | Yes | Amount to send (human-readable, e.g., `0.1`) |
|
|
569
|
+
| `--password <pw>` | No | Password for encrypted wallet |
|
|
570
|
+
| `--rpc <url>` | No | Override default RPC endpoint |
|
|
571
|
+
| `--gas-limit <limit>` | No | Custom gas limit |
|
|
572
|
+
| `--dry-run` | No | Build but do not send the transaction |
|
|
573
|
+
|
|
574
|
+
### Transfer Token (ERC20)
|
|
575
|
+
|
|
576
|
+
Send ERC20 tokens on the same chain. Token decimals are auto-detected from the contract, or can be specified manually.
|
|
577
|
+
|
|
578
|
+
```bash
|
|
579
|
+
# Send 100 USDC on Ethereum (auto-detect decimals)
|
|
580
|
+
xflows transfer-token --wallet alice --chain-id 1 \
|
|
581
|
+
--token 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
|
|
582
|
+
--to 0xRecipient --amount 100
|
|
583
|
+
|
|
584
|
+
# Send with explicit decimals
|
|
585
|
+
xflows transfer-token --wallet alice --chain-id 1 \
|
|
586
|
+
--token 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
|
|
587
|
+
--to 0xRecipient --amount 100 --decimals 6
|
|
588
|
+
|
|
589
|
+
# Send 50 USDT on BSC with encrypted wallet
|
|
590
|
+
xflows transfer-token --wallet alice --password mysecret --chain-id 56 \
|
|
591
|
+
--token 0x55d398326f99059fF775485246999027B3197955 \
|
|
592
|
+
--to 0xRecipient --amount 50
|
|
593
|
+
|
|
594
|
+
# Dry run (preview without sending)
|
|
595
|
+
xflows transfer-token --wallet alice --chain-id 1 \
|
|
596
|
+
--token 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
|
|
597
|
+
--to 0xRecipient --amount 100 --dry-run
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
| Flag | Required | Description |
|
|
601
|
+
|------|----------|-------------|
|
|
602
|
+
| `--wallet <name>` | Yes | Wallet name to use for signing |
|
|
603
|
+
| `--chain-id <id>` | Yes | Chain ID to send on |
|
|
604
|
+
| `--token <address>` | Yes | ERC20 token contract address |
|
|
605
|
+
| `--to <address>` | Yes | Recipient address |
|
|
606
|
+
| `--amount <amount>` | Yes | Amount to send (human-readable, e.g., `100`) |
|
|
607
|
+
| `--decimals <n>` | No | Token decimals (auto-detected if omitted) |
|
|
608
|
+
| `--password <pw>` | No | Password for encrypted wallet |
|
|
609
|
+
| `--rpc <url>` | No | Override default RPC endpoint |
|
|
610
|
+
| `--gas-limit <limit>` | No | Custom gas limit |
|
|
611
|
+
| `--dry-run` | No | Build but do not send the transaction |
|
|
612
|
+
|
|
613
|
+
**Features:**
|
|
614
|
+
- Auto-detects token decimals and symbol from the contract
|
|
615
|
+
- Checks token balance before sending to provide a clear error message
|
|
616
|
+
- Supports Wanchain gas price enforcement
|
|
617
|
+
|
|
514
618
|
### Transaction Status
|
|
515
619
|
|
|
516
620
|
Check the current state of a cross-chain transaction.
|
package/dist/index.js
CHANGED
|
@@ -3955,6 +3955,9 @@ function parseUnits(value, unit) {
|
|
|
3955
3955
|
}
|
|
3956
3956
|
return FixedNumber.fromString(value, { decimals, width: 512 }).value;
|
|
3957
3957
|
}
|
|
3958
|
+
function parseEther(ether) {
|
|
3959
|
+
return parseUnits(ether, 18);
|
|
3960
|
+
}
|
|
3958
3961
|
// node_modules/ethers/lib.esm/utils/uuid.js
|
|
3959
3962
|
function uuidV4(randomBytes) {
|
|
3960
3963
|
const bytes = getBytes(randomBytes, "randomBytes");
|
|
@@ -18657,7 +18660,7 @@ import * as readline from "readline";
|
|
|
18657
18660
|
// package.json
|
|
18658
18661
|
var package_default = {
|
|
18659
18662
|
name: "xflows",
|
|
18660
|
-
version: "1.0
|
|
18663
|
+
version: "1.2.0",
|
|
18661
18664
|
description: "CLI tool for Wanchain XFlows cross-chain bridge - wallet management, quote queries, and cross-chain transactions",
|
|
18662
18665
|
type: "module",
|
|
18663
18666
|
bin: {
|
|
@@ -18826,14 +18829,18 @@ function printJson(data) {
|
|
|
18826
18829
|
}
|
|
18827
18830
|
var ERC20_ABI = [
|
|
18828
18831
|
"function approve(address spender, uint256 amount) returns (bool)",
|
|
18829
|
-
"function allowance(address owner, address spender) view returns (uint256)"
|
|
18832
|
+
"function allowance(address owner, address spender) view returns (uint256)",
|
|
18833
|
+
"function transfer(address to, uint256 amount) returns (bool)",
|
|
18834
|
+
"function balanceOf(address owner) view returns (uint256)",
|
|
18835
|
+
"function decimals() view returns (uint8)",
|
|
18836
|
+
"function symbol() view returns (string)"
|
|
18830
18837
|
];
|
|
18831
18838
|
var program2 = new Command;
|
|
18832
18839
|
program2.name("xflows").version(VERSION).description(`XFlows Cross-Chain Bridge CLI Tool
|
|
18833
18840
|
|
|
18834
18841
|
` + `A command-line interface for Wanchain XFlows cross-chain bridge.
|
|
18835
18842
|
` + `Supports wallet management, quote queries, cross-chain transactions,
|
|
18836
|
-
` + `and all XFlows API query endpoints.
|
|
18843
|
+
` + `same-chain native/ERC20 transfers, and all XFlows API query endpoints.
|
|
18837
18844
|
|
|
18838
18845
|
` + `Wallet files are stored in ~/.xflows/wallets/
|
|
18839
18846
|
|
|
@@ -18842,6 +18849,8 @@ program2.name("xflows").version(VERSION).description(`XFlows Cross-Chain Bridge
|
|
|
18842
18849
|
` + ` xflows wallet create --name secureWallet --encrypt
|
|
18843
18850
|
` + ` xflows chains
|
|
18844
18851
|
` + ` xflows tokens --chain-id 1
|
|
18852
|
+
` + ` xflows transfer --wallet myWallet --chain-id 1 --to 0x... --amount 0.1
|
|
18853
|
+
` + ` xflows transfer-token --wallet myWallet --chain-id 1 --token 0x... --to 0x... --amount 100
|
|
18845
18854
|
` + ` xflows quote --from-chain 1 --to-chain 56 --from-token 0x0...0 --to-token 0x0...0 --from-address 0x... --to-address 0x... --amount 1.0
|
|
18846
18855
|
` + ` xflows send --wallet myWallet --from-chain 1 --to-chain 56 --from-token 0x0...0 --to-token 0x0...0 --to-address 0x... --amount 1.0
|
|
18847
18856
|
` + " xflows status --hash 0x... --from-chain 1 --to-chain 56 --from-token 0x0...0 --to-token 0x0...0 --from-address 0x... --to-address 0x... --amount 1.0");
|
|
@@ -18949,6 +18958,42 @@ walletCmd.command("balance").description(`Check native token balance on a specif
|
|
|
18949
18958
|
process.exit(1);
|
|
18950
18959
|
}
|
|
18951
18960
|
});
|
|
18961
|
+
walletCmd.command("token-balance").description(`Check ERC20 token balance on a specific chain
|
|
18962
|
+
|
|
18963
|
+
` + `Examples:
|
|
18964
|
+
` + ` # Check USDC balance on Ethereum
|
|
18965
|
+
` + " xflows wallet token-balance --name alice --chain-id 1 \\\n" + ` --token 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
|
|
18966
|
+
|
|
18967
|
+
` + ` # Check USDT balance on BSC with explicit decimals
|
|
18968
|
+
` + " xflows wallet token-balance --name alice --chain-id 56 \\\n" + " --token 0x55d398326f99059fF775485246999027B3197955 --decimals 18").requiredOption("--name <name>", "Wallet name").requiredOption("--chain-id <chainId>", "Chain ID to check balance on").requiredOption("--token <address>", "ERC20 token contract address").option("--decimals <decimals>", "Token decimals (auto-detected if omitted)").option("--password <password>", "Password to decrypt encrypted wallet").option("--rpc <url>", "Custom RPC URL (overrides default)").action(async (opts) => {
|
|
18969
|
+
try {
|
|
18970
|
+
const wallet = loadWallet(opts.name, opts.password);
|
|
18971
|
+
const provider = opts.rpc ? new JsonRpcProvider(opts.rpc) : getProvider2(opts.chainId);
|
|
18972
|
+
const tokenContract = new Contract(opts.token, ERC20_ABI, provider);
|
|
18973
|
+
let decimals;
|
|
18974
|
+
if (opts.decimals !== undefined) {
|
|
18975
|
+
decimals = Number(opts.decimals);
|
|
18976
|
+
} else {
|
|
18977
|
+
try {
|
|
18978
|
+
decimals = Number(await tokenContract.decimals());
|
|
18979
|
+
} catch {
|
|
18980
|
+
throw new Error("Could not auto-detect token decimals. Please provide --decimals manually.");
|
|
18981
|
+
}
|
|
18982
|
+
}
|
|
18983
|
+
let symbol = "TOKEN";
|
|
18984
|
+
try {
|
|
18985
|
+
symbol = await tokenContract.symbol();
|
|
18986
|
+
} catch {}
|
|
18987
|
+
const balance = await tokenContract.balanceOf(wallet.address);
|
|
18988
|
+
console.log(`Address: ${wallet.address}`);
|
|
18989
|
+
console.log(`Chain: ${opts.chainId}`);
|
|
18990
|
+
console.log(`Token: ${opts.token} (${symbol})`);
|
|
18991
|
+
console.log(`Balance: ${formatUnits(balance, decimals)}`);
|
|
18992
|
+
} catch (e) {
|
|
18993
|
+
console.error(`Error: ${e.message}`);
|
|
18994
|
+
process.exit(1);
|
|
18995
|
+
}
|
|
18996
|
+
});
|
|
18952
18997
|
walletCmd.command("delete").description("Delete a saved wallet").requiredOption("--name <name>", "Wallet name to delete").option("--force", "Skip confirmation", false).action(async (opts) => {
|
|
18953
18998
|
const walletDir = getWalletDir();
|
|
18954
18999
|
const filePath = path.join(walletDir, `${opts.name}.json`);
|
|
@@ -19181,6 +19226,141 @@ You can track the cross-chain status with:`);
|
|
|
19181
19226
|
process.exit(1);
|
|
19182
19227
|
}
|
|
19183
19228
|
});
|
|
19229
|
+
program2.command("transfer").description(`Send native tokens (ETH/BNB/WAN/etc.) on the same chain
|
|
19230
|
+
|
|
19231
|
+
` + `This is a simple same-chain transfer, NOT a cross-chain bridge operation.
|
|
19232
|
+
|
|
19233
|
+
` + `Examples:
|
|
19234
|
+
` + ` # Send 0.1 ETH on Ethereum
|
|
19235
|
+
` + ` xflows transfer --wallet alice --chain-id 1 --to 0xRecipient --amount 0.1
|
|
19236
|
+
|
|
19237
|
+
` + ` # Send 1.5 BNB on BSC with encrypted wallet
|
|
19238
|
+
` + " xflows transfer --wallet alice --password mysecret --chain-id 56 --to 0xRecipient --amount 1.5").requiredOption("--wallet <name>", "Wallet name to use for signing").requiredOption("--chain-id <chainId>", "Chain ID to send on").requiredOption("--to <address>", "Recipient address").requiredOption("--amount <amount>", "Amount to send (human-readable, e.g., 0.1)").option("--password <password>", "Password to decrypt encrypted wallet").option("--rpc <url>", "Custom RPC URL (overrides default)").option("--gas-limit <limit>", "Custom gas limit").option("--dry-run", "Only build the transaction, don't send it", false).action(async (opts) => {
|
|
19239
|
+
try {
|
|
19240
|
+
const wallet = loadWallet(opts.wallet, opts.password);
|
|
19241
|
+
const provider = opts.rpc ? new JsonRpcProvider(opts.rpc) : getProvider2(opts.chainId);
|
|
19242
|
+
const signer = wallet.connect(provider);
|
|
19243
|
+
const txRequest = {
|
|
19244
|
+
to: opts.to,
|
|
19245
|
+
value: parseEther(opts.amount)
|
|
19246
|
+
};
|
|
19247
|
+
if (opts.gasLimit) {
|
|
19248
|
+
txRequest.gasLimit = BigInt(opts.gasLimit);
|
|
19249
|
+
}
|
|
19250
|
+
const isWanchain = opts.chainId === "888";
|
|
19251
|
+
if (isWanchain) {
|
|
19252
|
+
const feeData = await provider.getFeeData();
|
|
19253
|
+
const minBaseFee = parseUnits("1", "gwei");
|
|
19254
|
+
if (feeData.gasPrice && feeData.gasPrice < minBaseFee) {
|
|
19255
|
+
txRequest.gasPrice = minBaseFee;
|
|
19256
|
+
console.log("Wanchain: enforcing minimum gasPrice of 1 gwei");
|
|
19257
|
+
} else if (feeData.maxFeePerGas) {
|
|
19258
|
+
const maxFee = feeData.maxFeePerGas < minBaseFee ? minBaseFee : feeData.maxFeePerGas;
|
|
19259
|
+
txRequest.gasPrice = maxFee;
|
|
19260
|
+
console.log(`Wanchain: using gasPrice ${formatUnits(maxFee, "gwei")} gwei`);
|
|
19261
|
+
}
|
|
19262
|
+
}
|
|
19263
|
+
if (opts.dryRun) {
|
|
19264
|
+
console.log("[Dry Run] Transaction details:");
|
|
19265
|
+
printJson({
|
|
19266
|
+
from: wallet.address,
|
|
19267
|
+
to: opts.to,
|
|
19268
|
+
value: txRequest.value.toString(),
|
|
19269
|
+
chainId: opts.chainId
|
|
19270
|
+
});
|
|
19271
|
+
return;
|
|
19272
|
+
}
|
|
19273
|
+
console.log(`Sending ${opts.amount} native token to ${opts.to} on chain ${opts.chainId}...`);
|
|
19274
|
+
const sentTx = await signer.sendTransaction(txRequest);
|
|
19275
|
+
console.log(`Transaction hash: ${sentTx.hash}`);
|
|
19276
|
+
console.log("Waiting for confirmation...");
|
|
19277
|
+
const receipt = await sentTx.wait();
|
|
19278
|
+
console.log(`Transaction confirmed in block ${receipt?.blockNumber}`);
|
|
19279
|
+
console.log(`Gas used: ${receipt?.gasUsed.toString()}`);
|
|
19280
|
+
} catch (e) {
|
|
19281
|
+
console.error(`Error: ${e.message}`);
|
|
19282
|
+
process.exit(1);
|
|
19283
|
+
}
|
|
19284
|
+
});
|
|
19285
|
+
program2.command("transfer-token").description(`Send ERC20 tokens on the same chain
|
|
19286
|
+
|
|
19287
|
+
` + `This is a simple same-chain ERC20 transfer, NOT a cross-chain bridge operation.
|
|
19288
|
+
|
|
19289
|
+
` + `Examples:
|
|
19290
|
+
` + ` # Send 100 USDC on Ethereum (6 decimals)
|
|
19291
|
+
` + " xflows transfer-token --wallet alice --chain-id 1 \\\n" + " --token 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \\\n" + ` --to 0xRecipient --amount 100 --decimals 6
|
|
19292
|
+
|
|
19293
|
+
` + ` # Send 50 USDT on BSC (auto-detect decimals)
|
|
19294
|
+
` + " xflows transfer-token --wallet alice --chain-id 56 \\\n" + " --token 0x55d398326f99059fF775485246999027B3197955 \\\n" + " --to 0xRecipient --amount 50").requiredOption("--wallet <name>", "Wallet name to use for signing").requiredOption("--chain-id <chainId>", "Chain ID to send on").requiredOption("--token <address>", "ERC20 token contract address").requiredOption("--to <address>", "Recipient address").requiredOption("--amount <amount>", "Amount to send (human-readable, e.g., 100)").option("--decimals <decimals>", "Token decimals (auto-detected from contract if omitted)").option("--password <password>", "Password to decrypt encrypted wallet").option("--rpc <url>", "Custom RPC URL (overrides default)").option("--gas-limit <limit>", "Custom gas limit").option("--dry-run", "Only build the transaction, don't send it", false).action(async (opts) => {
|
|
19295
|
+
try {
|
|
19296
|
+
const wallet = loadWallet(opts.wallet, opts.password);
|
|
19297
|
+
const provider = opts.rpc ? new JsonRpcProvider(opts.rpc) : getProvider2(opts.chainId);
|
|
19298
|
+
const signer = wallet.connect(provider);
|
|
19299
|
+
const tokenContract = new Contract(opts.token, ERC20_ABI, signer);
|
|
19300
|
+
let decimals;
|
|
19301
|
+
if (opts.decimals !== undefined) {
|
|
19302
|
+
decimals = Number(opts.decimals);
|
|
19303
|
+
} else {
|
|
19304
|
+
try {
|
|
19305
|
+
decimals = Number(await tokenContract.decimals());
|
|
19306
|
+
console.log(`Token decimals: ${decimals}`);
|
|
19307
|
+
} catch {
|
|
19308
|
+
throw new Error("Could not auto-detect token decimals. Please provide --decimals manually.");
|
|
19309
|
+
}
|
|
19310
|
+
}
|
|
19311
|
+
let symbol = "TOKEN";
|
|
19312
|
+
try {
|
|
19313
|
+
symbol = await tokenContract.symbol();
|
|
19314
|
+
} catch {}
|
|
19315
|
+
const amount = parseUnits(opts.amount, decimals);
|
|
19316
|
+
const balance = await tokenContract.balanceOf(wallet.address);
|
|
19317
|
+
if (balance < amount) {
|
|
19318
|
+
console.error(`Insufficient ${symbol} balance: ${formatUnits(balance, decimals)} < ${opts.amount}`);
|
|
19319
|
+
process.exit(1);
|
|
19320
|
+
}
|
|
19321
|
+
if (opts.dryRun) {
|
|
19322
|
+
console.log("[Dry Run] Transaction details:");
|
|
19323
|
+
printJson({
|
|
19324
|
+
from: wallet.address,
|
|
19325
|
+
to: opts.to,
|
|
19326
|
+
token: opts.token,
|
|
19327
|
+
symbol,
|
|
19328
|
+
amount: opts.amount,
|
|
19329
|
+
amountWei: amount.toString(),
|
|
19330
|
+
decimals,
|
|
19331
|
+
chainId: opts.chainId
|
|
19332
|
+
});
|
|
19333
|
+
return;
|
|
19334
|
+
}
|
|
19335
|
+
console.log(`Sending ${opts.amount} ${symbol} to ${opts.to} on chain ${opts.chainId}...`);
|
|
19336
|
+
const txOverrides = {};
|
|
19337
|
+
if (opts.gasLimit) {
|
|
19338
|
+
txOverrides.gasLimit = BigInt(opts.gasLimit);
|
|
19339
|
+
}
|
|
19340
|
+
const isWanchain = opts.chainId === "888";
|
|
19341
|
+
if (isWanchain) {
|
|
19342
|
+
const feeData = await provider.getFeeData();
|
|
19343
|
+
const minBaseFee = parseUnits("1", "gwei");
|
|
19344
|
+
if (feeData.gasPrice && feeData.gasPrice < minBaseFee) {
|
|
19345
|
+
txOverrides.gasPrice = minBaseFee;
|
|
19346
|
+
console.log("Wanchain: enforcing minimum gasPrice of 1 gwei");
|
|
19347
|
+
} else if (feeData.maxFeePerGas) {
|
|
19348
|
+
const maxFee = feeData.maxFeePerGas < minBaseFee ? minBaseFee : feeData.maxFeePerGas;
|
|
19349
|
+
txOverrides.gasPrice = maxFee;
|
|
19350
|
+
console.log(`Wanchain: using gasPrice ${formatUnits(maxFee, "gwei")} gwei`);
|
|
19351
|
+
}
|
|
19352
|
+
}
|
|
19353
|
+
const sentTx = await tokenContract.transfer(opts.to, amount, txOverrides);
|
|
19354
|
+
console.log(`Transaction hash: ${sentTx.hash}`);
|
|
19355
|
+
console.log("Waiting for confirmation...");
|
|
19356
|
+
const receipt = await sentTx.wait();
|
|
19357
|
+
console.log(`Transaction confirmed in block ${receipt?.blockNumber}`);
|
|
19358
|
+
console.log(`Gas used: ${receipt?.gasUsed.toString()}`);
|
|
19359
|
+
} catch (e) {
|
|
19360
|
+
console.error(`Error: ${e.message}`);
|
|
19361
|
+
process.exit(1);
|
|
19362
|
+
}
|
|
19363
|
+
});
|
|
19184
19364
|
program2.command("status").description(`Check cross-chain transaction status
|
|
19185
19365
|
|
|
19186
19366
|
` + `Status codes:
|