Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebbc2028e0 | ||
|
|
00d6193ee7 |
@@ -882,9 +882,12 @@ 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. A
|
the exception only fires where the entire displayed figure would read as zero.
|
||||||
genuine zero still renders `0.0000`, and truncation stays truncation: `0.99999`
|
Truncation stays truncation: `0.99999` shows as `0.9999`, never rounded up. The
|
||||||
shows as `0.9999`, never rounded up.
|
rule still renders a genuine zero as `0.0000`. Two lines of a swap 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.
|
||||||
|
|
||||||
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
|
||||||
@@ -893,13 +896,16 @@ 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`), so a fee reads the same there as on the
|
(`src/popup/views/confirmTx.js`). Both screens render a network fee through
|
||||||
approval screen. For this the ETH balance is stored exactly. A token balance is
|
`formatFee()` in `src/popup/views/helpers.js`, which prices the exact fee in USD
|
||||||
stored to six decimal places, and a holding below 0.000001 is not listed at all.
|
rather than its truncated figure, so the same fee reads the same on both, USD
|
||||||
The history and balance lists (`src/shared/transactions.js`) use the unfloored
|
value included. The ETH balance is stored exactly, so a balance below the floor
|
||||||
one: the transaction detail view is the authoritative record and already shows
|
reaches these screens as it is. A token balance is stored to six decimal places,
|
||||||
exact precision. The 4-decimal rule is unchanged everywhere else, including for
|
and a holding below 0.000001 is not listed at all. The history and balance lists
|
||||||
amounts at or above the floor on the approval screens.
|
(`src/shared/transactions.js`) use the unfloored one: the transaction detail
|
||||||
|
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
|
||||||
@@ -942,6 +948,41 @@ 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,10 +53,12 @@ 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, so the same fee reads the same on both screens.
|
approval screen already used. The confirmation and approval screens both
|
||||||
Token balances are still stored to six decimal places: that cut is also what
|
render the fee through `formatFee()` in `src/popup/views/helpers.js`, which
|
||||||
leaves a holding below 0.000001 off the balance list, and keeps the stored
|
prices the exact fee in USD, so the same fee reads the same on both, USD value
|
||||||
string within the 18 decimals the balance check reads.
|
included. Token balances are still stored to six decimal places: that cut is
|
||||||
|
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
|
||||||
@@ -185,6 +187,20 @@ 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,6 +8,7 @@ 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");
|
||||||
@@ -207,7 +208,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, ethPrice) {
|
function showTxFee(approvedTx) {
|
||||||
const network = networkByChainId(approvedTx.chainId);
|
const network = networkByChainId(approvedTx.chainId);
|
||||||
$("approve-tx-network").textContent = network
|
$("approve-tx-network").textContent = network
|
||||||
? network.name
|
? network.name
|
||||||
@@ -215,12 +216,9 @@ function showTxFee(approvedTx, ethPrice) {
|
|||||||
|
|
||||||
const gasLimit = BigInt(approvedTx.gasLimit);
|
const gasLimit = BigInt(approvedTx.gasLimit);
|
||||||
const feePerGas = BigInt(approvedTx.maxFeePerGas || approvedTx.gasPrice);
|
const feePerGas = BigInt(approvedTx.maxFeePerGas || approvedTx.gasPrice);
|
||||||
const maxFeeEth = formatTxValue(formatEther(gasLimit * feePerGas));
|
// Through formatFee(), as the confirmation screen's fee is, so the same
|
||||||
const usdStr = formatUsd(
|
// fee reads the same on both.
|
||||||
ethPrice ? parseFloat(maxFeeEth) * ethPrice : null,
|
$("approve-tx-fee").textContent = formatFee(gasLimit * feePerGas);
|
||||||
);
|
|
||||||
$("approve-tx-fee").textContent =
|
|
||||||
maxFeeEth + " ETH" + (usdStr ? " (" + usdStr + ")" : "");
|
|
||||||
|
|
||||||
let detail =
|
let detail =
|
||||||
gasLimit.toString() +
|
gasLimit.toString() +
|
||||||
@@ -332,7 +330,7 @@ function showTxApproval(details) {
|
|||||||
$("approve-tx-value").textContent =
|
$("approve-tx-value").textContent =
|
||||||
ethValueFormatted + " ETH" + (usdStr ? " (" + usdStr + ")" : "");
|
ethValueFormatted + " ETH" + (usdStr ? " (" + usdStr + ")" : "");
|
||||||
|
|
||||||
showTxFee(approvedTx, ethPrice);
|
showTxFee(approvedTx);
|
||||||
|
|
||||||
// Decode calldata (reuse decoded from above)
|
// Decode calldata (reuse decoded from above)
|
||||||
const decodedEl = $("approve-tx-decoded");
|
const decodedEl = $("approve-tx-decoded");
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ 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");
|
||||||
@@ -31,8 +32,8 @@ const {
|
|||||||
transferAmountUnits,
|
transferAmountUnits,
|
||||||
} = require("../../shared/transferAmount");
|
} = require("../../shared/transferAmount");
|
||||||
const { assertWithinCeilings } = require("../../shared/approvalVerify");
|
const { assertWithinCeilings } = require("../../shared/approvalVerify");
|
||||||
// Every balance and fee this screen shows goes through it, as the approval
|
// The balance lines, the fee reserve and the insufficient-balance messages go
|
||||||
// screen's do, so the same value reads the same on both.
|
// through it, as the approval screen's amounts do.
|
||||||
const { truncateAmountNeverZero } = require("../../shared/amountDisplay");
|
const { truncateAmountNeverZero } = require("../../shared/amountDisplay");
|
||||||
const {
|
const {
|
||||||
CODES,
|
CODES,
|
||||||
@@ -360,17 +361,10 @@ 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;
|
||||||
|
|
||||||
const ethPrice = getPrice("ETH");
|
// The fee lines go through formatFee(), as the approval screen's
|
||||||
const usd = (wei) =>
|
// does, so the same fee reads the same on both.
|
||||||
ethPrice ? parseFloat(formatEther(wei)) * ethPrice : null;
|
|
||||||
|
|
||||||
if (estimateWei !== null && estimateWei < gasCostWei) {
|
if (estimateWei !== null && estimateWei < gasCostWei) {
|
||||||
$("confirm-fee-amount").textContent = valueWithUsd(
|
$("confirm-fee-amount").textContent = "~" + formatFee(estimateWei);
|
||||||
"~" +
|
|
||||||
truncateAmountNeverZero(formatEther(estimateWei)) +
|
|
||||||
" ETH",
|
|
||||||
usd(estimateWei),
|
|
||||||
);
|
|
||||||
$("confirm-fee-reserve").textContent =
|
$("confirm-fee-reserve").textContent =
|
||||||
"up to " +
|
"up to " +
|
||||||
truncateAmountNeverZero(formatEther(gasCostWei)) +
|
truncateAmountNeverZero(formatEther(gasCostWei)) +
|
||||||
@@ -380,10 +374,7 @@ 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 = valueWithUsd(
|
$("confirm-fee-amount").textContent = formatFee(gasCostWei);
|
||||||
truncateAmountNeverZero(formatEther(gasCostWei)) + " ETH",
|
|
||||||
usd(gasCostWei),
|
|
||||||
);
|
|
||||||
setVisible("confirm-fee-reserve", false);
|
setVisible("confirm-fee-reserve", false);
|
||||||
}
|
}
|
||||||
feeStatus = FEE_KNOWN;
|
feeStatus = FEE_KNOWN;
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
// 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");
|
||||||
@@ -243,6 +245,19 @@ 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,
|
||||||
@@ -610,6 +625,7 @@ module.exports = {
|
|||||||
balanceLinesForAddress,
|
balanceLinesForAddress,
|
||||||
addressHoldsFunds,
|
addressHoldsFunds,
|
||||||
unknownableAmount,
|
unknownableAmount,
|
||||||
|
formatFee,
|
||||||
addressColor,
|
addressColor,
|
||||||
addressDotHtml,
|
addressDotHtml,
|
||||||
escapeHtml,
|
escapeHtml,
|
||||||
|
|||||||
+4
-5
@@ -1505,11 +1505,10 @@ 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` before filling
|
// It waits for the send screen to be showing `balance`, the fixture's balance
|
||||||
// anything in. That figure is the exact number the spend gate compares
|
// as that screen displays it, before filling anything in. Waiting for it —
|
||||||
// against, so waiting for it — rather than for a refresh to have probably
|
// rather than for a refresh to have probably landed — is what keeps every
|
||||||
// landed — is what keeps every assertion below deterministic after a
|
// assertion below deterministic after a fixture change.
|
||||||
// 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,6 +139,7 @@ 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");
|
||||||
@@ -256,18 +257,28 @@ 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.
|
// per gas that the approval screen calls the max fee. An ETH price is set, as
|
||||||
|
// 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([
|
||||||
["below the floor", 1n],
|
// 21000 gas at 1 wei.
|
||||||
["with more than four decimals", 58823529411n],
|
["below the floor", 1n, "0.00000000000002 ETH (< $0.01)"],
|
||||||
])("%s", async (_label, feePerGas) => {
|
// 0.001235294117631 ETH, which is $3.71. Pricing the truncated
|
||||||
|
// 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");
|
||||||
const onConfirm = text("confirm-fee-amount");
|
expect(text("confirm-fee-amount")).toBe(expected);
|
||||||
await approveTxWithFeePerGas(feePerGas);
|
await approveTxWithFeePerGas(feePerGas);
|
||||||
expect(text("approve-tx-fee")).toBe(onConfirm);
|
expect(text("approve-tx-fee")).toBe(expected);
|
||||||
expect(onConfirm).toMatch(/[1-9]/);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user