Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1df0ebb493 |
@@ -882,12 +882,9 @@ On those screens, when the truncated string would contain no digit from 1 to 9
|
|||||||
and the value does, the amount is extended to its first significant digit
|
and the value does, the amount is extended to its first significant digit
|
||||||
instead: `0.000000000000000001 DAI`, not `0.0000 DAI`. The test is on the whole
|
instead: `0.000000000000000001 DAI`, not `0.0000 DAI`. The test is on the whole
|
||||||
truncated string, integer part included, so `1.00005` still shows as `1.0000` —
|
truncated string, integer part included, so `1.00005` still shows as `1.0000` —
|
||||||
the exception only fires where the entire displayed figure would read as zero.
|
the exception only fires where the entire displayed figure would read as zero. A
|
||||||
Truncation stays truncation: `0.99999` shows as `0.9999`, never rounded up. The
|
genuine zero still renders `0.0000`, and truncation stays truncation: `0.99999`
|
||||||
rule still renders a genuine zero as `0.0000`. Two lines of a swap say a zero in
|
shows as `0.9999`, never rounded up.
|
||||||
words instead: `Min. received` reads `None (no minimum guaranteed)` for a zero
|
|
||||||
minimum, and `Amount` reads `All available (V4 open delta)` when the amount it
|
|
||||||
shows is a V4 exact-in `amountIn` of zero.
|
|
||||||
|
|
||||||
The rule and its exception live in `src/shared/amountDisplay.js` as
|
The rule and its exception live in `src/shared/amountDisplay.js` as
|
||||||
`truncateAmount()` and `truncateAmountNeverZero()`. Everything the approval and
|
`truncateAmount()` and `truncateAmountNeverZero()`. Everything the approval and
|
||||||
@@ -896,16 +893,13 @@ the ETH value and max fee (`src/popup/views/approval.js`), the swap's `Amount`
|
|||||||
and `Min. received` lines (`src/shared/uniswap.js`), the Send screen's
|
and `Min. received` lines (`src/shared/uniswap.js`), the Send screen's
|
||||||
`Current balance` (`src/popup/views/send.js`), and the balance and network fee
|
`Current balance` (`src/popup/views/send.js`), and the balance and network fee
|
||||||
on the confirmation screen for the wallet's own send
|
on the confirmation screen for the wallet's own send
|
||||||
(`src/popup/views/confirmTx.js`). Both screens render a network fee through
|
(`src/popup/views/confirmTx.js`), so a fee reads the same there as on the
|
||||||
`formatFee()` in `src/popup/views/helpers.js`, which prices the exact fee in USD
|
approval screen. For this the ETH balance is stored exactly. A token balance is
|
||||||
rather than its truncated figure, so the same fee reads the same on both, USD
|
stored to six decimal places, and a holding below 0.000001 is not listed at all.
|
||||||
value included. The ETH balance is stored exactly, so a balance below the floor
|
The history and balance lists (`src/shared/transactions.js`) use the unfloored
|
||||||
reaches these screens as it is. A token balance is stored to six decimal places,
|
one: the transaction detail view is the authoritative record and already shows
|
||||||
and a holding below 0.000001 is not listed at all. The history and balance lists
|
exact precision. The 4-decimal rule is unchanged everywhere else, including for
|
||||||
(`src/shared/transactions.js`) use the unfloored one: the transaction detail
|
amounts at or above the floor on the approval screens.
|
||||||
view is the authoritative record and already shows exact precision. The
|
|
||||||
4-decimal rule is unchanged everywhere else, including for amounts at or above
|
|
||||||
the floor on the approval screens.
|
|
||||||
|
|
||||||
The floor applies only where the token's scale is known. Where it is not, the
|
The floor applies only where the token's scale is known. Where it is not, the
|
||||||
approval screen states base units instead of a quantity — see Unknown token
|
approval screen states base units instead of a quantity — see Unknown token
|
||||||
@@ -948,41 +942,6 @@ and compare against. Reading the stored field directly instead answers `null`
|
|||||||
for a bundled or tracked token the explorer merely omitted, which is not a
|
for a bundled or tracked token the explorer merely omitted, which is not a
|
||||||
refusal the wallet has any reason to make.
|
refusal the wallet has any reason to make.
|
||||||
|
|
||||||
**Decoded amount lines on the transaction approval screen:** the `Amount` line
|
|
||||||
of a decoded ERC-20 call, and the `Amount` and `Min. received` lines of a
|
|
||||||
decoded swap (see TxApproval below), do not always read as a number. They can
|
|
||||||
read:
|
|
||||||
|
|
||||||
- A formatted quantity, e.g. `17.1900 USDT`, when the token's scale is known:
|
|
||||||
truncated to four decimals, with the floor and the zero cases described above.
|
|
||||||
- `<amount> base units (decimals unknown)` when the scale is unknown: the
|
|
||||||
base-unit integer, rather than a figure at a guessed scale (see Unknown token
|
|
||||||
scale above).
|
|
||||||
- `Unlimited`: on the ERC-20 `Amount` line, an `approve` of the `uint256`
|
|
||||||
maximum, an unbounded allowance. On the swap's `Amount` line, any amount at or
|
|
||||||
above the `uint160` maximum, whichever step set the line: a `PERMIT2_PERMIT`
|
|
||||||
amount at that maximum, which is an unbounded permit, or a V2 or V3 exact-in
|
|
||||||
or `WRAP_ETH` amount that large, which is not an allowance. The router's
|
|
||||||
whole-balance value, `CONTRACT_BALANCE` (`2^255`), is one such amount.
|
|
||||||
- `All available (V4 open delta)`: the swap's `Amount` line, when the amount it
|
|
||||||
shows is a V4 exact-in `amountIn` of zero. V4 reads that zero as "use the
|
|
||||||
whole open delta", so the calldata states no quantity. The line shows the
|
|
||||||
amount of one step that names an input token or amount: the last
|
|
||||||
`PERMIT2_PERMIT` step if there is one, otherwise the first V2 or V3 exact-in,
|
|
||||||
`WRAP_ETH` or V4 swap step, a V4 swap step giving the `amountIn` of its first
|
|
||||||
readable exact-in action.
|
|
||||||
- `None (no minimum guaranteed)`: the swap's `Min. received` line, when the
|
|
||||||
minimum it shows is zero, whether a V2, V3 or V4 swap's minimum or a
|
|
||||||
`BALANCE_CHECK_ERC20` step's `minBalance`. Before
|
|
||||||
[#359](https://git.eeqj.de/sneak/AutistMask/issues/359), a zero `minBalance`
|
|
||||||
read `0.0000` when the token's scale was known.
|
|
||||||
|
|
||||||
The swap's `Token In` and `Token Out` lines name a currency, not an amount; each
|
|
||||||
reads `Unknown (not named in the calldata)` when the decoder found no token for
|
|
||||||
that side. The token permission warning on the signature screen has its own
|
|
||||||
amount wording, including `Unknown`; the SignApproval section below describes
|
|
||||||
it.
|
|
||||||
|
|
||||||
#### Partial USD totals
|
#### Partial USD totals
|
||||||
|
|
||||||
Prices are fetched for the top 25 tokens only, so an address can hold assets the
|
Prices are fetched for the top 25 tokens only, so an address can hold assets the
|
||||||
|
|||||||
@@ -53,12 +53,10 @@ but the review is broader than any of them.
|
|||||||
stored exactly, and the Send screen's `Current balance`, and the confirmation
|
stored exactly, and the Send screen's `Current balance`, and the confirmation
|
||||||
screen's balance, fee, reserve and insufficient-balance messages, go through
|
screen's balance, fee, reserve and insufficient-balance messages, go through
|
||||||
`truncateAmountNeverZero()` in `src/shared/amountDisplay.js`, the helper the
|
`truncateAmountNeverZero()` in `src/shared/amountDisplay.js`, the helper the
|
||||||
approval screen already used. The confirmation and approval screens both
|
approval screen already used, so the same fee reads the same on both screens.
|
||||||
render the fee through `formatFee()` in `src/popup/views/helpers.js`, which
|
Token balances are still stored to six decimal places: that cut is also what
|
||||||
prices the exact fee in USD, so the same fee reads the same on both, USD value
|
leaves a holding below 0.000001 off the balance list, and keeps the stored
|
||||||
included. Token balances are still stored to six decimal places: that cut is
|
string within the 18 decimals the balance check reads.
|
||||||
also what leaves a holding below 0.000001 off the balance list, and keeps the
|
|
||||||
stored string within the 18 decimals the balance check reads.
|
|
||||||
- 2026-10-03: The typed-data signing screen warns for a token permission, and
|
- 2026-10-03: The typed-data signing screen warns for a token permission, and
|
||||||
names the primary type ethers signs
|
names the primary type ethers signs
|
||||||
([#400](https://git.eeqj.de/sneak/AutistMask/issues/400)). A Permit or Permit2
|
([#400](https://git.eeqj.de/sneak/AutistMask/issues/400)). A Permit or Permit2
|
||||||
@@ -187,20 +185,6 @@ but the review is broader than any of them.
|
|||||||
standalone storage entry, never part of the versioned `autistmask` profile, so
|
standalone storage entry, never part of the versioned `autistmask` profile, so
|
||||||
the state schema is untouched and no existing profile is affected.
|
the state schema is untouched and no existing profile is affected.
|
||||||
|
|
||||||
- 2026-09-21: `README.md` no longer says a genuine zero always renders `0.0000`
|
|
||||||
([#369](https://git.eeqj.de/sneak/AutistMask/issues/369)). The amount rule
|
|
||||||
still renders one as `0.0000`, but two swap lines say a zero in words instead:
|
|
||||||
`Min. received` reads `None (no minimum guaranteed)` for a zero minimum, and
|
|
||||||
`Amount` reads `All available (V4 open delta)` when the amount it shows is a
|
|
||||||
V4 exact-in `amountIn` of zero. A new list says what the decoded ERC-20 and
|
|
||||||
swap amount lines on the transaction approval screen can read: a formatted
|
|
||||||
quantity, base units with decimals unknown, `Unlimited`,
|
|
||||||
`All available (V4 open delta)` and `None (no minimum guaranteed)`, which a
|
|
||||||
zero `minBalance` on a `BALANCE_CHECK_ERC20` step now reads instead of
|
|
||||||
`0.0000` at a known scale. The README also names
|
|
||||||
`Unknown (not named in the calldata)` on the swap's token lines, and points to
|
|
||||||
SignApproval for the token permission warning's own wording. Docs only.
|
|
||||||
|
|
||||||
- 2026-08-30: An address no longer wraps, or is shortened to fit, in any of the
|
- 2026-08-30: An address no longer wraps, or is shortened to fit, in any of the
|
||||||
common views ([#380](https://git.eeqj.de/sneak/AutistMask/issues/380)). The
|
common views ([#380](https://git.eeqj.de/sneak/AutistMask/issues/380)). The
|
||||||
wallet list was the reported case: the address shared one row with the
|
wallet list was the reported case: the address shared one row with the
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ const {
|
|||||||
renderAddressHtml,
|
renderAddressHtml,
|
||||||
attachCopyHandlers,
|
attachCopyHandlers,
|
||||||
onViewLeave,
|
onViewLeave,
|
||||||
formatFee,
|
|
||||||
} = require("./helpers");
|
} = require("./helpers");
|
||||||
const { state, saveState } = require("../../shared/state");
|
const { state, saveState } = require("../../shared/state");
|
||||||
const { networkByChainId } = require("../../shared/networks");
|
const { networkByChainId } = require("../../shared/networks");
|
||||||
@@ -208,7 +207,7 @@ function showPhishingWarning(elementId, isPhishing) {
|
|||||||
// and the nonce. The background compares every one of them against the signed
|
// and the nonce. The background compares every one of them against the signed
|
||||||
// artifact, so every one of them has to be on the screen — a number that is
|
// artifact, so every one of them has to be on the screen — a number that is
|
||||||
// verified but never displayed is verified against nothing the user agreed to.
|
// verified but never displayed is verified against nothing the user agreed to.
|
||||||
function showTxFee(approvedTx) {
|
function showTxFee(approvedTx, ethPrice) {
|
||||||
const network = networkByChainId(approvedTx.chainId);
|
const network = networkByChainId(approvedTx.chainId);
|
||||||
$("approve-tx-network").textContent = network
|
$("approve-tx-network").textContent = network
|
||||||
? network.name
|
? network.name
|
||||||
@@ -216,9 +215,12 @@ function showTxFee(approvedTx) {
|
|||||||
|
|
||||||
const gasLimit = BigInt(approvedTx.gasLimit);
|
const gasLimit = BigInt(approvedTx.gasLimit);
|
||||||
const feePerGas = BigInt(approvedTx.maxFeePerGas || approvedTx.gasPrice);
|
const feePerGas = BigInt(approvedTx.maxFeePerGas || approvedTx.gasPrice);
|
||||||
// Through formatFee(), as the confirmation screen's fee is, so the same
|
const maxFeeEth = formatTxValue(formatEther(gasLimit * feePerGas));
|
||||||
// fee reads the same on both.
|
const usdStr = formatUsd(
|
||||||
$("approve-tx-fee").textContent = formatFee(gasLimit * feePerGas);
|
ethPrice ? parseFloat(maxFeeEth) * ethPrice : null,
|
||||||
|
);
|
||||||
|
$("approve-tx-fee").textContent =
|
||||||
|
maxFeeEth + " ETH" + (usdStr ? " (" + usdStr + ")" : "");
|
||||||
|
|
||||||
let detail =
|
let detail =
|
||||||
gasLimit.toString() +
|
gasLimit.toString() +
|
||||||
@@ -330,7 +332,7 @@ function showTxApproval(details) {
|
|||||||
$("approve-tx-value").textContent =
|
$("approve-tx-value").textContent =
|
||||||
ethValueFormatted + " ETH" + (usdStr ? " (" + usdStr + ")" : "");
|
ethValueFormatted + " ETH" + (usdStr ? " (" + usdStr + ")" : "");
|
||||||
|
|
||||||
showTxFee(approvedTx);
|
showTxFee(approvedTx, ethPrice);
|
||||||
|
|
||||||
// Decode calldata (reuse decoded from above)
|
// Decode calldata (reuse decoded from above)
|
||||||
const decodedEl = $("approve-tx-decoded");
|
const decodedEl = $("approve-tx-decoded");
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ const {
|
|||||||
attachCopyHandlers,
|
attachCopyHandlers,
|
||||||
goBack,
|
goBack,
|
||||||
onViewLeave,
|
onViewLeave,
|
||||||
formatFee,
|
|
||||||
} = require("./helpers");
|
} = require("./helpers");
|
||||||
const { state } = require("../../shared/state");
|
const { state } = require("../../shared/state");
|
||||||
const { getSignerForAddress } = require("../../shared/wallet");
|
const { getSignerForAddress } = require("../../shared/wallet");
|
||||||
@@ -32,8 +31,8 @@ const {
|
|||||||
transferAmountUnits,
|
transferAmountUnits,
|
||||||
} = require("../../shared/transferAmount");
|
} = require("../../shared/transferAmount");
|
||||||
const { assertWithinCeilings } = require("../../shared/approvalVerify");
|
const { assertWithinCeilings } = require("../../shared/approvalVerify");
|
||||||
// The balance lines, the fee reserve and the insufficient-balance messages go
|
// Every balance and fee this screen shows goes through it, as the approval
|
||||||
// through it, as the approval screen's amounts do.
|
// screen's do, so the same value reads the same on both.
|
||||||
const { truncateAmountNeverZero } = require("../../shared/amountDisplay");
|
const { truncateAmountNeverZero } = require("../../shared/amountDisplay");
|
||||||
const {
|
const {
|
||||||
CODES,
|
CODES,
|
||||||
@@ -361,10 +360,17 @@ async function estimateGas(txInfo) {
|
|||||||
// flight; a stale fee must not reach the screen or the balance check.
|
// flight; a stale fee must not reach the screen or the balance check.
|
||||||
if (pendingTx !== txInfo) return;
|
if (pendingTx !== txInfo) return;
|
||||||
|
|
||||||
// The fee lines go through formatFee(), as the approval screen's
|
const ethPrice = getPrice("ETH");
|
||||||
// does, so the same fee reads the same on both.
|
const usd = (wei) =>
|
||||||
|
ethPrice ? parseFloat(formatEther(wei)) * ethPrice : null;
|
||||||
|
|
||||||
if (estimateWei !== null && estimateWei < gasCostWei) {
|
if (estimateWei !== null && estimateWei < gasCostWei) {
|
||||||
$("confirm-fee-amount").textContent = "~" + formatFee(estimateWei);
|
$("confirm-fee-amount").textContent = valueWithUsd(
|
||||||
|
"~" +
|
||||||
|
truncateAmountNeverZero(formatEther(estimateWei)) +
|
||||||
|
" ETH",
|
||||||
|
usd(estimateWei),
|
||||||
|
);
|
||||||
$("confirm-fee-reserve").textContent =
|
$("confirm-fee-reserve").textContent =
|
||||||
"up to " +
|
"up to " +
|
||||||
truncateAmountNeverZero(formatEther(gasCostWei)) +
|
truncateAmountNeverZero(formatEther(gasCostWei)) +
|
||||||
@@ -374,7 +380,10 @@ async function estimateGas(txInfo) {
|
|||||||
// No spread to report: either there is no estimate, or the node
|
// No spread to report: either there is no estimate, or the node
|
||||||
// quotes a gas price at or above maxFeePerGas, so the expected
|
// quotes a gas price at or above maxFeePerGas, so the expected
|
||||||
// cost is not below the reserve. Show the reserve alone.
|
// cost is not below the reserve. Show the reserve alone.
|
||||||
$("confirm-fee-amount").textContent = formatFee(gasCostWei);
|
$("confirm-fee-amount").textContent = valueWithUsd(
|
||||||
|
truncateAmountNeverZero(formatEther(gasCostWei)) + " ETH",
|
||||||
|
usd(gasCostWei),
|
||||||
|
);
|
||||||
setVisible("confirm-fee-reserve", false);
|
setVisible("confirm-fee-reserve", false);
|
||||||
}
|
}
|
||||||
feeStatus = FEE_KNOWN;
|
feeStatus = FEE_KNOWN;
|
||||||
|
|||||||
@@ -12,8 +12,6 @@
|
|||||||
// escapeHtml lives in src/shared/html.js, where the escape and the
|
// escapeHtml lives in src/shared/html.js, where the escape and the
|
||||||
// reasoning behind it are; it is re-exported below so views keep importing
|
// reasoning behind it are; it is re-exported below so views keep importing
|
||||||
// it from here.
|
// it from here.
|
||||||
const { formatEther } = require("ethers");
|
|
||||||
const { truncateAmountNeverZero } = require("../../shared/amountDisplay");
|
|
||||||
const { DEBUG } = require("../../shared/constants");
|
const { DEBUG } = require("../../shared/constants");
|
||||||
const { escapeHtml } = require("../../shared/html");
|
const { escapeHtml } = require("../../shared/html");
|
||||||
const { isDebug } = require("../../shared/log");
|
const { isDebug } = require("../../shared/log");
|
||||||
@@ -245,19 +243,6 @@ function unknownableAmount(balance) {
|
|||||||
return Number.isFinite(n) ? n : null;
|
return Number.isFinite(n) ? n : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A network fee in wei as the confirmation and approval screens both show it:
|
|
||||||
// the ETH figure through truncateAmountNeverZero(), then its USD value when the
|
|
||||||
// ETH price is known. The USD value is of the exact fee, not of the truncated
|
|
||||||
// figure, so it never understates what the fee costs.
|
|
||||||
function formatFee(wei) {
|
|
||||||
const eth = formatEther(wei);
|
|
||||||
const ethPrice = getPrice("ETH");
|
|
||||||
const usd = ethPrice ? formatUsd(parseFloat(eth) * ethPrice) : "";
|
|
||||||
return (
|
|
||||||
truncateAmountNeverZero(eth) + " ETH" + (usd ? " (" + usd + ")" : "")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// One row of the balance list: symbol, quantity, fiat value.
|
// One row of the balance list: symbol, quantity, fiat value.
|
||||||
//
|
//
|
||||||
// `symbol` is the ERC-20's own symbol() as the block explorer reported it,
|
// `symbol` is the ERC-20's own symbol() as the block explorer reported it,
|
||||||
@@ -625,7 +610,6 @@ module.exports = {
|
|||||||
balanceLinesForAddress,
|
balanceLinesForAddress,
|
||||||
addressHoldsFunds,
|
addressHoldsFunds,
|
||||||
unknownableAmount,
|
unknownableAmount,
|
||||||
formatFee,
|
|
||||||
addressColor,
|
addressColor,
|
||||||
addressDotHtml,
|
addressDotHtml,
|
||||||
escapeHtml,
|
escapeHtml,
|
||||||
|
|||||||
+5
-4
@@ -1505,10 +1505,11 @@ async function backToAddress(page) {
|
|||||||
|
|
||||||
// Drive the popup to the confirmation screen for one send.
|
// Drive the popup to the confirmation screen for one send.
|
||||||
//
|
//
|
||||||
// It waits for the send screen to be showing `balance`, the fixture's balance
|
// It waits for the send screen to be showing `balance` before filling
|
||||||
// as that screen displays it, before filling anything in. Waiting for it —
|
// anything in. That figure is the exact number the spend gate compares
|
||||||
// rather than for a refresh to have probably landed — is what keeps every
|
// against, so waiting for it — rather than for a refresh to have probably
|
||||||
// assertion below deterministic after a fixture change.
|
// landed — is what keeps every assertion below deterministic after a
|
||||||
|
// fixture change.
|
||||||
async function goToConfirm(page, { token, balance, amount }) {
|
async function goToConfirm(page, { token, balance, amount }) {
|
||||||
await backToAddress(page);
|
await backToAddress(page);
|
||||||
await page.click("#btn-send");
|
await page.click("#btn-send");
|
||||||
|
|||||||
@@ -139,7 +139,6 @@ global.navigator = { clipboard: { writeText() {} } };
|
|||||||
|
|
||||||
const { refreshBalances } = require("../src/shared/balances");
|
const { refreshBalances } = require("../src/shared/balances");
|
||||||
const { state } = require("../src/shared/state");
|
const { state } = require("../src/shared/state");
|
||||||
const { prices, clearPrices } = require("../src/shared/prices");
|
|
||||||
const send = require("../src/popup/views/send");
|
const send = require("../src/popup/views/send");
|
||||||
const confirmTx = require("../src/popup/views/confirmTx");
|
const confirmTx = require("../src/popup/views/confirmTx");
|
||||||
const approval = require("../src/popup/views/approval");
|
const approval = require("../src/popup/views/approval");
|
||||||
@@ -257,28 +256,18 @@ describe("a fee below 0.000001 ETH never renders as zero", () => {
|
|||||||
|
|
||||||
// The confirmation screen shows the reserve alone when the node quotes no
|
// The confirmation screen shows the reserve alone when the node quotes no
|
||||||
// cheaper estimate, and that reserve is the same gas limit times maximum fee
|
// cheaper estimate, and that reserve is the same gas limit times maximum fee
|
||||||
// per gas that the approval screen calls the max fee. An ETH price is set, as
|
// per gas that the approval screen calls the max fee.
|
||||||
// it is on mainnet, so the USD value has to match too.
|
|
||||||
describe("the same fee reads the same on the confirmation and approval screens", () => {
|
describe("the same fee reads the same on the confirmation and approval screens", () => {
|
||||||
beforeEach(() => {
|
|
||||||
prices.ETH = 3000;
|
|
||||||
});
|
|
||||||
afterEach(() => {
|
|
||||||
clearPrices();
|
|
||||||
});
|
|
||||||
|
|
||||||
test.each([
|
test.each([
|
||||||
// 21000 gas at 1 wei.
|
["below the floor", 1n],
|
||||||
["below the floor", 1n, "0.00000000000002 ETH (< $0.01)"],
|
["with more than four decimals", 58823529411n],
|
||||||
// 0.001235294117631 ETH, which is $3.71. Pricing the truncated
|
])("%s", async (_label, feePerGas) => {
|
||||||
// 0.0012 instead would read $3.60.
|
|
||||||
["with more than four decimals", 58823529411n, "0.0012 ETH ($3.71)"],
|
|
||||||
])("%s", async (_label, feePerGas, expected) => {
|
|
||||||
mockNode.feeData = { maxFeePerGas: feePerGas, gasPrice: feePerGas };
|
mockNode.feeData = { maxFeePerGas: feePerGas, gasPrice: feePerGas };
|
||||||
await refreshWith(10n ** 18n);
|
await refreshWith(10n ** 18n);
|
||||||
await confirmEthSend("0.1");
|
await confirmEthSend("0.1");
|
||||||
expect(text("confirm-fee-amount")).toBe(expected);
|
const onConfirm = text("confirm-fee-amount");
|
||||||
await approveTxWithFeePerGas(feePerGas);
|
await approveTxWithFeePerGas(feePerGas);
|
||||||
expect(text("approve-tx-fee")).toBe(expected);
|
expect(text("approve-tx-fee")).toBe(onConfirm);
|
||||||
|
expect(onConfirm).toMatch(/[1-9]/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user