比较提交

..

3 次代码提交

作者 SHA1 备注 提交日期
user
1df770d3b6 fix: prevent double symbol display on swap tx broadcast/status views
所有检查均成功
check / check (push) Successful in 22s
For Uniswap swaps, the decoded Amount value includes the token symbol
(e.g. '2.0000 USDT'). The tx status view then appended 'ETH' because
pendingTxDetails.token remained 'ETH' (router address is not a token).

Fix:
- Add rawValue (numeric-only) to uniswap decoder's Amount detail
- Extract Token In address from decoded details in approval.js to set
  the correct token/tokenSymbol on pendingTxDetails for swaps
- The existing d.rawValue || d.value pattern now picks up the clean
  numeric value, and symbol comes from tokenSymbol
2026-02-28 11:30:44 -08:00
clawbot
607d2349b0 fix: prevent double symbol display on tx broadcast status views
所有检查均成功
check / check (push) Successful in 22s
The decodeCalldata function in approval.js was embedding the token symbol
into the Amount value string (e.g. '2.0000 USDT'). This value was then
assigned to pendingTxDetails.amount, and txStatus.js would append the
symbol again, producing '2.0000 USDT ETH' (or '2.0000 USDT USDT' when
the token was in TOKEN_BY_ADDRESS).

Fix: decodeCalldata now provides a rawValue field (numeric only) on
Amount details. pendingTxDetails.amount uses rawValue when available,
so txStatus.js can append the correct symbol exactly once.

Affected paths:
- approve() decoded amount (approve calldata)
- transfer() decoded amount (transfer calldata)
- pendingTxDetails.amount assignment

Audited all other amount+symbol display sites:
- txStatus.js showWait/showSuccess/showError: correctly derive symbol
  from txInfo.token, no duplication
- confirmTx.js show(): builds symbol independently, amount is raw — OK
- send.js: amount is raw user input — OK
- addressToken.js: uses balanceLine helper — OK
- transactions.js parseTx/parseTokenTransfer: separate value/symbol — OK

Fixes #59
2026-02-28 11:27:26 -08:00
clawbot
3c2d553070 test: add V4 swap ERC20→ERC20 decoder regression test
所有检查均成功
check / check (push) Successful in 37s
Adds a test that constructs a Uniswap V4 USDT→USDC swap using
SETTLE/SWAP_EXACT_IN_SINGLE/TAKE sub-actions inside a V4_SWAP command.
Without decodeV4Swap(), the output token would be unresolvable and the
swap name would not show 'USDT → USDC'. This test fails on the old code
and passes with the decodeV4Swap() fix.

Refs: #59
2026-02-28 11:22:14 -08:00
修改 4 个文件,包含 42 行新增6186 行删除

1
.gitignore vendored
查看文件

@@ -25,3 +25,4 @@ dist/
# Yarn
.yarn-integrity
package-lock.json

6175
package-lock.json 自动生成的

文件差异内容过多而无法显示 加载差异

查看文件

@@ -78,10 +78,12 @@ function decodeCalldata(data, toAddress) {
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
const isUnlimited = rawAmount === maxUint;
const amountRaw = isUnlimited
? "Unlimited"
: formatTxValue(formatUnits(rawAmount, tokenDecimals));
const amountStr = isUnlimited
? "Unlimited"
: formatTxValue(formatUnits(rawAmount, tokenDecimals)) +
(tokenSymbol ? " " + tokenSymbol : "");
: amountRaw + (tokenSymbol ? " " + tokenSymbol : "");
return {
name: "Token Approval",
@@ -100,7 +102,11 @@ function decodeCalldata(data, toAddress) {
value: spender,
address: spender,
},
{ label: "Amount", value: amountStr },
{
label: "Amount",
value: amountStr,
rawValue: amountRaw,
},
],
};
}
@@ -108,9 +114,11 @@ function decodeCalldata(data, toAddress) {
if (parsed.name === "transfer") {
const to = parsed.args[0];
const rawAmount = parsed.args[1];
const amountRaw = formatTxValue(
formatUnits(rawAmount, tokenDecimals),
);
const amountStr =
formatTxValue(formatUnits(rawAmount, tokenDecimals)) +
(tokenSymbol ? " " + tokenSymbol : "");
amountRaw + (tokenSymbol ? " " + tokenSymbol : "");
return {
name: "Token Transfer",
@@ -125,7 +133,11 @@ function decodeCalldata(data, toAddress) {
isToken: true,
},
{ label: "Recipient", value: to, address: to },
{ label: "Amount", value: amountStr },
{
label: "Amount",
value: amountStr,
rawValue: amountRaw,
},
],
};
}
@@ -155,20 +167,31 @@ function showTxApproval(details) {
tokenSymbol: token ? token.symbol : null,
};
// If this is an ERC-20 call, try to extract the real recipient and amount
// If this is an ERC-20 call or a swap, extract the real recipient, amount, and token info
const decoded = decodeCalldata(details.txParams.data, toAddr || "");
if (decoded && decoded.details) {
let decodedTokenSymbol = null;
let decodedTokenAddress = null;
for (const d of decoded.details) {
if (d.label === "Recipient" && d.address) {
pendingTxDetails.to = d.address;
}
if (d.label === "Amount") {
pendingTxDetails.amount = d.value;
pendingTxDetails.amount = d.rawValue || d.value;
}
if (d.label === "Token In" && !decodedTokenSymbol) {
// Extract token symbol and address from decoded details
decodedTokenSymbol = d.value;
if (d.address) decodedTokenAddress = d.address;
}
}
if (token) {
pendingTxDetails.token = toAddr;
pendingTxDetails.tokenSymbol = token.symbol;
} else if (decodedTokenAddress) {
// For swaps through routers: use the input token info
pendingTxDetails.token = decodedTokenAddress;
pendingTxDetails.tokenSymbol = decodedTokenSymbol;
}
}

查看文件

@@ -445,12 +445,19 @@ function decode(data, toAddress) {
const maxUint160 = BigInt(
"0xffffffffffffffffffffffffffffffffffffffff",
);
const rawAmount =
inputAmount >= maxUint160
? "Unlimited"
: formatAmount(inputAmount, inInfo.decimals);
const amountStr =
inputAmount >= maxUint160
? "Unlimited"
: formatAmount(inputAmount, inInfo.decimals) +
(inSymbol ? " " + inSymbol : "");
details.push({ label: "Amount", value: amountStr });
: rawAmount + (inSymbol ? " " + inSymbol : "");
details.push({
label: "Amount",
value: amountStr,
rawValue: rawAmount,
});
}
if (outSymbol) {