@trustwallet/cli 0.6.9 → 0.6.11
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/dist/commands/alert.d.ts.map +1 -1
- package/dist/commands/erc20.d.ts.map +1 -1
- package/dist/commands/query.d.ts.map +1 -1
- package/dist/commands/swap.d.ts.map +1 -1
- package/dist/commands/wallet.d.ts.map +1 -1
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/index.js +410 -44
- package/package.json +12 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alert.d.ts","sourceRoot":"","sources":["../../src/commands/alert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"alert.d.ts","sourceRoot":"","sources":["../../src/commands/alert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoL3D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"erc20.d.ts","sourceRoot":"","sources":["../../src/commands/erc20.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"erc20.d.ts","sourceRoot":"","sources":["../../src/commands/erc20.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgL3D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/commands/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/commands/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAskB3D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../../src/commands/swap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"swap.d.ts","sourceRoot":"","sources":["../../src/commands/swap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkS1D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/commands/wallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/commands/wallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8tB5D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,cAAc,EAAwB,MAAM,YAAY,CAAC;AAEpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAoB,cAAc,EAAwB,MAAM,YAAY,CAAC;AAEpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAYnD,UAAU,WAAW;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,IAAI,cAAc,CAWjD;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC,CAiB3D;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,cAAc,CAAC,CAGzD;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC,CAQ3D;AAED,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,mBAAmB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAsB,eAAe,CAAC,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBnF"}
|
package/dist/index.js
CHANGED
|
@@ -6167,6 +6167,9 @@ function patchNodeStubs() {
|
|
|
6167
6167
|
parsed.pathname = `/naas/session/${_naasSessionId}${parsed.pathname}`;
|
|
6168
6168
|
resolvedUrl = parsed.toString();
|
|
6169
6169
|
}
|
|
6170
|
+
if (resolvedUrl.includes("aag") || resolvedUrl.includes("account-abstraction")) {
|
|
6171
|
+
console.error("[AAG]", init3?.method || "GET", resolvedUrl.slice(0, 200));
|
|
6172
|
+
}
|
|
6170
6173
|
if (resolvedUrl.includes("gateway.us.trustwallet.com")) {
|
|
6171
6174
|
resolvedUrl = resolvedUrl.replace("gateway.us.trustwallet.com", "tws.trustwallet.com");
|
|
6172
6175
|
}
|
|
@@ -6406,7 +6409,7 @@ function registerShutdownHandlers(providers, onBeforeExit) {
|
|
|
6406
6409
|
process.removeListener("SIGTERM", handler);
|
|
6407
6410
|
};
|
|
6408
6411
|
}
|
|
6409
|
-
var fs2, path2, import_trust_sdk, import_trust_sdk2, import_trust_sdk3, import_trust_sdk4, import_crypto2, __require2, polyfillsApplied, _credentials, _naasSessionId, nodeStubsPatched, NAAS_SESSION_RE, naasSessionPatched, coinTypeByValue, walletCore, initialized, BlockchainClient, WalletCoreSigner, domainsByCoinId, GATEWAY_URL, WALLET_ID_SUFFIX, WALLET_ID_LENGTH, EVM_COIN_IDS, MAINTAINED_COIN_IDS, WalletProvider, AgentWalletProvider, SHUTDOWN_TIMEOUT_MS;
|
|
6412
|
+
var fs2, path2, import_trust_sdk, import_trust_sdk2, import_trust_sdk3, import_trust_sdk4, import_crypto2, __require2, polyfillsApplied, _credentials, _naasSessionId, nodeStubsPatched, NAAS_SESSION_RE, naasSessionPatched, coinTypeByValue, walletCore, initialized, SPONSORED_RPC, BlockchainClient, WalletCoreSigner, domainsByCoinId, GATEWAY_URL, WALLET_ID_SUFFIX, WALLET_ID_LENGTH, EVM_COIN_IDS, MAINTAINED_COIN_IDS, WalletProvider, AgentWalletProvider, SHUTDOWN_TIMEOUT_MS;
|
|
6410
6413
|
var init_dist3 = __esm({
|
|
6411
6414
|
"../wallet-core/dist/index.mjs"() {
|
|
6412
6415
|
"use strict";
|
|
@@ -6436,7 +6439,11 @@ var init_dist3 = __esm({
|
|
|
6436
6439
|
coinTypeByValue = null;
|
|
6437
6440
|
walletCore = null;
|
|
6438
6441
|
initialized = false;
|
|
6439
|
-
|
|
6442
|
+
SPONSORED_RPC = {
|
|
6443
|
+
20000714: "https://bsc-sponsored.twnodes.com",
|
|
6444
|
+
60: "https://ethereum-sponsored.twnodes.com"
|
|
6445
|
+
};
|
|
6446
|
+
BlockchainClient = class _BlockchainClient {
|
|
6440
6447
|
signer;
|
|
6441
6448
|
constructor(signer) {
|
|
6442
6449
|
this.signer = signer;
|
|
@@ -6553,14 +6560,15 @@ var init_dist3 = __esm({
|
|
|
6553
6560
|
const asset = contractAddress ? new import_trust_sdk2.Asset.Token(account, contractAddress, tokenTypeForCoinId(coinId)) : new import_trust_sdk2.Asset.Coin(account);
|
|
6554
6561
|
const decimals = params.decimals !== void 0 ? params.decimals : contractAddress ? resolveToken(params.assetId, chainKey).decimals : getCoinDecimals(coinId);
|
|
6555
6562
|
const amountWei = humanAmountToWei(params.amount, decimals);
|
|
6556
|
-
|
|
6563
|
+
let transaction = new import_trust_sdk2.TransactionTransfer(
|
|
6557
6564
|
params.to,
|
|
6558
6565
|
asset,
|
|
6559
6566
|
amountWei.toString(),
|
|
6560
6567
|
false,
|
|
6561
6568
|
params.memo || null
|
|
6562
6569
|
);
|
|
6563
|
-
const fee = await
|
|
6570
|
+
const { fee, transaction7702 } = await this.calculateFeeWithSponsorship(transaction, account, coinId);
|
|
6571
|
+
if (transaction7702) transaction = transaction7702;
|
|
6564
6572
|
const nonce = await import_trust_sdk2.BlockchainService.fetchNonce(account);
|
|
6565
6573
|
let encodedTx;
|
|
6566
6574
|
try {
|
|
@@ -6584,7 +6592,7 @@ var init_dist3 = __esm({
|
|
|
6584
6592
|
}
|
|
6585
6593
|
}
|
|
6586
6594
|
}
|
|
6587
|
-
const hash = await
|
|
6595
|
+
const hash = await this.sendTransactionWithSponsorship(chain2, encodedTx, coinId);
|
|
6588
6596
|
return { hash, chainKey };
|
|
6589
6597
|
}
|
|
6590
6598
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -6602,13 +6610,14 @@ var init_dist3 = __esm({
|
|
|
6602
6610
|
const account = this.getAccountFromSigner(chainKey);
|
|
6603
6611
|
const asset = new import_trust_sdk2.Asset.Token(account, contractAddress, tokenTypeForCoinId(coinId));
|
|
6604
6612
|
const approveData = this.encodeApproveCalldata(params.spender, params.amount);
|
|
6605
|
-
|
|
6613
|
+
let transaction = new import_trust_sdk2.TransactionSmartContract(
|
|
6606
6614
|
asset,
|
|
6607
6615
|
contractAddress,
|
|
6608
6616
|
"0",
|
|
6609
6617
|
approveData
|
|
6610
6618
|
);
|
|
6611
|
-
const fee = await
|
|
6619
|
+
const { fee, transaction7702 } = await this.calculateFeeWithSponsorship(transaction, account, coinId);
|
|
6620
|
+
if (transaction7702) transaction = transaction7702;
|
|
6612
6621
|
const nonce = await import_trust_sdk2.BlockchainService.fetchNonce(account);
|
|
6613
6622
|
let encodedTx;
|
|
6614
6623
|
try {
|
|
@@ -6632,7 +6641,7 @@ var init_dist3 = __esm({
|
|
|
6632
6641
|
}
|
|
6633
6642
|
}
|
|
6634
6643
|
}
|
|
6635
|
-
const hash = await
|
|
6644
|
+
const hash = await this.sendTransactionWithSponsorship(chain2, encodedTx, coinId);
|
|
6636
6645
|
return { hash, chainKey };
|
|
6637
6646
|
}
|
|
6638
6647
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -6647,8 +6656,9 @@ var init_dist3 = __esm({
|
|
|
6647
6656
|
const account = this.getAccountFromSigner(chainKey);
|
|
6648
6657
|
const asset = new import_trust_sdk2.Asset.Coin(account);
|
|
6649
6658
|
const valueWei = params.value && params.value !== "0x0" && params.value !== "0x" ? BigInt(params.value).toString() : "0";
|
|
6650
|
-
|
|
6651
|
-
const fee = await
|
|
6659
|
+
let transaction = new import_trust_sdk2.TransactionSmartContract(asset, params.to, valueWei, params.data);
|
|
6660
|
+
const { fee, transaction7702 } = await this.calculateFeeWithSponsorship(transaction, account, coinId);
|
|
6661
|
+
if (transaction7702) transaction = transaction7702;
|
|
6652
6662
|
const nonce = await import_trust_sdk2.BlockchainService.fetchNonce(account);
|
|
6653
6663
|
let encodedTx;
|
|
6654
6664
|
try {
|
|
@@ -6667,7 +6677,7 @@ var init_dist3 = __esm({
|
|
|
6667
6677
|
}
|
|
6668
6678
|
}
|
|
6669
6679
|
}
|
|
6670
|
-
const hash = await
|
|
6680
|
+
const hash = await this.sendTransactionWithSponsorship(chain2, encodedTx, coinId);
|
|
6671
6681
|
return { hash, chainKey };
|
|
6672
6682
|
}
|
|
6673
6683
|
async getAllowance(params) {
|
|
@@ -6828,6 +6838,193 @@ var init_dist3 = __esm({
|
|
|
6828
6838
|
const chain2 = new import_trust_sdk2.DefinedChain(ct5);
|
|
6829
6839
|
await import_trust_sdk2.BlockchainService.setNode(chain2, new import_trust_sdk2.Node(rpcUrl));
|
|
6830
6840
|
}
|
|
6841
|
+
// EIP-7702 sponsorship-eligible chain coin IDs
|
|
6842
|
+
static SPONSORABLE_COINS = [60, 20000714];
|
|
6843
|
+
/**
|
|
6844
|
+
* Build the sponsored RPC URL with NaaS session if available.
|
|
6845
|
+
*/
|
|
6846
|
+
getSponsoredRpcUrl(coinId) {
|
|
6847
|
+
const base3 = SPONSORED_RPC[coinId];
|
|
6848
|
+
if (!base3) return void 0;
|
|
6849
|
+
const sessionId = process.env.TWAK_NAAS_SESSION_ID;
|
|
6850
|
+
return sessionId ? `${base3}/naas/session/${sessionId}/` : base3;
|
|
6851
|
+
}
|
|
6852
|
+
/**
|
|
6853
|
+
* Try sending via sponsored RPC first (checks pm_isSponsorable, then
|
|
6854
|
+
* eth_sendRawTransaction). Falls back to regular BlockchainService.
|
|
6855
|
+
*/
|
|
6856
|
+
async sendTransactionWithSponsorship(chain2, encodedTx, coinId) {
|
|
6857
|
+
const sponsoredUrl = this.getSponsoredRpcUrl(coinId);
|
|
6858
|
+
if (sponsoredUrl) {
|
|
6859
|
+
try {
|
|
6860
|
+
let rlpStart = 0;
|
|
6861
|
+
if (encodedTx[0] === 10) {
|
|
6862
|
+
let offset = 1;
|
|
6863
|
+
while (offset < encodedTx.length && (encodedTx[offset] & 128) !== 0) offset++;
|
|
6864
|
+
offset++;
|
|
6865
|
+
rlpStart = offset;
|
|
6866
|
+
}
|
|
6867
|
+
const rawRlp = "0x" + Array.from(encodedTx.slice(rlpStart)).map((b3) => b3.toString(16).padStart(2, "0")).join("");
|
|
6868
|
+
const resp = await fetch(sponsoredUrl, {
|
|
6869
|
+
method: "POST",
|
|
6870
|
+
headers: { "Content-Type": "application/json" },
|
|
6871
|
+
body: JSON.stringify({ id: 0, jsonrpc: "2.0", method: "eth_sendRawTransaction", params: [rawRlp] }),
|
|
6872
|
+
signal: AbortSignal.timeout(3e4)
|
|
6873
|
+
});
|
|
6874
|
+
const json = await resp.json();
|
|
6875
|
+
if (json.result) return json.result;
|
|
6876
|
+
} catch {
|
|
6877
|
+
}
|
|
6878
|
+
}
|
|
6879
|
+
return import_trust_sdk2.BlockchainService.sendTransactionV2(chain2, encodedTx);
|
|
6880
|
+
}
|
|
6881
|
+
// Known stablecoins to try as gas payment tokens when getSupportedTokens returns empty
|
|
6882
|
+
static FALLBACK_GAS_TOKENS = {
|
|
6883
|
+
20000714: [
|
|
6884
|
+
// BSC
|
|
6885
|
+
"0x55d398326f99059fF775485246999027B3197955",
|
|
6886
|
+
// USDT
|
|
6887
|
+
"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"
|
|
6888
|
+
// USDC
|
|
6889
|
+
],
|
|
6890
|
+
60: [
|
|
6891
|
+
// ETH
|
|
6892
|
+
"0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
6893
|
+
// USDT
|
|
6894
|
+
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
|
|
6895
|
+
// USDC
|
|
6896
|
+
]
|
|
6897
|
+
};
|
|
6898
|
+
/**
|
|
6899
|
+
* Find a token the wallet holds that can pay for gas on this chain.
|
|
6900
|
+
* Tries SmartWalletConfig.getSupportedTokens() first, then falls back
|
|
6901
|
+
* to known stablecoins (USDT/USDC).
|
|
6902
|
+
*/
|
|
6903
|
+
async findGasToken(account, coinId) {
|
|
6904
|
+
const ct5 = requireCoinType(coinId);
|
|
6905
|
+
const chain2 = new import_trust_sdk2.DefinedChain(ct5);
|
|
6906
|
+
const candidates = [];
|
|
6907
|
+
try {
|
|
6908
|
+
const supportedTokens = await import_trust_sdk2.SmartWalletConfig.getSupportedTokens(chain2);
|
|
6909
|
+
if (supportedTokens?.length) {
|
|
6910
|
+
for (const t of supportedTokens) {
|
|
6911
|
+
if (t.address) candidates.push(t.address);
|
|
6912
|
+
}
|
|
6913
|
+
}
|
|
6914
|
+
} catch {
|
|
6915
|
+
}
|
|
6916
|
+
const seen = new Set(candidates.map((a3) => a3.toLowerCase()));
|
|
6917
|
+
for (const addr of _BlockchainClient.FALLBACK_GAS_TOKENS[coinId] || []) {
|
|
6918
|
+
if (!seen.has(addr.toLowerCase())) candidates.push(addr);
|
|
6919
|
+
}
|
|
6920
|
+
if (candidates.length === 0) return void 0;
|
|
6921
|
+
const tokenAssets = candidates.map((addr) => new import_trust_sdk2.Asset.Token(account, addr, import_trust_sdk2.TokenType.Erc20));
|
|
6922
|
+
try {
|
|
6923
|
+
const balances = await import_trust_sdk2.BlockchainService.loadBalances(ct5, tokenAssets);
|
|
6924
|
+
for (let i2 = 0; i2 < balances.length; i2++) {
|
|
6925
|
+
const avail = balances[i2]?.balances?.find(
|
|
6926
|
+
(b3) => b3.type === import_trust_sdk2.BalanceType.Available
|
|
6927
|
+
);
|
|
6928
|
+
if (avail && BigInt(avail.amount || "0") > 0n) {
|
|
6929
|
+
return tokenAssets[i2];
|
|
6930
|
+
}
|
|
6931
|
+
}
|
|
6932
|
+
} catch {
|
|
6933
|
+
}
|
|
6934
|
+
return void 0;
|
|
6935
|
+
}
|
|
6936
|
+
/**
|
|
6937
|
+
* Calculate fee, falling back to EIP-7702 smart wallet sponsorship
|
|
6938
|
+
* when the wallet can't afford native gas (BSC/ETH only).
|
|
6939
|
+
*
|
|
6940
|
+
* Sets is7702=true and energy=tokenAsset on the transaction so the
|
|
6941
|
+
* Trust SDK routes through the Smart Wallet fee service internally.
|
|
6942
|
+
*/
|
|
6943
|
+
async calculateFeeWithSponsorship(transaction, account, coinId) {
|
|
6944
|
+
if (!_BlockchainClient.SPONSORABLE_COINS.includes(coinId)) {
|
|
6945
|
+
return { fee: await import_trust_sdk2.BlockchainService.calculateFee(transaction) };
|
|
6946
|
+
}
|
|
6947
|
+
let supports7702 = false;
|
|
6948
|
+
try {
|
|
6949
|
+
const ct5 = requireCoinType(coinId);
|
|
6950
|
+
supports7702 = await import_trust_sdk2.SmartWalletConfig.supports7702(ct5);
|
|
6951
|
+
} catch {
|
|
6952
|
+
}
|
|
6953
|
+
if (!supports7702) {
|
|
6954
|
+
return { fee: await import_trust_sdk2.BlockchainService.calculateFee(transaction) };
|
|
6955
|
+
}
|
|
6956
|
+
const fee = await import_trust_sdk2.BlockchainService.calculateFee(transaction);
|
|
6957
|
+
const feeAmount = BigInt(fee.amount || "0");
|
|
6958
|
+
if (feeAmount <= 0n) return { fee };
|
|
6959
|
+
let canAfford = true;
|
|
6960
|
+
try {
|
|
6961
|
+
const ct5 = requireCoinType(coinId);
|
|
6962
|
+
const energy = new import_trust_sdk2.Asset.Coin(account);
|
|
6963
|
+
const balanceResults = await import_trust_sdk2.BlockchainService.loadBalances(ct5, [energy]);
|
|
6964
|
+
const available = balanceResults[0]?.balances?.find(
|
|
6965
|
+
(b3) => b3.type === import_trust_sdk2.BalanceType.Available
|
|
6966
|
+
);
|
|
6967
|
+
const nativeBalance = BigInt(available?.amount || "0");
|
|
6968
|
+
canAfford = nativeBalance >= feeAmount;
|
|
6969
|
+
} catch {
|
|
6970
|
+
canAfford = false;
|
|
6971
|
+
}
|
|
6972
|
+
if (canAfford) return { fee };
|
|
6973
|
+
const nativeEnergy = new import_trust_sdk2.Asset.Coin(account);
|
|
6974
|
+
let tx7702 = transaction;
|
|
6975
|
+
if (transaction instanceof import_trust_sdk2.TransactionSmartContract) {
|
|
6976
|
+
tx7702 = transaction.copy(void 0, void 0, void 0, void 0, nativeEnergy, true);
|
|
6977
|
+
} else if (transaction instanceof import_trust_sdk2.TransactionTransfer) {
|
|
6978
|
+
tx7702 = transaction.copy(void 0, void 0, void 0, void 0, void 0, void 0, nativeEnergy, true);
|
|
6979
|
+
} else if (transaction instanceof import_trust_sdk2.TransactionTrade) {
|
|
6980
|
+
tx7702 = transaction.copy(void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, nativeEnergy, true);
|
|
6981
|
+
}
|
|
6982
|
+
let baseFee;
|
|
6983
|
+
try {
|
|
6984
|
+
baseFee = await import_trust_sdk2.BlockchainService.calculateFee(tx7702);
|
|
6985
|
+
process.stderr.write(`[7702] baseFee ok, amount:${baseFee.amount} type:${baseFee.constructor?.name}
|
|
6986
|
+
`);
|
|
6987
|
+
} catch (e2) {
|
|
6988
|
+
process.stderr.write(`[7702] baseFee FAILED: ${e2 instanceof Error ? e2.message : String(e2)}
|
|
6989
|
+
`);
|
|
6990
|
+
return { fee };
|
|
6991
|
+
}
|
|
6992
|
+
const userOpData = baseFee.data;
|
|
6993
|
+
if (!userOpData) {
|
|
6994
|
+
return { fee: baseFee, transaction7702: tx7702 };
|
|
6995
|
+
}
|
|
6996
|
+
const gasToken = await this.findGasToken(account, coinId);
|
|
6997
|
+
if (!gasToken) {
|
|
6998
|
+
return { fee: baseFee, transaction7702: tx7702 };
|
|
6999
|
+
}
|
|
7000
|
+
try {
|
|
7001
|
+
const int8Data = typeof userOpData === "string" ? new Int8Array(Buffer.from(userOpData.replace("0x", ""), "hex")) : new Int8Array(userOpData);
|
|
7002
|
+
const { EthereumAaService } = await import("@trustwallet-trust-sdk/trust-sdk");
|
|
7003
|
+
const paymasters = await EthereumAaService.getFeeQuotes(
|
|
7004
|
+
tx7702,
|
|
7005
|
+
nativeEnergy,
|
|
7006
|
+
int8Data,
|
|
7007
|
+
[gasToken]
|
|
7008
|
+
);
|
|
7009
|
+
if (paymasters && paymasters.length > 0) {
|
|
7010
|
+
const finalFee = await EthereumAaService.simulatePaymasterTransaction(
|
|
7011
|
+
tx7702,
|
|
7012
|
+
paymasters[0]
|
|
7013
|
+
);
|
|
7014
|
+
let txWithToken = transaction;
|
|
7015
|
+
if (transaction instanceof import_trust_sdk2.TransactionSmartContract) {
|
|
7016
|
+
txWithToken = transaction.copy(void 0, void 0, void 0, void 0, gasToken, true);
|
|
7017
|
+
} else if (transaction instanceof import_trust_sdk2.TransactionTransfer) {
|
|
7018
|
+
txWithToken = transaction.copy(void 0, void 0, void 0, void 0, void 0, void 0, gasToken, true);
|
|
7019
|
+
} else if (transaction instanceof import_trust_sdk2.TransactionTrade) {
|
|
7020
|
+
txWithToken = transaction.copy(void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, gasToken, true);
|
|
7021
|
+
}
|
|
7022
|
+
return { fee: finalFee, transaction7702: txWithToken };
|
|
7023
|
+
}
|
|
7024
|
+
} catch {
|
|
7025
|
+
}
|
|
7026
|
+
return { fee: baseFee, transaction7702: tx7702 };
|
|
7027
|
+
}
|
|
6831
7028
|
getAccountFromSigner(chainKey) {
|
|
6832
7029
|
if (!this.signer) {
|
|
6833
7030
|
throw new Error("BlockchainClient requires a signer for this operation");
|
|
@@ -12616,7 +12813,17 @@ var init_dist5 = __esm({
|
|
|
12616
12813
|
} catch (err) {
|
|
12617
12814
|
const msg = err instanceof Error ? err.message : String(err);
|
|
12618
12815
|
const details = err?.details;
|
|
12619
|
-
|
|
12816
|
+
let detailsStr = "";
|
|
12817
|
+
if (details != null) {
|
|
12818
|
+
try {
|
|
12819
|
+
detailsStr = JSON.stringify(details);
|
|
12820
|
+
} catch {
|
|
12821
|
+
try {
|
|
12822
|
+
detailsStr = String(details);
|
|
12823
|
+
} catch {
|
|
12824
|
+
}
|
|
12825
|
+
}
|
|
12826
|
+
}
|
|
12620
12827
|
if (msg.includes("GraphQL") || msg.includes("Failed to decode") || detailsStr.includes("GraphQL") || detailsStr.includes("Failed to decode")) {
|
|
12621
12828
|
return { valid: false, message: "Invalid address format" };
|
|
12622
12829
|
}
|
|
@@ -22167,6 +22374,12 @@ var import_chalk2 = __toESM(require_source());
|
|
|
22167
22374
|
init_dist2();
|
|
22168
22375
|
init_dist4();
|
|
22169
22376
|
init_dist();
|
|
22377
|
+
var EMBEDDED_NAAS_SESSION_ID = "NDVjMWRjY2MtYTYwNy00NGNhLWIxZGUtMmJiZDIyNmEyODQ4";
|
|
22378
|
+
function resolveNaasSessionId() {
|
|
22379
|
+
if (process.env.TWAK_NAAS_SESSION_ID) return process.env.TWAK_NAAS_SESSION_ID;
|
|
22380
|
+
if (EMBEDDED_NAAS_SESSION_ID && !EMBEDDED_NAAS_SESSION_ID.startsWith("__")) return EMBEDDED_NAAS_SESSION_ID;
|
|
22381
|
+
return void 0;
|
|
22382
|
+
}
|
|
22170
22383
|
async function getCredentials() {
|
|
22171
22384
|
const envAccessId = process.env.TWAK_ACCESS_ID;
|
|
22172
22385
|
const envSecret = process.env.TWAK_HMAC_SECRET;
|
|
@@ -22191,7 +22404,7 @@ async function ensureTrustSDK() {
|
|
|
22191
22404
|
await initTrustSDK({
|
|
22192
22405
|
accessId: creds.accessId,
|
|
22193
22406
|
hmacSecret: creds.hmacSecret,
|
|
22194
|
-
naasSessionId:
|
|
22407
|
+
naasSessionId: resolveNaasSessionId()
|
|
22195
22408
|
});
|
|
22196
22409
|
return creds;
|
|
22197
22410
|
}
|
|
@@ -38907,6 +39120,7 @@ ${qr3}`;
|
|
|
38907
39120
|
const result = {
|
|
38908
39121
|
agentWallet: exists ? "configured" : "not configured",
|
|
38909
39122
|
keychainPassword: keychainHasPassword ? "stored" : "not stored",
|
|
39123
|
+
chains: totalChains,
|
|
38910
39124
|
supportedChains: totalChains,
|
|
38911
39125
|
...createdAt ? { createdAt } : {},
|
|
38912
39126
|
...addressCount !== void 0 ? { addressCount } : {}
|
|
@@ -38940,6 +39154,18 @@ ${qr3}`;
|
|
|
38940
39154
|
return [{ chainKey, chain: chain2, address: addrEntry.address }];
|
|
38941
39155
|
});
|
|
38942
39156
|
const suppress = (fn2) => fn2();
|
|
39157
|
+
const pMap = async (items, fn2, concurrency) => {
|
|
39158
|
+
const results = new Array(items.length);
|
|
39159
|
+
let idx = 0;
|
|
39160
|
+
const run = async () => {
|
|
39161
|
+
while (idx < items.length) {
|
|
39162
|
+
const i2 = idx++;
|
|
39163
|
+
results[i2] = await fn2(items[i2]);
|
|
39164
|
+
}
|
|
39165
|
+
};
|
|
39166
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => run()));
|
|
39167
|
+
return results;
|
|
39168
|
+
};
|
|
38943
39169
|
const toHuman = (raw, decimals) => {
|
|
38944
39170
|
const big = BigInt(raw);
|
|
38945
39171
|
const div = 10n ** BigInt(decimals);
|
|
@@ -38950,14 +39176,14 @@ ${qr3}`;
|
|
|
38950
39176
|
};
|
|
38951
39177
|
const holdingsAssets = chainEntries.map(({ chain: chain2, address }) => ({ coin: chain2.coinId, address }));
|
|
38952
39178
|
const [nativeResults, holdings] = await Promise.all([
|
|
38953
|
-
|
|
39179
|
+
pMap(chainEntries, async ({ chainKey, chain: chain2, address }) => {
|
|
38954
39180
|
try {
|
|
38955
39181
|
const balance = await suppress(() => blockchainClient.getBalance(`c${chain2.coinId}`, address));
|
|
38956
39182
|
return { chainKey, chain: chain2, address, balance };
|
|
38957
39183
|
} catch {
|
|
38958
39184
|
return { chainKey, chain: chain2, address, balance: null };
|
|
38959
39185
|
}
|
|
38960
|
-
})
|
|
39186
|
+
}, 5),
|
|
38961
39187
|
(async () => {
|
|
38962
39188
|
try {
|
|
38963
39189
|
return await new SecurityService2(httpClient).getTokenHoldings(holdingsAssets);
|
|
@@ -38988,7 +39214,7 @@ ${qr3}`;
|
|
|
38988
39214
|
if (t.contract) tokenJobs.push({ chainKey, coinId: chain2.coinId, address, ...t });
|
|
38989
39215
|
}
|
|
38990
39216
|
}
|
|
38991
|
-
const tokenBalances = await
|
|
39217
|
+
const tokenBalances = await pMap(tokenJobs, async (job) => {
|
|
38992
39218
|
const fallback = job.balance ?? "0";
|
|
38993
39219
|
try {
|
|
38994
39220
|
const assetId = `c${job.coinId}_t${job.contract}`;
|
|
@@ -38997,7 +39223,7 @@ ${qr3}`;
|
|
|
38997
39223
|
} catch {
|
|
38998
39224
|
return { ...job, rawBalance: fallback };
|
|
38999
39225
|
}
|
|
39000
|
-
})
|
|
39226
|
+
}, 5);
|
|
39001
39227
|
const nativeAssetIds = nativeResults.map(({ chain: chain2 }) => `c${chain2.coinId}`);
|
|
39002
39228
|
const nonZeroTokens = tokenBalances.filter((t) => {
|
|
39003
39229
|
const dec = t.decimals ?? 18;
|
|
@@ -39502,6 +39728,55 @@ function registerSwapCommand(program3) {
|
|
|
39502
39728
|
const transactions = await swapClient.getSwapTransactions(route);
|
|
39503
39729
|
let txHash = "";
|
|
39504
39730
|
const blockchainClient = provider.getBlockchainClient();
|
|
39731
|
+
const hasApprovalTx = transactions.some((t) => t.transaction.type === "approval");
|
|
39732
|
+
if (!hasApprovalTx && chainConfig?.isEVM) {
|
|
39733
|
+
const stepApproval = firstStep.approval;
|
|
39734
|
+
if (stepApproval && stepApproval.operatorAddress) {
|
|
39735
|
+
const fromAssetAddr = firstStep.from.asset.address;
|
|
39736
|
+
const isNative = !fromAssetAddr || fromAssetAddr === NATIVE_TOKEN_ADDRESS;
|
|
39737
|
+
if (!isNative && chainConfig.coinId) {
|
|
39738
|
+
const assetId = formatTokenId(chainConfig.coinId, fromAssetAddr);
|
|
39739
|
+
try {
|
|
39740
|
+
const allowance = await blockchainClient.getAllowance({
|
|
39741
|
+
assetId,
|
|
39742
|
+
owner: walletAddress,
|
|
39743
|
+
spender: stepApproval.operatorAddress
|
|
39744
|
+
});
|
|
39745
|
+
const requiredAmount = BigInt(stepApproval.minAmount || parsedAmount);
|
|
39746
|
+
if (allowance < requiredAmount) {
|
|
39747
|
+
info("Sending token approval...");
|
|
39748
|
+
const hdWallet = provider.getSigner().getHDWallet();
|
|
39749
|
+
const approveResult = await blockchainClient.approve({
|
|
39750
|
+
assetId,
|
|
39751
|
+
spender: stepApproval.operatorAddress,
|
|
39752
|
+
amount: requiredAmount.toString(),
|
|
39753
|
+
hdWallet
|
|
39754
|
+
});
|
|
39755
|
+
info(`Approval tx: ${getExplorerTxUrl(fromChain, approveResult.hash)}`);
|
|
39756
|
+
const approvalDeadline = Date.now() + 6e4;
|
|
39757
|
+
while (Date.now() < approvalDeadline) {
|
|
39758
|
+
await new Promise((r3) => setTimeout(r3, 2e3));
|
|
39759
|
+
try {
|
|
39760
|
+
const status = await blockchainClient.findTransactionStatus(fromChain, walletAddress, approveResult.hash);
|
|
39761
|
+
if (status.confirmed) break;
|
|
39762
|
+
if (status.failed) throw new Error("Approval transaction failed");
|
|
39763
|
+
} catch (e2) {
|
|
39764
|
+
const err = e2 instanceof Error ? e2 : new Error(String(e2));
|
|
39765
|
+
if (err.message.startsWith("Approval transaction failed")) throw err;
|
|
39766
|
+
}
|
|
39767
|
+
}
|
|
39768
|
+
}
|
|
39769
|
+
} catch (e2) {
|
|
39770
|
+
const msg = e2 instanceof Error ? e2.message : String(e2);
|
|
39771
|
+
if (msg.includes("insufficient funds")) {
|
|
39772
|
+
throw new Error(`Insufficient ${chainConfig?.symbol || "native token"} for approval gas. Fund your wallet with ${chainConfig?.symbol || "native tokens"} first.`);
|
|
39773
|
+
}
|
|
39774
|
+
if (msg.includes("failed")) throw e2;
|
|
39775
|
+
info(`Warning: could not check/send approval: ${msg}`);
|
|
39776
|
+
}
|
|
39777
|
+
}
|
|
39778
|
+
}
|
|
39779
|
+
}
|
|
39505
39780
|
const pollForConfirmation = async (hash, timeoutMs) => {
|
|
39506
39781
|
const deadline = Date.now() + timeoutMs;
|
|
39507
39782
|
while (Date.now() < deadline) {
|
|
@@ -39574,10 +39849,11 @@ init_dist2();
|
|
|
39574
39849
|
init_dist4();
|
|
39575
39850
|
function registerErc20Command(program3) {
|
|
39576
39851
|
const erc20 = program3.command("erc20").description("ERC-20 token operations");
|
|
39577
|
-
erc20.command("approve").description("Approve a spender for token spending").requiredOption("--token <assetId>", "Token asset ID (e.g., c60_t0xA0b8...)").requiredOption("--spender <address>", "Spender address").requiredOption("--amount <n>", 'Amount to approve (in smallest unit, or "unlimited")').
|
|
39852
|
+
erc20.command("approve").description("Approve a spender for token spending").requiredOption("--token <assetId>", "Token asset ID (e.g., c60_t0xA0b8...)").requiredOption("--spender <address>", "Spender address").requiredOption("--amount <n>", 'Amount to approve (in smallest unit, or "unlimited")').option("--password <password>", "Wallet password (falls back to keychain / TWAK_WALLET_PASSWORD)").option("--confirm-unlimited", "Required when --amount unlimited to acknowledge the security risk").option("--json", "JSON output").action(async (opts) => {
|
|
39578
39853
|
try {
|
|
39579
39854
|
await ensureTrustSDK();
|
|
39580
|
-
const
|
|
39855
|
+
const password = await resolvePassword(opts);
|
|
39856
|
+
const provider = await AgentWalletProvider.fromStorage(password);
|
|
39581
39857
|
const { coinId, contractAddress } = parseTokenId(opts.token);
|
|
39582
39858
|
if (!contractAddress) {
|
|
39583
39859
|
const msg = "Cannot approve native tokens. Provide an ERC-20 asset ID (e.g., c60_t0xA0b8...)";
|
|
@@ -39637,10 +39913,11 @@ function registerErc20Command(program3) {
|
|
|
39637
39913
|
}
|
|
39638
39914
|
process.exit();
|
|
39639
39915
|
});
|
|
39640
|
-
erc20.command("revoke").description("Revoke token approval (set allowance to 0)").requiredOption("--token <assetId>", "Token asset ID (e.g., c60_t0xA0b8...)").requiredOption("--spender <address>", "Spender address to revoke").
|
|
39916
|
+
erc20.command("revoke").description("Revoke token approval (set allowance to 0)").requiredOption("--token <assetId>", "Token asset ID (e.g., c60_t0xA0b8...)").requiredOption("--spender <address>", "Spender address to revoke").option("--password <password>", "Wallet password (falls back to keychain / TWAK_WALLET_PASSWORD)").option("--json", "JSON output").action(async (opts) => {
|
|
39641
39917
|
try {
|
|
39642
39918
|
await ensureTrustSDK();
|
|
39643
|
-
const
|
|
39919
|
+
const password = await resolvePassword(opts);
|
|
39920
|
+
const provider = await AgentWalletProvider.fromStorage(password);
|
|
39644
39921
|
const { coinId, contractAddress } = parseTokenId(opts.token);
|
|
39645
39922
|
if (!contractAddress) {
|
|
39646
39923
|
const msg = "Cannot revoke approval for native tokens. Provide an ERC-20 asset ID.";
|
|
@@ -39728,7 +40005,7 @@ function resolveTokenLabel(tokenId) {
|
|
|
39728
40005
|
function registerAlertCommand(program3) {
|
|
39729
40006
|
const alert = program3.command("alert").description("Manage price alerts");
|
|
39730
40007
|
const alertStore = new AlertStore();
|
|
39731
|
-
alert.command("create").description("Create a price alert").requiredOption("--token <tokenId>", "Token
|
|
40008
|
+
alert.command("create").description("Create a price alert").requiredOption("--token <tokenId>", "Token symbol (e.g., ETH, BTC) or asset ID (e.g., c60)").option("--chain <key>", "Chain key (auto-detected for native tokens like ETH, BNB, SOL)").option("--above <price>", "Alert when price goes above").option("--below <price>", "Alert when price goes below").option("--json", "JSON output").action(async (opts) => {
|
|
39732
40009
|
const aboveProvided = typeof opts.above !== "undefined";
|
|
39733
40010
|
const belowProvided = typeof opts.below !== "undefined";
|
|
39734
40011
|
if (aboveProvided && belowProvided || !aboveProvided && !belowProvided) {
|
|
@@ -39745,23 +40022,73 @@ function registerAlertCommand(program3) {
|
|
|
39745
40022
|
process.exitCode = 1;
|
|
39746
40023
|
return;
|
|
39747
40024
|
}
|
|
39748
|
-
|
|
39749
|
-
|
|
39750
|
-
if (opts.json) output({ error: `Unknown chain: ${opts.chain}` }, true);
|
|
39751
|
-
process.exitCode = 1;
|
|
39752
|
-
return;
|
|
39753
|
-
}
|
|
40025
|
+
let resolvedTokenId = opts.token;
|
|
40026
|
+
let resolvedChain = opts.chain;
|
|
39754
40027
|
try {
|
|
39755
40028
|
parseTokenId(opts.token);
|
|
40029
|
+
if (!resolvedChain) {
|
|
40030
|
+
resolvedChain = tokenIdToChain(opts.token);
|
|
40031
|
+
if (!resolvedChain) {
|
|
40032
|
+
error("Could not detect chain from asset ID. Provide --chain.");
|
|
40033
|
+
if (opts.json) output({ error: "Chain required for this asset ID" }, true);
|
|
40034
|
+
process.exitCode = 1;
|
|
40035
|
+
return;
|
|
40036
|
+
}
|
|
40037
|
+
}
|
|
39756
40038
|
} catch {
|
|
39757
|
-
|
|
39758
|
-
|
|
40039
|
+
const sym = opts.token.toUpperCase();
|
|
40040
|
+
const NATIVE_SYMBOLS2 = {
|
|
40041
|
+
ETH: "ethereum",
|
|
40042
|
+
BNB: "bsc",
|
|
40043
|
+
SOL: "solana",
|
|
40044
|
+
BTC: "bitcoin",
|
|
40045
|
+
MATIC: "polygon",
|
|
40046
|
+
AVAX: "avalanche",
|
|
40047
|
+
FTM: "fantom",
|
|
40048
|
+
TRX: "tron",
|
|
40049
|
+
DOT: "polkadot",
|
|
40050
|
+
ATOM: "cosmos",
|
|
40051
|
+
NEAR: "near",
|
|
40052
|
+
APT: "aptos",
|
|
40053
|
+
TON: "ton",
|
|
40054
|
+
SUI: "sui",
|
|
40055
|
+
LTC: "litecoin",
|
|
40056
|
+
DOGE: "dogecoin",
|
|
40057
|
+
CELO: "celo",
|
|
40058
|
+
S: "sonic"
|
|
40059
|
+
};
|
|
40060
|
+
if (!resolvedChain && NATIVE_SYMBOLS2[sym]) {
|
|
40061
|
+
resolvedChain = NATIVE_SYMBOLS2[sym];
|
|
40062
|
+
}
|
|
40063
|
+
if (!resolvedChain) {
|
|
40064
|
+
error(`Cannot resolve "${opts.token}" without --chain. Provide --chain or use asset ID format (c60).`);
|
|
40065
|
+
if (opts.json) output({ error: "Chain required" }, true);
|
|
40066
|
+
process.exitCode = 1;
|
|
40067
|
+
return;
|
|
40068
|
+
}
|
|
40069
|
+
const chain2 = getChainById(resolvedChain);
|
|
40070
|
+
if (!chain2) {
|
|
40071
|
+
error(`Unknown chain: ${resolvedChain}. Run \`twak chains\` to see supported chains.`);
|
|
40072
|
+
if (opts.json) output({ error: `Unknown chain: ${resolvedChain}` }, true);
|
|
40073
|
+
process.exitCode = 1;
|
|
40074
|
+
return;
|
|
40075
|
+
}
|
|
40076
|
+
const resolved = resolveToken(sym, resolvedChain);
|
|
40077
|
+
if (resolved.address === NATIVE_TOKEN_ADDRESS || resolved.address === sym) {
|
|
40078
|
+
resolvedTokenId = formatTokenId(chain2.coinId);
|
|
40079
|
+
} else {
|
|
40080
|
+
resolvedTokenId = formatTokenId(chain2.coinId, resolved.address);
|
|
40081
|
+
}
|
|
40082
|
+
}
|
|
40083
|
+
if (!isChainSupported(resolvedChain)) {
|
|
40084
|
+
error(`Unknown chain: ${resolvedChain}. Run \`twak chains\` to see supported chains.`);
|
|
40085
|
+
if (opts.json) output({ error: `Unknown chain: ${resolvedChain}` }, true);
|
|
39759
40086
|
process.exitCode = 1;
|
|
39760
40087
|
return;
|
|
39761
40088
|
}
|
|
39762
40089
|
const record2 = await alertStore.create({
|
|
39763
|
-
tokenId:
|
|
39764
|
-
chainKey:
|
|
40090
|
+
tokenId: resolvedTokenId,
|
|
40091
|
+
chainKey: resolvedChain,
|
|
39765
40092
|
condition,
|
|
39766
40093
|
targetPrice
|
|
39767
40094
|
});
|
|
@@ -39902,7 +40229,7 @@ function handleError(err, json) {
|
|
|
39902
40229
|
process.exitCode = 1;
|
|
39903
40230
|
}
|
|
39904
40231
|
function registerQueryCommand(program3) {
|
|
39905
|
-
program3.command("price <token>").description("Get token price").option("--chain <id>", "Chain").option("--history
|
|
40232
|
+
program3.command("price <token>").description("Get token price").option("--chain <id>", "Chain").option("--history [period]", "Price history period: hour, day, week, month, year, all (default: week)").option("--json", "JSON output").action(async (token, opts) => {
|
|
39906
40233
|
try {
|
|
39907
40234
|
const client = await getClient();
|
|
39908
40235
|
const swapClient = new SwapClient(client);
|
|
@@ -39968,7 +40295,8 @@ function registerQueryCommand(program3) {
|
|
|
39968
40295
|
process.exitCode = 1;
|
|
39969
40296
|
return;
|
|
39970
40297
|
}
|
|
39971
|
-
if (opts.history) {
|
|
40298
|
+
if (opts.history !== void 0) {
|
|
40299
|
+
const period = typeof opts.history === "string" ? opts.history : "week";
|
|
39972
40300
|
const chainInfo = getChainById(chain2);
|
|
39973
40301
|
if (!chainInfo) throw new Error(`Unknown chain: ${chain2}`);
|
|
39974
40302
|
const isNative = !tokenInfo.address || tokenInfo.address === NATIVE_TOKEN_ADDRESS || tokenInfo.address === SOLANA_NATIVE_ADDRESS;
|
|
@@ -39977,7 +40305,7 @@ function registerQueryCommand(program3) {
|
|
|
39977
40305
|
"GET",
|
|
39978
40306
|
`/v1/market/charts/${assetId}`,
|
|
39979
40307
|
void 0,
|
|
39980
|
-
`currency=USD&period=${
|
|
40308
|
+
`currency=USD&period=${period}`
|
|
39981
40309
|
);
|
|
39982
40310
|
output({ token: token.toUpperCase(), chain: chain2, priceUsd: price, history: chartData.prices }, opts.json);
|
|
39983
40311
|
return;
|
|
@@ -39992,14 +40320,24 @@ function registerQueryCommand(program3) {
|
|
|
39992
40320
|
handleError(err, opts.json);
|
|
39993
40321
|
}
|
|
39994
40322
|
});
|
|
39995
|
-
program3.command("search <query>").description("Search for tokens").option("--networks <
|
|
40323
|
+
program3.command("search <query>").description("Search for tokens").option("--networks <names>", "Comma-separated chain names or coin IDs (e.g., ethereum,bsc)").option("--limit <n>", "Max results", "10").option("--json", "JSON output").action(async (query, opts) => {
|
|
39996
40324
|
try {
|
|
39997
40325
|
const client = await getClient();
|
|
39998
40326
|
const swapClient = new SwapClient(client);
|
|
40327
|
+
let networks;
|
|
40328
|
+
if (opts.networks) {
|
|
40329
|
+
networks = opts.networks.split(",").map((n4) => {
|
|
40330
|
+
const trimmed = n4.trim();
|
|
40331
|
+
if (/^\d+$/.test(trimmed)) return trimmed;
|
|
40332
|
+
const chain2 = getChainById(trimmed);
|
|
40333
|
+
if (chain2) return String(chain2.coinId);
|
|
40334
|
+
throw new Error(`Unknown network "${trimmed}". Use a supported chain name or numeric coin ID.`);
|
|
40335
|
+
}).join(",");
|
|
40336
|
+
}
|
|
39999
40337
|
const result = await swapClient.searchTokens({
|
|
40000
40338
|
query,
|
|
40001
40339
|
limit: parseInt(opts.limit, 10),
|
|
40002
|
-
...
|
|
40340
|
+
...networks ? { networks } : {}
|
|
40003
40341
|
});
|
|
40004
40342
|
output(result, opts.json);
|
|
40005
40343
|
} catch (err) {
|
|
@@ -40126,9 +40464,19 @@ function registerQueryCommand(program3) {
|
|
|
40126
40464
|
}
|
|
40127
40465
|
}
|
|
40128
40466
|
});
|
|
40129
|
-
program3.command("balance").description("Get
|
|
40467
|
+
program3.command("balance").description("Get token balance for an address (native or ERC-20)").requiredOption("--address <address>", "Wallet address").option("--coin <coinId>", "SLIP44 coin ID (for native token)").option("--chain <key>", "Chain key (e.g., ethereum, bsc)").option("--token <address>", "Token contract address (for ERC-20)").option("--json", "JSON output").action(async (opts) => {
|
|
40130
40468
|
try {
|
|
40131
|
-
|
|
40469
|
+
let coinId;
|
|
40470
|
+
if (opts.coin) {
|
|
40471
|
+
coinId = Number(opts.coin);
|
|
40472
|
+
if (!Number.isInteger(coinId)) throw new Error(`Invalid coin ID: ${opts.coin}`);
|
|
40473
|
+
} else if (opts.chain) {
|
|
40474
|
+
const chainInfo = getChainById(opts.chain);
|
|
40475
|
+
if (!chainInfo) throw new Error(`Unknown chain: ${opts.chain}`);
|
|
40476
|
+
coinId = chainInfo.coinId;
|
|
40477
|
+
} else {
|
|
40478
|
+
throw new Error("Provide --coin or --chain");
|
|
40479
|
+
}
|
|
40132
40480
|
const chain2 = getChainByCoinId(coinId);
|
|
40133
40481
|
if (!chain2) throw new Error(`Unknown coin ID: ${coinId}`);
|
|
40134
40482
|
try {
|
|
@@ -40142,17 +40490,35 @@ function registerQueryCommand(program3) {
|
|
|
40142
40490
|
} catch (err) {
|
|
40143
40491
|
if (err instanceof Error && err.message.startsWith("Invalid address")) throw err;
|
|
40144
40492
|
}
|
|
40493
|
+
const assetId = opts.token ? `c${coinId}_t${opts.token}` : `c${coinId}`;
|
|
40145
40494
|
const client = new BlockchainClient();
|
|
40146
|
-
const balance = await client.getBalance(
|
|
40495
|
+
const balance = await client.getBalance(assetId, opts.address);
|
|
40496
|
+
let decimals = chain2.decimals;
|
|
40497
|
+
let symbol = chain2.symbol;
|
|
40498
|
+
if (opts.token) {
|
|
40499
|
+
const apiClient = await getClient();
|
|
40500
|
+
const swapClient = new SwapClient(apiClient);
|
|
40501
|
+
const chainKey = opts.chain || Object.entries(CHAINS).find(([, c3]) => c3.coinId === coinId)?.[0] || "";
|
|
40502
|
+
const tokens = await swapClient.searchTokens({ query: opts.token, chains: [chainKey], limit: 1 });
|
|
40503
|
+
if (tokens.length > 0) {
|
|
40504
|
+
decimals = tokens[0].decimals ?? 18;
|
|
40505
|
+
symbol = tokens[0].symbol ?? opts.token;
|
|
40506
|
+
} else {
|
|
40507
|
+
decimals = 18;
|
|
40508
|
+
symbol = opts.token;
|
|
40509
|
+
}
|
|
40510
|
+
}
|
|
40147
40511
|
const fmt = (raw) => {
|
|
40148
40512
|
const big = BigInt(raw);
|
|
40149
|
-
|
|
40150
|
-
|
|
40513
|
+
if (decimals === 0) return big.toString();
|
|
40514
|
+
const div = 10n ** BigInt(decimals);
|
|
40515
|
+
return `${big / div}.${(big % div).toString().padStart(decimals, "0").slice(0, 6)}`;
|
|
40151
40516
|
};
|
|
40152
40517
|
output({
|
|
40153
40518
|
address: opts.address,
|
|
40154
40519
|
chain: chain2.id,
|
|
40155
|
-
symbol
|
|
40520
|
+
symbol,
|
|
40521
|
+
...opts.token ? { token: opts.token } : {},
|
|
40156
40522
|
available: fmt(balance.available),
|
|
40157
40523
|
...balance.staked ? { staked: fmt(balance.staked) } : {},
|
|
40158
40524
|
...balance.pending ? { pending: fmt(balance.pending) } : {},
|
|
@@ -54352,7 +54718,7 @@ var crypto5 = __toESM(require("crypto"));
|
|
|
54352
54718
|
// package.json
|
|
54353
54719
|
var package_default = {
|
|
54354
54720
|
name: "@trustwallet/cli",
|
|
54355
|
-
version: "0.6.
|
|
54721
|
+
version: "0.6.11",
|
|
54356
54722
|
description: "TWAK CLI \u2014 command-line interface for Trust Wallet Agent Kit",
|
|
54357
54723
|
main: "dist/index.js",
|
|
54358
54724
|
types: "dist/index.d.ts",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trustwallet/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.11",
|
|
4
4
|
"description": "TWAK CLI — command-line interface for Trust Wallet Agent Kit",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -27,17 +27,17 @@
|
|
|
27
27
|
"ora": "5.4.1",
|
|
28
28
|
"tsup": "8.5.1",
|
|
29
29
|
"typescript": "5.7.3",
|
|
30
|
-
"@twak/
|
|
31
|
-
"@twak/
|
|
32
|
-
"@twak/
|
|
33
|
-
"@twak/
|
|
34
|
-
"@twak/
|
|
35
|
-
"@twak/
|
|
36
|
-
"@twak/transactions": "0.6.
|
|
37
|
-
"@twak/wallet": "0.6.
|
|
38
|
-
"@twak/
|
|
39
|
-
"@twak/
|
|
40
|
-
"@twak/
|
|
30
|
+
"@twak/core": "0.6.11",
|
|
31
|
+
"@twak/mcp": "0.6.11",
|
|
32
|
+
"@twak/security": "0.6.11",
|
|
33
|
+
"@twak/storage": "0.6.11",
|
|
34
|
+
"@twak/actions": "0.6.11",
|
|
35
|
+
"@twak/swap": "0.6.11",
|
|
36
|
+
"@twak/transactions": "0.6.11",
|
|
37
|
+
"@twak/wallet": "0.6.11",
|
|
38
|
+
"@twak/wallet-core": "0.6.11",
|
|
39
|
+
"@twak/blockchain": "0.6.11",
|
|
40
|
+
"@twak/walletconnect": "0.6.11"
|
|
41
41
|
},
|
|
42
42
|
"publishConfig": {
|
|
43
43
|
"access": "public"
|