1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-25 03:20:23 +01:00

Token allowance flow update (#19666)

This commit is contained in:
Niranjana Binoy 2023-07-11 10:57:59 -04:00 committed by GitHub
parent f9b1514914
commit 129f6f3f64
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 668 additions and 262 deletions

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "Seed-Phrase anzeigen"
},
"reviewSpendingCap": {
"message": "Überprüfen SIe Ihre Ausgabegrenze"
},
"revokeAllTokensTitle": {
"message": "Erlaubnis zum Zugriff auf alle Ihre $1 sowie deren Übertragung entziehen?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3140,10 +3137,6 @@
"message": "$1 ohne Ausgabenlimit genehmigen",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "Eine Ausgabegrenze für Ihr $1 einrichten",
"description": "$1 is a token symbol"
},
"settings": {
"message": "Einstellungen"
},
@ -4167,9 +4160,6 @@
"urlExistsErrorMsg": {
"message": "Diese URL wird derzeit vom $1-Netzwerk verwendet."
},
"useDefault": {
"message": "Standardeinstellungen verwenden"
},
"useMultiAccountBalanceChecker": {
"message": "Kontoguthaben-Anfragen sammeln"
},

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "Αποκάλυψη φράσης ανάκτησης"
},
"reviewSpendingCap": {
"message": "Επανεξετάστε το όριο δαπανών σας"
},
"revokeAllTokensTitle": {
"message": "Ανάκληση άδειας πρόσβασης σε όλα σας τα $1;",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3137,10 +3134,6 @@
"message": "Έγκριση $1 χωρίς όριο δαπανών",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "Ορίστε ένα ανώτατο όριο δαπανών για το $1",
"description": "$1 is a token symbol"
},
"settings": {
"message": "Ρυθμίσεις"
},
@ -4164,9 +4157,6 @@
"urlExistsErrorMsg": {
"message": "Αυτό το URL χρησιμοποιείται επί του παρόντος από το δίκτυο $1."
},
"useDefault": {
"message": "Χρήση προκαθορισμένου"
},
"useMultiAccountBalanceChecker": {
"message": "Μαζικά αιτήματα υπολοίπου λογαριασμού"
},

View File

@ -1055,6 +1055,9 @@
"customerSupport": {
"message": "customer support"
},
"dappRequestedSpendingCap": {
"message": "Site requested spending cap"
},
"dappSuggested": {
"message": "Site suggested"
},
@ -3544,9 +3547,6 @@
"revealTheSeedPhrase": {
"message": "Reveal seed phrase"
},
"reviewSpendingCap": {
"message": "Review the spending cap for your"
},
"revokeAllTokensTitle": {
"message": "Revoke permission to access and transfer all of your $1?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3766,10 +3766,6 @@
"message": "Approve $1 with no spend limit",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "Set a spending cap for your $1",
"description": "$1 is a token symbol"
},
"settingAddSnapAccount": {
"message": "Add snap account"
},
@ -4092,6 +4088,9 @@
"message": "Only enter a number that you're comfortable with $1 accessing now or in the future. You can always increase the token limit later.",
"description": "$1 is origin of the site requesting the token limit"
},
"spendingCapRequest": {
"message": "Spending cap request for your $1"
},
"srpInputNumberOfWords": {
"message": "I have a $1-word phrase",
"description": "This is the text for each option in the dropdown where a user selects how many words their secret recovery phrase has during import. The $1 is the number of words (either 12, 15, 18, 21, or 24)."
@ -5141,9 +5140,6 @@
"urlExistsErrorMsg": {
"message": "This URL is currently used by the $1 network."
},
"useDefault": {
"message": "Use default"
},
"useMultiAccountBalanceChecker": {
"message": "Batch account balance requests"
},
@ -5174,6 +5170,9 @@
"usePhishingDetectionDescription": {
"message": "Display a warning for phishing domains targeting Ethereum users"
},
"useSiteSuggestion": {
"message": "Use site suggestion"
},
"useTokenDetectionPrivacyDesc": {
"message": "Automatically displaying tokens sent to your account involves communication with third party servers to fetch tokens images. Those serves will have access to your IP address."
},

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "Revelar frase semilla"
},
"reviewSpendingCap": {
"message": "Revise su límite de gasto"
},
"revokeAllTokensTitle": {
"message": "¿Revocar el permiso para acceder y transferir todos sus $1?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3140,10 +3137,6 @@
"message": "Aprobar $1 sin límite preestablecido",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "Establecer un límite de gasto para su $1",
"description": "$1 is a token symbol"
},
"settings": {
"message": "Configuración"
},
@ -4167,9 +4160,6 @@
"urlExistsErrorMsg": {
"message": "En este momento, la red $1 está utilizando esta dirección URL."
},
"useDefault": {
"message": "Uso por defecto"
},
"useMultiAccountBalanceChecker": {
"message": "Solicitudes de saldo de cuenta por lotes"
},

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "Révéler la phrase mnémonique"
},
"reviewSpendingCap": {
"message": "Modifiez votre plafond de dépenses"
},
"revokeAllTokensTitle": {
"message": "Révoquer lautorisation daccès et de transfert de tous vos $1 ?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3140,10 +3137,6 @@
"message": "Approuver $1 sans limite de dépenses",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "Fixez un plafond de dépenses pour vos $1",
"description": "$1 is a token symbol"
},
"settings": {
"message": "Paramètres"
},
@ -4167,9 +4160,6 @@
"urlExistsErrorMsg": {
"message": "Cette URL est actuellement utilisée par le réseau $1."
},
"useDefault": {
"message": "Utiliser par défaut"
},
"useMultiAccountBalanceChecker": {
"message": "Demandes dinformations concernant le solde de plusieurs comptes"
},

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "सीड फ़्रेज़ दिखाएं"
},
"reviewSpendingCap": {
"message": "अपनी खर्च के सीमा की समीक्षा करें"
},
"revokeAllTokensTitle": {
"message": "आपके सभी $1 को एक्सेस और स्थानांतरित करने की अनुमति निरस्त करें?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3140,10 +3137,6 @@
"message": "बिना किसी खर्च सीमा के $1 स्वीकृत करें",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "अपने $1 के लिए खर्च की सीमा को निर्धारित करें",
"description": "$1 is a token symbol"
},
"settings": {
"message": "सेटिंग"
},
@ -4167,9 +4160,6 @@
"urlExistsErrorMsg": {
"message": "यह URL वर्तमान में $1 नेटवर्क द्वारा उपयोग किया जाता है।"
},
"useDefault": {
"message": "डिफॉल्ट का उपयोग करें"
},
"useMultiAccountBalanceChecker": {
"message": "खाता के शेष राशि के अनुरोधों को बैच करें"
},

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "Ungkap frasa seed"
},
"reviewSpendingCap": {
"message": "Tinjau batas pengeluaran Anda"
},
"revokeAllTokensTitle": {
"message": "Cabut izin untuk mengakses dan mentransfer seluruh $1 Anda?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3140,10 +3137,6 @@
"message": "Setujui $1 tanpa batas penggunaan",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "Tetapkan batas pengeluaran untuk $1",
"description": "$1 is a token symbol"
},
"settings": {
"message": "Pengaturan"
},
@ -4167,9 +4160,6 @@
"urlExistsErrorMsg": {
"message": "URL ini saat ini digunakan oleh jaringan $1."
},
"useDefault": {
"message": "Gunakan default"
},
"useMultiAccountBalanceChecker": {
"message": "Kelompokkan permintaan saldo akun"
},

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "シードフレーズを表示"
},
"reviewSpendingCap": {
"message": "使用上限を確認してください"
},
"revokeAllTokensTitle": {
"message": "すべての $1 へのアクセスおよび転送許可を取り消しますか?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3140,10 +3137,6 @@
"message": "使用限度額なしで $1 を承認",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "$1 の使用上限を設定",
"description": "$1 is a token symbol"
},
"settings": {
"message": "設定"
},
@ -4167,9 +4160,6 @@
"urlExistsErrorMsg": {
"message": "このURLは現在$1ネットワークで使用されています。"
},
"useDefault": {
"message": "既定値を使用"
},
"useMultiAccountBalanceChecker": {
"message": "アカウント残高の一括リクエスト"
},

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "시드 구문 보기"
},
"reviewSpendingCap": {
"message": "지출 한도 검토"
},
"revokeAllTokensTitle": {
"message": "모든 $1에 액세스할 수 있는 권한을 철회할까요?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3140,10 +3137,6 @@
"message": "$1 무제한 지출 승인",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "$1에 대한 지출 한도 설정",
"description": "$1 is a token symbol"
},
"settings": {
"message": "설정"
},
@ -4167,9 +4160,6 @@
"urlExistsErrorMsg": {
"message": "이 URL은 현재 $1 네트워크에서 사용됩니다."
},
"useDefault": {
"message": "기본값 사용"
},
"useMultiAccountBalanceChecker": {
"message": "일괄 계정 잔액 요청"
},

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "Revelar a frase de recuperação"
},
"reviewSpendingCap": {
"message": "Revise seu limite de gastos"
},
"revokeAllTokensTitle": {
"message": "Revogar permissão de acesso e transferência de todos os seus $1?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3140,10 +3137,6 @@
"message": "Aprovar $1 sem limite de gastos",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "Definir um limite de gastos para seu $1",
"description": "$1 is a token symbol"
},
"settings": {
"message": "Definições"
},
@ -4167,9 +4160,6 @@
"urlExistsErrorMsg": {
"message": "O ID da cadeia está sendo usado pela rede $1."
},
"useDefault": {
"message": "Usar padrão"
},
"useMultiAccountBalanceChecker": {
"message": "Agrupar solicitações de saldo de contas"
},

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "Показать сид-фразу"
},
"reviewSpendingCap": {
"message": "Проверьте свой лимит расходов"
},
"revokeAllTokensTitle": {
"message": "Отозвать разрешение на доступ ко всем вашим $1 и их перевод?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3140,10 +3137,6 @@
"message": "Одобрить $1 без ограничений по расходам",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "Установить верхний лимит расходов для вашего $1",
"description": "$1 is a token symbol"
},
"settings": {
"message": "Настройки"
},
@ -4167,9 +4160,6 @@
"urlExistsErrorMsg": {
"message": "Это URL-адрес в настоящее время используется сетью $1."
},
"useDefault": {
"message": "Использовать значения по умолчанию"
},
"useMultiAccountBalanceChecker": {
"message": "Пакетные запросы баланса счета"
},

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "Ipakita ang seed phrase"
},
"reviewSpendingCap": {
"message": "I-review ang iyong limitasyon sa paggastos"
},
"revokeAllTokensTitle": {
"message": "Bawiin ang pahintulot na i-access at ilipat ang lahat ng iyong $1?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3140,10 +3137,6 @@
"message": "Aprubahan ang $1 nang walang limitasyon sa paggastos",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "Magtakda ng limitasyon sa paggastos para sa iyong $1",
"description": "$1 is a token symbol"
},
"settings": {
"message": "Mga Setting"
},
@ -4167,9 +4160,6 @@
"urlExistsErrorMsg": {
"message": "Nasa kasalukuyang listahan ng mga network na ang URL."
},
"useDefault": {
"message": "Gamitin ang default"
},
"useMultiAccountBalanceChecker": {
"message": "Mga kahilingan sa balanse ng batch account"
},

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "Tohum ifadesini ortaya çıkar"
},
"reviewSpendingCap": {
"message": "Harcama üst limitinize göz atın"
},
"revokeAllTokensTitle": {
"message": "Tüm $1 için izin erişim ve transfer izni geri çekilsin mi?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3140,10 +3137,6 @@
"message": "$1 için harcama limiti olmadan onay ver",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "$1 için harcama üst limiti belirle",
"description": "$1 is a token symbol"
},
"settings": {
"message": "Ayarlar"
},
@ -4167,9 +4160,6 @@
"urlExistsErrorMsg": {
"message": "Bu URL şu anda $1 ağı tarafından kullanılıyor."
},
"useDefault": {
"message": "Varsayılanı kullan"
},
"useMultiAccountBalanceChecker": {
"message": "Toplu hesap bakiyesi talepleri"
},

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "Hiện cụm từ khôi phục bí mật"
},
"reviewSpendingCap": {
"message": "Xem lại hạn mức chi tiêu của bạn"
},
"revokeAllTokensTitle": {
"message": "Thu hồi quyền truy cập và chuyển tất cả $1 của bạn?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3140,10 +3137,6 @@
"message": "Phê duyệt $1 không có giới hạn chi tiêu",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "Đặt hạn mức chi tiêu cho $1 của bạn",
"description": "$1 is a token symbol"
},
"settings": {
"message": "Cài đặt"
},
@ -4167,9 +4160,6 @@
"urlExistsErrorMsg": {
"message": "Mạng $1 hiện đang sử dụng URL này."
},
"useDefault": {
"message": "Sử dụng mặc định"
},
"useMultiAccountBalanceChecker": {
"message": "Xử lý hàng loạt yêu cầu số dư tài khoản"
},

View File

@ -2956,9 +2956,6 @@
"revealTheSeedPhrase": {
"message": "显示助记词"
},
"reviewSpendingCap": {
"message": "检查您的支出上限"
},
"revokeAllTokensTitle": {
"message": "撤销访问和转移您的所有 $1 的权限?",
"description": "$1 is the symbol of the token for which the user is revoking approval"
@ -3140,10 +3137,6 @@
"message": "批准$1且无消费限制",
"description": "The token symbol that is being approved"
},
"setSpendingCap": {
"message": "为 $1 设置支出上限",
"description": "$1 is a token symbol"
},
"settings": {
"message": "设置"
},
@ -4167,9 +4160,6 @@
"urlExistsErrorMsg": {
"message": "此 URL 目前已被 $1 网络使用。"
},
"useDefault": {
"message": "使用默认值"
},
"useMultiAccountBalanceChecker": {
"message": "账户余额分批请求"
},

View File

@ -129,10 +129,6 @@ describe('Create token, approve token and approve token without gas', function (
text: 'Got it',
tag: 'button',
});
await driver.clickElement({
text: 'Use default',
css: '.mm-button-link',
});
await driver.clickElement({
text: 'View details',
css: '.token-allowance-container__view-details',
@ -157,17 +153,17 @@ describe('Create token, approve token and approve token without gas', function (
await driver.clickElement({ text: 'Next', tag: 'button' });
await driver.findElement({
text: 'Review the spending cap for your',
tag: 'div',
text: 'Spending cap request for your ',
css: '.box--flex-direction-row',
});
const defaultSpendingCup = await driver.findElement({
const defaultSpendingCap = await driver.findElement({
text: '7 TST',
css: '.box--flex-direction-row > h6',
});
assert.equal(
await defaultSpendingCup.getText(),
await defaultSpendingCap.getText(),
'7 TST',
'Default value is not correctly set',
);
@ -253,13 +249,13 @@ describe('Create token, approve token and approve token without gas', function (
tag: 'button',
});
let spendingCup = await driver.findElement({
let spendingCap = await driver.findElement({
text: '5 TST',
css: '.box--flex-direction-row > h6',
});
assert.equal(
await spendingCup.getText(),
await spendingCap.getText(),
'5 TST',
'Default value is not correctly set',
);
@ -309,12 +305,12 @@ describe('Create token, approve token and approve token without gas', function (
tag: 'button',
});
spendingCup = await driver.findElement({
spendingCap = await driver.findElement({
text: '9 TST',
css: '.box--flex-direction-row > h6',
});
assert.equal(
await spendingCup.getText(),
await spendingCap.getText(),
'9 TST',
'Default value is not correctly set',
);
@ -429,7 +425,7 @@ describe('Create token, approve token and approve token without gas', function (
);
});
it('approves token without gas, set default spending cap, submits the transaction and finds the transaction in the transactions list', async function () {
it('approves token without gas, set site suggested spending cap, submits the transaction and finds the transaction in the transactions list', async function () {
await withFixtures(
{
dapp: true,
@ -465,9 +461,16 @@ describe('Create token, approve token and approve token without gas', function (
const pendingTxes = await driver.findElements('.transaction-list-item');
pendingTxes[0].click();
// set spending cap
// set custom spending cap
const spendingCap = await driver.findElement(
'[data-testid="custom-spending-cap-input"]',
);
await spendingCap.fill('5');
// set site suggested spending cap
await driver.clickElement({
text: 'Use default',
text: 'Use site suggestion',
css: '.mm-button-link',
});
await driver.clickElement({

View File

@ -51,15 +51,6 @@ exports[`CustomSpendingCap should match snapshot 1`] = `
</div>
</div>
</div>
<div
class="mm-box form-field__heading-detail mm-box--margin-right-0 mm-box--margin-bottom-2 mm-box--text-align-end"
>
<button
class="box mm-text mm-button-base mm-button-link mm-button-link--size-auto mm-text--body-md box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-default box--background-color-transparent"
>
Use default
</button>
</div>
</div>
<input
class="form-field__input"
@ -67,7 +58,7 @@ exports[`CustomSpendingCap should match snapshot 1`] = `
id="custom-spending-cap"
placeholder="Enter a number"
type="text"
value="10"
value="7"
/>
</div>
@ -85,7 +76,7 @@ exports[`CustomSpendingCap should match snapshot 1`] = `
class="box custom-spending-cap__description box--flex-direction-row"
>
<h6
class="box mm-text mm-text--body-sm box--padding-top-2 box--padding-bottom-2 box--flex-direction-row box--color-text-default"
class="box mm-text mm-text--body-sm box--padding-top-2 box--flex-direction-row box--color-text-default"
>
<span>
@ -93,7 +84,7 @@ exports[`CustomSpendingCap should match snapshot 1`] = `
<h6
class="box mm-text custom-spending-cap__input-value-and-token-name mm-text--body-sm-bold box--flex-direction-row box--color-text-default"
>
10
7
TST
</h6>
@ -101,6 +92,13 @@ exports[`CustomSpendingCap should match snapshot 1`] = `
</span>
</h6>
<a
class="box mm-text mm-button-base mm-button-base--size-sm mm-button-link mm-text--body-md box--margin-bottom-2 box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-default box--background-color-transparent"
href="https://support.metamask.io/hc/en-us/articles/6055177143579-How-to-customize-token-approvals-with-a-spending-cap"
target="_blank"
>
Learn more
</a>
</div>
</label>
</div>

View File

@ -1,5 +1,5 @@
import React, { useState, useContext, useEffect, useRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useDispatch } from 'react-redux';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import BigNumber from 'bignumber.js';
@ -21,7 +21,6 @@ import {
BackgroundColor,
TextColor,
} from '../../../helpers/constants/design-system';
import { getCustomTokenAmount } from '../../../selectors';
import { setCustomTokenAmount } from '../../../ducks/app/app';
import { calcTokenAmount } from '../../../../shared/lib/transactions-controller-utils';
import { hexToDecimal } from '../../../../shared/modules/conversion.utils';
@ -34,6 +33,7 @@ import { Numeric } from '../../../../shared/modules/Numeric';
import { estimateGas } from '../../../store/actions';
import { getCustomTxParamsData } from '../../../pages/confirm-approve/confirm-approve.util';
import { useGasFeeContext } from '../../../contexts/gasFee';
import ZENDESK_URLS from '../../../helpers/constants/zendesk-url';
import { CustomSpendingCapTooltip } from './custom-spending-cap-tooltip';
export default function CustomSpendingCap({
@ -45,18 +45,17 @@ export default function CustomSpendingCap({
passTheErrorText,
decimals,
setInputChangeInProgress,
customSpendingCap,
setCustomSpendingCap,
}) {
const t = useContext(I18nContext);
const dispatch = useDispatch();
const { updateTransaction } = useGasFeeContext();
const inputRef = useRef(null);
const value = useSelector(getCustomTokenAmount);
const [error, setError] = useState('');
const [showUseDefaultButton, setShowUseDefaultButton] = useState(
value !== String(dappProposedValue) && true,
);
const [showUseSiteSuggestionButton, setShowUseSiteSuggestionButton] =
useState(customSpendingCap !== String(dappProposedValue) && true);
const inputLogicEmptyStateText = t('inputLogicEmptyState');
const replaceCommaToDot = (inputValue) => {
@ -102,7 +101,7 @@ export default function CustomSpendingCap({
};
const [customSpendingCapText, setCustomSpendingCapText] = useState(
getInputTextLogic(value).description,
getInputTextLogic(customSpendingCap).description,
);
const handleChange = async (valueInput) => {
@ -139,37 +138,42 @@ export default function CustomSpendingCap({
setError(spendingCapError);
}
}
setCustomSpendingCap(String(valueInput));
dispatch(setCustomTokenAmount(String(valueInput)));
try {
const newData = getCustomTxParamsData(txParams.data, {
customPermissionAmount: valueInput,
decimals,
});
const { from, to, value: txValue } = txParams;
const estimatedGasLimit = await estimateGas({
from,
to,
value: txValue,
data: newData,
});
if (estimatedGasLimit) {
await updateTransaction({
gasLimit: hexToDecimal(addHexPrefix(estimatedGasLimit)),
if (String(valueInput) !== '') {
try {
const newData = getCustomTxParamsData(txParams.data, {
customPermissionAmount: valueInput,
decimals,
});
const { from, to, value: txValue } = txParams;
const estimatedGasLimit = await estimateGas({
from,
to,
value: txValue,
data: newData,
});
if (estimatedGasLimit) {
await updateTransaction({
gasLimit: hexToDecimal(addHexPrefix(estimatedGasLimit)),
});
}
} catch (exp) {
console.error('Error in trying to update gas limit', exp);
}
} catch (exp) {
console.error('Error in trying to update gas limit', exp);
}
setInputChangeInProgress(false);
};
useEffect(() => {
if (value !== String(dappProposedValue)) {
setShowUseDefaultButton(true);
if (customSpendingCap === String(dappProposedValue)) {
setShowUseSiteSuggestionButton(false);
} else {
setShowUseSiteSuggestionButton(true);
}
}, [value, dappProposedValue]);
}, [customSpendingCap, dappProposedValue]);
useEffect(() => {
passTheErrorText(error);
@ -185,7 +189,7 @@ export default function CustomSpendingCap({
}, [inputRef.current]);
const chooseTooltipContentText = decConversionGreaterThan(
value,
customSpendingCap,
currentTokenBalance,
)
? t('warningTooltipText', [
@ -221,7 +225,7 @@ export default function CustomSpendingCap({
>
<label
htmlFor={
decConversionGreaterThan(value, currentTokenBalance)
decConversionGreaterThan(customSpendingCap, currentTokenBalance)
? 'custom-spending-cap-input-value'
: 'custom-spending-cap'
}
@ -231,18 +235,23 @@ export default function CustomSpendingCap({
dataTestId="custom-spending-cap-input"
wrappingLabelProps={{ as: 'div' }}
id={
decConversionGreaterThan(value, currentTokenBalance)
decConversionGreaterThan(customSpendingCap, currentTokenBalance)
? 'custom-spending-cap-input-value'
: 'custom-spending-cap'
}
TooltipCustomComponent={
<CustomSpendingCapTooltip
tooltipContentText={
replaceCommaToDot(value) ? chooseTooltipContentText : ''
replaceCommaToDot(customSpendingCap)
? chooseTooltipContentText
: ''
}
tooltipIcon={
replaceCommaToDot(value)
? decConversionGreaterThan(value, currentTokenBalance)
replaceCommaToDot(customSpendingCap)
? decConversionGreaterThan(
customSpendingCap,
currentTokenBalance,
)
: ''
}
/>
@ -251,18 +260,18 @@ export default function CustomSpendingCap({
titleText={t('customSpendingCap')}
placeholder={t('enterANumber')}
error={error}
value={value}
value={customSpendingCap}
titleDetail={
showUseDefaultButton && (
showUseSiteSuggestionButton && (
<ButtonLink
size={Size.auto}
onClick={(e) => {
e.preventDefault();
setShowUseDefaultButton(false);
setShowUseSiteSuggestionButton(false);
handleChange(dappProposedValue);
}}
>
{t('useDefault')}
{t('useSiteSuggestion')}
</ButtonLink>
)
}
@ -298,12 +307,19 @@ export default function CustomSpendingCap({
variant={TextVariant.bodySm}
as="h6"
paddingTop={2}
paddingBottom={2}
>
{replaceCommaToDot(value)
{replaceCommaToDot(customSpendingCap)
? customSpendingCapText
: inputLogicEmptyStateText}
</Text>
<ButtonLink
size={Size.SM}
href={ZENDESK_URLS.TOKEN_ALLOWANCE_WITH_SPENDING_CAP}
target="_blank"
marginBottom={2}
>
{t('learnMoreUpperCase')}
</ButtonLink>
</Box>
</label>
</Box>
@ -345,4 +361,12 @@ CustomSpendingCap.propTypes = {
* Updating input state to changing
*/
setInputChangeInProgress: PropTypes.func.isRequired,
/**
* Custom token amount or The dapp suggested amount
*/
customSpendingCap: PropTypes.string,
/**
* State method to update the custom token value
*/
setCustomSpendingCap: PropTypes.func.isRequired,
};

View File

@ -23,6 +23,9 @@ export default {
decimals: {
control: 'text',
},
customSpendingCap: {
control: { type: 'text' },
},
},
args: {
tokenName: 'DAI',
@ -30,6 +33,7 @@ export default {
dappProposedValue: '7',
siteOrigin: 'Uniswap.org',
decimals: '4',
customSpendingCap: '7',
},
};
@ -38,3 +42,13 @@ export const DefaultStory = (args) => {
};
DefaultStory.storyName = 'Default';
export const CustomSpendingCapStory = (args) => {
return <CustomSpendingCap {...args} />;
};
CustomSpendingCapStory.storyName = 'CustomSpendingCapStory';
CustomSpendingCapStory.args = {
...DefaultStory.args,
customSpendingCap: '8',
};

View File

@ -26,6 +26,8 @@ const props = {
decimals: '4',
passTheErrorText: () => undefined,
setInputChangeInProgress: () => undefined,
customSpendingCap: '7',
setCustomSpendingCap: () => undefined,
};
describe('CustomSpendingCap', () => {

View File

@ -63,7 +63,7 @@ export default function ReviewSpendingCap({
as="h6"
display={DISPLAY.INLINE_BLOCK}
>
{t('customSpendingCap')}
{t('dappRequestedSpendingCap')}
</Text>
<Box marginLeft={2} display={DISPLAY.INLINE_BLOCK}>
<Tooltip

View File

@ -28,6 +28,8 @@ const ZENDESK_URLS = {
'https://metamask.zendesk.com/hc/en-us/articles/360059952212-MetaMask-is-a-non-custodial-wallet',
SPEEDUP_CANCEL:
'https://metamask.zendesk.com/hc/en-us/articles/360015489251-How-to-speed-up-or-cancel-a-pending-transaction',
TOKEN_ALLOWANCE_WITH_SPENDING_CAP:
'https://support.metamask.io/hc/en-us/articles/6055177143579-How-to-customize-token-approvals-with-a-spending-cap',
TOKEN_SAFETY_PRACTICES:
'https://metamask.zendesk.com/hc/en-us/articles/4403988839451',
UNKNOWN_NETWORK:

View File

@ -0,0 +1,489 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TokenAllowancePage should match snapshot 1`] = `
<div>
<div
class="box token-allowance-container page-container box--flex-direction-row"
>
<div
class="box box--flex-direction-row"
>
<div
class="confirm-page-container-navigation"
style="display: none;"
>
<div
class="confirm-page-container-navigation__container"
data-testid="navigation-container"
style="visibility: hidden;"
>
<button
class="confirm-page-container-navigation__arrow"
data-testid="first-page"
>
<i
class="fa fa-angle-double-left fa-2x"
/>
</button>
<button
class="confirm-page-container-navigation__arrow"
data-testid="previous-page"
>
<i
class="fa fa-angle-left fa-2x"
/>
</button>
</div>
<div
class="confirm-page-container-navigation__textcontainer"
>
<div
class="confirm-page-container-navigation__navtext"
>
0
of
0
</div>
<div
class="confirm-page-container-navigation__longtext"
>
requests waiting to be acknowledged
</div>
</div>
<div
class="confirm-page-container-navigation__container"
style="visibility: hidden;"
>
<button
class="confirm-page-container-navigation__arrow"
data-testid="next-page"
>
<i
class="fa fa-angle-right fa-2x"
/>
</button>
<button
class="confirm-page-container-navigation__arrow"
data-testid="last-page"
>
<i
class="fa fa-angle-double-right fa-2x"
/>
</button>
</div>
</div>
</div>
<div
class="box box--padding-right-4 box--padding-left-4 box--display-flex box--flex-direction-row box--justify-content-space-between box--align-items-center"
>
<div
class="box box--flex-direction-row"
/>
<div
class="box box--flex-direction-row box--text-align-end"
>
<h6
class="box mm-text mm-text--body-sm mm-text--font-weight-bold box--flex-direction-row box--color-text-muted"
>
1
of
2
</h6>
</div>
</div>
<div
class="box network-account-balance-header box--padding-4 box--display-flex box--flex-direction-row box--justify-content-space-between box--align-items-center"
>
<div
class="box box--display-flex box--gap-2 box--flex-direction-row box--align-items-center"
>
<div
class="box box--display-flex box--flex-direction-row box--align-items-center"
>
<div
class=""
>
<div
class="identicon"
style="height: 32px; width: 32px; border-radius: 16px;"
>
<div
style="border-radius: 50px; overflow: hidden; padding: 0px; margin: 0px; width: 32px; height: 32px; display: inline-block; background: rgb(250, 58, 0);"
>
<svg
height="32"
width="32"
x="0"
y="0"
>
<rect
fill="#18CDF2"
height="32"
transform="translate(-1.04839350379394 -3.3042840694604987) rotate(328.9 16 16)"
width="32"
x="0"
y="0"
/>
<rect
fill="#035E56"
height="32"
transform="translate(-18.298461708832043 10.5924618717486) rotate(176.2 16 16)"
width="32"
x="0"
y="0"
/>
<rect
fill="#F26602"
height="32"
transform="translate(16.667842018223922 -14.205139722997082) rotate(468.9 16 16)"
width="32"
x="0"
y="0"
/>
</svg>
</div>
</div>
</div>
<div
class="network-account-balance-header__network-account__ident-icon-ethereum--gray"
>
<span
class="icon-with-fallback__fallback"
>
M
</span>
</div>
</div>
<div
class="box box--display-flex box--flex-direction-column box--align-items-flex-start"
>
<h6
class="box mm-text mm-text--body-sm box--flex-direction-row box--color-text-alternative"
>
mainnet
</h6>
<h6
class="box mm-text mm-text--body-sm mm-text--font-weight-bold box--flex-direction-row box--color-text-default"
>
Account 1
</h6>
</div>
</div>
<div
class="box box--display-flex box--flex-direction-column box--align-items-flex-end"
>
<h6
class="box mm-text mm-text--body-sm box--flex-direction-row box--color-text-alternative"
>
Balance
</h6>
<h6
align="end"
class="box mm-text mm-text--body-sm mm-text--font-weight-bold box--flex-direction-row box--color-text-default"
>
10
TST
</h6>
</div>
</div>
<div
class="box box--display-flex box--flex-direction-row box--justify-content-center"
>
<div
class="box token-allowance-container__icon-display-content box--margin-top-6 box--margin-right-12 box--margin-bottom-8 box--margin-left-12 box--padding-top-2 box--padding-right-4 box--padding-bottom-2 box--padding-left-2 box--display-flex box--flex-direction-row box--align-items-center box--border-style-solid box--border-color-border-muted box--border-width-1"
>
<div
class=""
>
<img
alt="https://metamask.github.io"
class="url-icon token-allowance-container__icon-display-content__siteimage-identicon"
src="https://metamask.github.io/test-dapp/metamask-fox.svg"
/>
</div>
<h6
class="box mm-text mm-text--body-sm box--margin-left-1 box--flex-direction-row box--color-text-alternative"
>
https://metamask.github.io
</h6>
</div>
</div>
<div
class="box box--margin-right-4 box--margin-left-4 box--flex-direction-row"
>
<h3
align="center"
class="box mm-text mm-text--heading-md box--flex-direction-row box--color-text-default"
>
<span>
Spending cap request for your
<div
class="box box--margin-top-4 box--flex-direction-row"
>
<div
class="box contract-token-values box--display-flex box--gap-2 box--flex-direction-row box--justify-content-center box--align-items-center"
>
<div
class=""
>
<div
class="identicon"
style="height: 24px; width: 24px; border-radius: 12px;"
>
<div
style="border-radius: 50px; overflow: hidden; padding: 0px; margin: 0px; width: 24px; height: 24px; display: inline-block; background: rgb(242, 206, 2);"
>
<svg
height="24"
width="24"
x="0"
y="0"
>
<rect
fill="#186FF2"
height="24"
transform="translate(4.5535541527659795 -0.012406777909352561) rotate(501.9 12 12)"
width="24"
x="0"
y="0"
/>
<rect
fill="#F97101"
height="24"
transform="translate(-10.003810991077078 6.326210026231173) rotate(323.7 12 12)"
width="24"
x="0"
y="0"
/>
<rect
fill="#FB1832"
height="24"
transform="translate(-22.151479903389234 -4.322407331572157) rotate(370.5 12 12)"
width="24"
x="0"
y="0"
/>
</svg>
</div>
</div>
</div>
<h2
class="box box--flex-direction-row typography typography--h2 typography--weight-bold typography--style-normal typography--color-text-alternative"
>
TST
</h2>
<div>
<div
aria-describedby="tippy-tooltip-1"
class=""
data-original-title="Copy to clipboard"
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<button
aria-label="Copy to clipboard"
class="box mm-button-icon mm-button-icon--size-lg box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-icon-muted box--background-color-transparent box--rounded-lg"
>
<span
class="box mm-icon mm-icon--size-lg box--display-inline-block box--flex-direction-row box--color-inherit"
style="mask-image: url('./images/icons/copy.svg');"
/>
</button>
</div>
</div>
<div>
<div
aria-describedby="tippy-tooltip-2"
class=""
data-original-title="Open in block explorer"
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<button
aria-label="Open in block explorer"
class="box mm-button-icon mm-button-icon--size-lg box--display-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-icon-muted box--background-color-transparent box--rounded-lg"
>
<span
class="box mm-icon mm-icon--size-lg box--display-inline-block box--flex-direction-row box--color-inherit"
style="mask-image: url('./images/icons/export.svg');"
/>
</button>
</div>
</div>
</div>
</div>
</span>
</h3>
</div>
<div
class="box box--margin-top-1 box--display-flex box--flex-direction-row box--justify-content-center"
>
<a
class="button btn-link token-allowance-container__verify-link"
role="button"
tabindex="0"
>
<h6
class="box mm-text mm-text--body-sm box--flex-direction-row box--color-primary-default"
>
Verify third-party details
</h6>
</a>
</div>
<div
class="box box--margin-4 box--sm:margin-4 box--md:margin-3 box--lg:margin-4 box--flex-direction-row"
>
<div
class="box custom-spending-cap box--padding-top-2 box--padding-right-6 box--padding-left-6 box--display-flex box--gap-2 box--flex-direction-column box--align-items-flex-start box--background-color-background-alternative box--rounded-sm"
>
<div
class="box custom-spending-cap__input box--display-block box--flex-direction-row box--justify-content-center"
>
<label
for="custom-spending-cap"
>
<div
class="form-field"
>
<div
class="mm-box"
>
<div
class="form-field__heading"
>
<div
class="mm-box form-field__heading-title mm-box--display-flex mm-box--align-items-baseline"
>
<h6
class="box mm-text mm-text--body-sm-bold box--display-inline-block box--flex-direction-row box--color-text-default"
for="custom-spending-cap"
tag="label"
>
Custom spending cap
</h6>
<div
class="box box--display-inline-block box--flex-direction-row"
>
<div>
<div
aria-describedby="tippy-tooltip-3"
class=""
data-original-title="null"
data-tooltipped=""
style="display: inline;"
tabindex="0"
>
<span
class="box mm-icon mm-icon--size-inherit box--display-inline-block box--flex-direction-row box--color-inherit"
style="mask-image: url('./images/icons/question.svg');"
/>
</div>
</div>
</div>
</div>
</div>
<input
class="form-field__input"
data-testid="custom-spending-cap-input"
id="custom-spending-cap"
placeholder="Enter a number"
type="text"
value="7"
/>
</div>
</div>
<div
class="box custom-spending-cap__max box--margin-left-auto box--padding-right-4 box--padding-bottom-2 box--flex-direction-row box--text-align-end box--width-max"
>
<button
class="box mm-text mm-button-base mm-button-link mm-button-link--size-auto mm-text--body-md box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-default box--background-color-transparent"
>
Max
</button>
</div>
<div
class="box custom-spending-cap__description box--flex-direction-row"
>
<h6
class="box mm-text mm-text--body-sm box--padding-top-2 box--flex-direction-row box--color-text-default"
>
<span>
This allows the third party to spend
<h6
class="box mm-text custom-spending-cap__input-value-and-token-name mm-text--body-sm-bold box--flex-direction-row box--color-text-default"
>
7
TST
</h6>
from your current balance.
</span>
</h6>
<a
class="box mm-text mm-button-base mm-button-base--size-sm mm-button-link mm-text--body-md box--margin-bottom-2 box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-default box--background-color-transparent"
href="https://support.metamask.io/hc/en-us/articles/6055177143579-How-to-customize-token-approvals-with-a-spending-cap"
target="_blank"
>
Learn more
</a>
</div>
</label>
</div>
</div>
</div>
<div
class="box box--display-flex box--flex-direction-row box--justify-content-center"
>
<a
class="button btn-link token-allowance-container__view-details"
role="button"
tabindex="0"
>
<h6
class="box mm-text mm-text--body-sm box--margin-right-1 box--flex-direction-row box--color-primary-default"
>
View details
</h6>
<i
class="fa fa-sm fa-angle-down"
/>
</a>
</div>
<div
class="page-container__footer"
>
<footer>
<button
class="button btn--rounded btn-secondary page-container__footer-button page-container__footer-button__cancel"
data-testid="page-container-footer-cancel"
role="button"
tabindex="0"
>
Reject
</button>
<button
class="button btn--rounded btn-primary page-container__footer-button"
data-testid="page-container-footer-next"
role="button"
tabindex="0"
>
Next
</button>
</footer>
</div>
</div>
</div>
`;

View File

@ -29,7 +29,6 @@ import {
transactionFeeSelector,
getKnownMethodData,
getRpcPrefsForCurrentProvider,
getCustomTokenAmount,
getUnapprovedTxCount,
getUnapprovedTransactions,
getUseCurrencyRateCheck,
@ -101,6 +100,9 @@ export default function TokenAllowance({
const { hostname } = new URL(origin);
const thisOriginIsAllowedToSkipFirstPage = ALLOWED_HOSTS.includes(hostname);
const [customSpendingCap, setCustomSpendingCap] = useState(
dappProposedTokenAmount,
);
const [showContractDetails, setShowContractDetails] = useState(false);
const [inputChangeInProgress, setInputChangeInProgress] = useState(false);
const [showFullTxDetails, setShowFullTxDetails] = useState(false);
@ -122,24 +124,20 @@ export default function TokenAllowance({
const unapprovedTxCount = useSelector(getUnapprovedTxCount);
const unapprovedTxs = useSelector(getUnapprovedTransactions);
const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck);
let customTokenAmount = useSelector(getCustomTokenAmount);
if (thisOriginIsAllowedToSkipFirstPage && dappProposedTokenAmount) {
customTokenAmount = dappProposedTokenAmount;
}
const replaceCommaToDot = (inputValue) => {
return inputValue.replace(/,/gu, '.');
};
let customPermissionAmount = NUM_W_OPT_DECIMAL_COMMA_OR_DOT_REGEX.test(
customTokenAmount,
customSpendingCap,
)
? replaceCommaToDot(customTokenAmount).toString()
? replaceCommaToDot(customSpendingCap).toString()
: '0';
const maxTokenAmount = calcTokenAmount(MAX_TOKEN_ALLOWANCE_AMOUNT, decimals);
if (customTokenAmount.length > 1 && Number(customTokenAmount)) {
const customSpendLimitNumber = new BigNumber(customTokenAmount);
if (customSpendingCap.length > 1 && Number(customSpendingCap)) {
const customSpendLimitNumber = new BigNumber(customSpendingCap);
if (customSpendLimitNumber.greaterThan(maxTokenAmount)) {
customPermissionAmount = 0;
}
@ -170,7 +168,7 @@ export default function TokenAllowance({
const { balanceError } = useGasFeeContext();
const disableNextButton =
isFirstPage && (customTokenAmount === '' || errorText !== '');
isFirstPage && (customSpendingCap === '' || errorText !== '');
const disableApproveButton = !isFirstPage && balanceError;
@ -212,9 +210,9 @@ export default function TokenAllowance({
fullTxData.originalApprovalAmount = dappProposedTokenAmount;
}
if (customTokenAmount) {
fullTxData.customTokenAmount = customTokenAmount;
fullTxData.finalApprovalAmount = customTokenAmount;
if (customSpendingCap) {
fullTxData.customTokenAmount = customSpendingCap;
fullTxData.finalApprovalAmount = customSpendingCap;
} else if (dappProposedTokenAmount !== undefined) {
fullTxData.finalApprovalAmount = dappProposedTokenAmount;
}
@ -255,7 +253,7 @@ export default function TokenAllowance({
);
};
const isEmpty = customTokenAmount === '';
const isEmpty = customSpendingCap === '';
const renderContractTokenValues = (
<Box marginTop={4} key={tokenAddress}>
@ -359,17 +357,12 @@ export default function TokenAllowance({
<Box marginLeft={4} marginRight={4}>
<Text variant={TextVariant.headingMd} align={TextAlign.Center}>
{isFirstPage ? (
t('setSpendingCap', [renderContractTokenValues])
t('spendingCapRequest', [renderContractTokenValues])
) : (
<Box>
{customTokenAmount === '0' || isEmpty ? (
t('revokeSpendingCap', [renderContractTokenValues])
) : (
<Box>
{t('reviewSpendingCap')}
{renderContractTokenValues}
</Box>
)}
{customSpendingCap === '0' || isEmpty
? t('revokeSpendingCap', [renderContractTokenValues])
: t('spendingCapRequest', [renderContractTokenValues])}
</Box>
)}
</Text>
@ -405,15 +398,17 @@ export default function TokenAllowance({
passTheErrorText={(value) => setErrorText(value)}
decimals={decimals}
setInputChangeInProgress={setInputChangeInProgress}
customSpendingCap={customSpendingCap}
setCustomSpendingCap={setCustomSpendingCap}
/>
) : (
<ReviewSpendingCap
tokenName={tokenSymbol}
currentTokenBalance={currentTokenBalance}
tokenValue={
isNaN(parseFloat(customTokenAmount))
isNaN(parseFloat(customSpendingCap))
? dappProposedTokenAmount
: replaceCommaToDot(customTokenAmount)
: replaceCommaToDot(customSpendingCap)
}
onEdit={() => handleBackClick()}
/>

View File

@ -187,12 +187,20 @@ describe('TokenAllowancePage', () => {
store = configureMockStore()(state);
});
it('should render title "Set a spending cap for your" in token allowance page', () => {
it('should match snapshot', () => {
const { container } = renderWithProvider(
<TokenAllowance {...props} />,
store,
);
expect(container).toMatchSnapshot();
});
it('should render title "Spending cap request for your" in token allowance page', () => {
const { getByText } = renderWithProvider(
<TokenAllowance {...props} />,
store,
);
expect(getByText('Set a spending cap for your')).toBeInTheDocument();
expect(getByText('Spending cap request for your')).toBeInTheDocument();
});
it('should render reject button', () => {
@ -215,37 +223,55 @@ describe('TokenAllowancePage', () => {
expect(getByText('Function: Approve')).toBeInTheDocument();
});
it('should click Use default and set input value to default', () => {
const { getByText, getByTestId } = renderWithProvider(
it('should load the page with dappProposedAmount prefilled and "Use site suggestion" should not be displayed', () => {
const { queryByText, getByTestId } = renderWithProvider(
<TokenAllowance {...props} />,
store,
);
act(() => {
const useDefault = getByText('Use default');
fireEvent.click(useDefault);
const useSiteSuggestion = queryByText('Use site suggestion');
expect(useSiteSuggestion).not.toBeInTheDocument();
});
const input = getByTestId('custom-spending-cap-input');
expect(input.value).toBe('1');
expect(input.value).toBe('7');
});
it('should call back button when button is clicked and return to previous page', () => {
it('should click Use site suggestion and set input value to default', () => {
const { getByText, getByTestId } = renderWithProvider(
<TokenAllowance {...props} />,
store,
);
const textField = getByTestId('custom-spending-cap-input');
expect(textField.value).toBe('7');
fireEvent.change(textField, { target: { value: '1' } });
expect(textField.value).toBe('1');
act(() => {
const useSiteSuggestion = getByText('Use site suggestion');
expect(useSiteSuggestion).toBeInTheDocument();
fireEvent.click(useSiteSuggestion);
});
expect(textField.value).toBe('7');
});
it('should call back button when button is clicked and return to previous page', () => {
const { getByText } = renderWithProvider(
<TokenAllowance {...props} />,
store,
);
const nextButton = getByText('Next');
fireEvent.click(nextButton);
expect(getByText('Site requested spending cap')).toBeInTheDocument();
const backButton = getByText('< Back');
fireEvent.click(backButton);
expect(getByText('Set a spending cap for your')).toBeInTheDocument();
expect(getByText('Spending cap request for your')).toBeInTheDocument();
});
it('should click Verify third-party details and show popup Third-party details, then close popup', () => {
@ -265,14 +291,11 @@ describe('TokenAllowancePage', () => {
});
it('should show ledger info text if the sending address is ledger', () => {
const { queryByText, getByText, getByTestId } = renderWithProvider(
const { queryByText, getByText } = renderWithProvider(
<TokenAllowance {...props} fromAddressIsLedger />,
store,
);
const textField = getByTestId('custom-spending-cap-input');
fireEvent.change(textField, { target: { value: '1' } });
expect(queryByText('Prior to clicking confirm:')).toBeNull();
const nextButton = getByText('Next');
@ -282,14 +305,11 @@ describe('TokenAllowancePage', () => {
});
it('should not show ledger info text if the sending address is not ledger', () => {
const { queryByText, getByText, getByTestId } = renderWithProvider(
const { queryByText, getByText } = renderWithProvider(
<TokenAllowance {...props} fromAddressIsLedger={false} />,
store,
);
const textField = getByTestId('custom-spending-cap-input');
fireEvent.change(textField, { target: { value: '1' } });
expect(queryByText('Prior to clicking confirm:')).toBeNull();
const nextButton = getByText('Next');