From a8df267f7c7907480fdcb199007d2fc18af371f0 Mon Sep 17 00:00:00 2001 From: vincent-byte-vega <166813270+vincent-byte-vega@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:23:50 +0200 Subject: [PATCH] Version 1.5.0 --- ios/Podfile.lock | 4 +- loc/de-DE.json | 27 + loc/en-GB.json | 27 + loc/en-US.json | 8 + loc/es-ES.json | 27 + loc/fr-FR.json | 27 + loc/it-IT.json | 27 + loc/nl-NL.json | 27 + loc/pt-BR.json | 27 + loc/ru-RU.json | 27 + loc/tr-TR.json | 27 + loc/uk-UA.json | 27 + loc/vi-VN.json | 27 + .../web3Wallet/ethereum/types.ts | 2 + .../utils/adaptEIP712ToDefinitionList.ts | 23 +- .../ethereum/utils/sanitizeEIP712.ts | 26 + package.json | 10 +- src/Navigation.tsx | 5 +- src/Routes.tsx | 6 +- .../lottie/assetMarketDataAnimation.json | 1 + src/components/AnimatedSlides/SimpleSlide.tsx | 16 +- src/components/LargeHeader.tsx | 8 +- src/components/SendReceiveButtons.tsx | 8 +- .../TokenMarketData/GeneralMarketData.tsx | 2 +- .../TokenMarketData/HighLowPriceChange.tsx | 4 +- .../HistoricalAssetPriceChart.tsx | 24 +- .../PriceAndChangeSmallInfo.tsx | 6 +- src/components/TransactionsTokenHeader.tsx | 33 +- src/hooks/useAppInitBlastWelcoming.ts | 23 - src/hooks/useAppInitTasks.ts | 3 + src/hooks/useCommonSnapPoints.ts | 7 +- src/hooks/useDeviceSize.ts | 25 + src/hooks/whatsNewHooks/useIsTaskCompleted.ts | 7 + src/hooks/whatsNewHooks/useWhatsNewQueue.ts | 27 + src/hooks/whatsNewHooks/useWhatsNewTask.ts | 28 + src/realm/RealmContext.tsx | 2 +- src/realm/defi/useDefi.ts | 30 +- src/realm/defi/useDefiMutations.ts | 7 +- src/realm/migrations/index.ts | 1 + .../migrations/migrationsSchemaVersion26.ts | 16 + src/realm/migrations/onMigration.ts | 10 +- src/realm/nfts/useNfts.ts | 2 +- src/realm/realmSchema.ts | 2 +- src/realm/settings/schema.ts | 3 + src/realm/settings/useSettingsByKey.ts | 2 +- src/realm/settings/useSettingsMutations.ts | 8 - src/realm/tokens/useTokens.ts | 24 +- src/realm/transactions/transactionFilters.ts | 4 +- .../transactions/usePendingTransactions.ts | 30 +- src/realm/transactions/useTransactions.ts | 32 +- src/realm/wallets/useWallets.tsx | 14 +- .../components/GenericSignContent.tsx | 19 +- src/screens/BlastWelcoming/index.ts | 1 - src/screens/DebugScreen.tsx | 7 - src/screens/Home/HomeScreen.tsx | 2 - src/screens/Send/utils/getTimeEstimate.ts | 1 + .../Transactions/TransactionsScreen.tsx | 168 +++--- .../Transactions/TransactionsScreenV2.tsx | 243 --------- .../components/TokenMarketDataBottomSheet.tsx | 20 +- src/screens/Transactions/index.ts | 2 +- .../WhatsNewAssetMarketDataScreen.tsx | 88 +++ .../WhatsNewBlastScreen.tsx} | 12 +- src/screens/WhatsNew/index.ts | 2 + src/utils/findFirstNonZeroDecimalIndex.ts | 20 +- src/utils/formatCurrency.ts | 36 +- yarn.lock | 504 ++++++++---------- 66 files changed, 1114 insertions(+), 801 deletions(-) create mode 100644 modules/wallet-connect/web3Wallet/ethereum/utils/sanitizeEIP712.ts create mode 100644 src/assets/lottie/assetMarketDataAnimation.json delete mode 100644 src/hooks/useAppInitBlastWelcoming.ts create mode 100644 src/hooks/useDeviceSize.ts create mode 100644 src/hooks/whatsNewHooks/useIsTaskCompleted.ts create mode 100644 src/hooks/whatsNewHooks/useWhatsNewQueue.ts create mode 100644 src/hooks/whatsNewHooks/useWhatsNewTask.ts create mode 100644 src/realm/migrations/migrationsSchemaVersion26.ts delete mode 100644 src/screens/BlastWelcoming/index.ts delete mode 100644 src/screens/Transactions/TransactionsScreenV2.tsx create mode 100644 src/screens/WhatsNew/WhatsNewAssetMarketDataScreen.tsx rename src/screens/{BlastWelcoming/BlastWelcomingScreen.tsx => WhatsNew/WhatsNewBlastScreen.tsx} (86%) create mode 100644 src/screens/WhatsNew/index.ts diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 8f66d10..e6cc601 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -373,7 +373,7 @@ PODS: - glog - react-native-blur (4.3.2): - React-Core - - react-native-compat (2.12.2): + - react-native-compat (2.13.3): - RCT-Folly (= 2021.07.22.00) - React-Core - react-native-config (1.5.1): @@ -908,7 +908,7 @@ SPEC CHECKSUMS: React-jsinspector: 194e32c6aab382d88713ad3dd0025c5f5c4ee072 React-logger: cebf22b6cf43434e471dc561e5911b40ac01d289 react-native-blur: cfdad7b3c01d725ab62a8a729f42ea463998afa2 - react-native-compat: c741279b875109d2d9fc8da22e80c00ef91311a6 + react-native-compat: d4cbc6baa534b34984808b9224e5a4b6293af236 react-native-config: 86038147314e2e6d10ea9972022aa171e6b1d4d8 react-native-get-random-values: dee677497c6a740b71e5612e8dbd83e7539ed5bb react-native-netinfo: fefd4e98d75cbdd6e85fc530f7111a8afdf2b0c5 diff --git a/loc/de-DE.json b/loc/de-DE.json index 334c61f..394fc10 100644 --- a/loc/de-DE.json +++ b/loc/de-DE.json @@ -149,6 +149,13 @@ "body": "Du hast deine Secret Recovery Phrase nicht abgesichert. Wir empfehlen dir, ein Backup durchzuführen, damit du den Zugang zu deinen Mitteln nicht verlierst.", "header": "Sichere deine Wallet ab, bevor du Mittel dafür erhalten kannst." }, + "blastWelcoming": { + "boldBlastNetwork": "Blast Network", + "buttonText": "Hört sich gut an", + "part1": "Deine Wallet unterstützt nun {boldBlastNetwork}. Ethereum L2 mit nativer Rendite für ETH und Stablecoins.", + "part2": "Mit dieser Integration haben wir den Weg dafür bereitet, schnell weitere Level-2-Netzwerke hinzufügen zu können, und gleichzeitig weiterhin die sicherste Erfahrung mit mobilen Wallets zu bieten.", + "title": "Kraken Wallet heißt Blast herzlich willkommen!" + }, "broadcast": { "sent": "Gesendet" }, @@ -423,6 +430,7 @@ "title": "Wallets verwalten" }, "marketData": { + "about": "Über {assetSymbol}", "allTimeHigh": { "details": "Der höchste Preis, zu dem eine Kryptowährung seit ihrer Einführung getradet wurde.", "title": "Rekordhoch:" @@ -443,7 +451,9 @@ "short": "FDV", "title": "Vollständig verwässerter Wert:" }, + "high": "Hoch:", "links": "Links", + "low": "Niedrig:", "marketCap": { "details": "Der gesamte Marktwert einer Kryptowährung, berechnet durch die Multiplikation des aktuellen Preises mit der Umlaufmenge.", "short": "Marktkapitalisierung", @@ -453,6 +463,21 @@ "details": "Die maximale Anzahl an Coins oder Tokens, die jemals für eine Kryptowährung existieren werden, gemäß der Definition des Projektprotokolls.", "title": "Maximales Angebot:" }, + "networkFee": { + "current": "Aktuelle Gebühr", + "duration": "Dauer", + "title": "Netzwerkgebühr" + }, + "period": { + "all": "ALLE", + "day": "24 Std.", + "month": "1 M", + "week": "1 W.", + "year": "1 J." + }, + "price": "Preis", + "priceNotAvailable": "Preis (nicht verfügbar)", + "readMore": "Mehr lesen", "showLess": "Weniger zeigen", "terminology": "Terminologie", "tokenContract": "Token-Kontrakt", @@ -520,6 +545,8 @@ "subheading": "Deine Wallet enthält 0 NFTs in allen unterstützten Netzwerken" }, "selectedNetworks": { + "blastHeading": "Blast NFTs sind in Kürze verfügbar", + "blastSubheading": "Mit dieser Wallet kannst du noch nicht deine NFTs im Blast Network einsehen", "heading": "Keine NFTs in ausgewählten Netzwerken", "subheading": "Deine Wallet enthält 0 NFTs in den ausgewählten Netzwerken" } diff --git a/loc/en-GB.json b/loc/en-GB.json index 1ed42e4..aba553b 100644 --- a/loc/en-GB.json +++ b/loc/en-GB.json @@ -149,6 +149,13 @@ "body": "You haven't backed up your Secret Recovery Phrase. We recommend backing up to avoid losing access to your funds.", "header": "Before receiving funds in this wallet, back it up" }, + "blastWelcoming": { + "boldBlastNetwork": "Blast Network", + "buttonText": "Sounds good", + "part1": "Your wallet now supports the {boldBlastNetwork}. The Ethereum L2 with native yield for ETH and stablecoins.", + "part2": "With this integration, we've set the stage to add more Level 2 networks rapidly, while maintaining the most secure mobile wallet experience.", + "title": "Kraken Wallet Welcomes Blast!" + }, "broadcast": { "sent": "Sent" }, @@ -423,6 +430,7 @@ "title": "Manage wallets" }, "marketData": { + "about": "About {assetSymbol}", "allTimeHigh": { "details": "The highest price a cryptocurrency has traded at since its inception.", "title": "All-Time High:" @@ -443,7 +451,9 @@ "short": "FDV", "title": "Fully Diluted Valuation:" }, + "high": "High:", "links": "Links", + "low": "Low:", "marketCap": { "details": "The total market value of a cryptocurrency, calculated by multiplying the current price by the circulating supply.", "short": "Market Cap", @@ -453,6 +463,21 @@ "details": "The maximum number of coins or tokens that will ever exist for a cryptocurrency, as defined by the project's protocol.", "title": "Max Supply:" }, + "networkFee": { + "current": "Current fee", + "duration": "Duration", + "title": "Network fee" + }, + "period": { + "all": "ALL", + "day": "24h", + "month": "1M", + "week": "1W", + "year": "1Y" + }, + "price": "Price", + "priceNotAvailable": "Price (not available)", + "readMore": "Read more", "showLess": "Show less", "terminology": "Terminology", "tokenContract": "Token contract", @@ -520,6 +545,8 @@ "subheading": "Your wallet contains 0 NFTs on all of the supported networks" }, "selectedNetworks": { + "blastHeading": "Blast NFTs coming soon", + "blastSubheading": "This wallet does not yet support viewing your NFTs on the Blast network", "heading": "No NFTs on selected networks", "subheading": "Your wallet contains 0 NFTs on the selected networks" } diff --git a/loc/en-US.json b/loc/en-US.json index 7242aee..6ce00d0 100644 --- a/loc/en-US.json +++ b/loc/en-US.json @@ -903,5 +903,13 @@ "backUpNow": "Back up now", "body": "You haven't backed up your Secret Recovery Phrase. We recommend backing up to avoid losing access to your funds.", "header": "Before receiving funds in this wallet, back it up" + }, + "whatsNew": { + "assetMarketData": { + "title": "Comprehensive asset data at your fingertips", + "part1": "You can now track your holdings' an asset's performance and price changes directly in the wallet!", + "part2": "Dive into detailed asset insights, get informed of potential threats, and seamlessly access essential information like token contracts and current network fees.", + "buttonText": "Check it out" + } } } diff --git a/loc/es-ES.json b/loc/es-ES.json index bb3048c..d972ba4 100644 --- a/loc/es-ES.json +++ b/loc/es-ES.json @@ -149,6 +149,13 @@ "body": "Aún no has hecho una copia de seguridad de tu frase de recuperación secreta. Te recomendamos que hagas una copia de seguridad para que no pierdas el acceso a tus fondos.", "header": "Antes de recibir fondos en este monedero, haz una copia de seguridad" }, + "blastWelcoming": { + "boldBlastNetwork": "Blast Network", + "buttonText": "Me gusta", + "part1": "Tu monedero ahora es compatible con la {boldBlastNetwork}. El Ethereum L2 con rendimiento nativo para ETH y criptomonedas estables.", + "part2": "Con esta integración, hemos preparado las condiciones para añadir rápidamente más redes de Nivel 2, manteniendo al mismo tiempo la experiencia de monedero móvil más segura.", + "title": "¡Kraken Wallet da la bienvenida a Blast!" + }, "broadcast": { "sent": "Enviado" }, @@ -423,6 +430,7 @@ "title": "Gestionar monederos" }, "marketData": { + "about": "Acerca de {assetSymbol}", "allTimeHigh": { "details": "El precio más alto al que se ha se ha operado con una criptomoneda desde su creación.", "title": "Máximo histórico:" @@ -443,7 +451,9 @@ "short": "FDV", "title": "Valoración totalmente diluida:" }, + "high": "Alto:", "links": "Enlaces", + "low": "Bajo:", "marketCap": { "details": "El valor total de mercado de una criptomoneda, calculado multiplicando el precio actual por el suministro en circulación.", "short": "Market Cap", @@ -453,6 +463,21 @@ "details": "El número máximo de monedas o tokens que existirán para una criptomoneda, según lo definido por el protocolo del proyecto.", "title": "Suministro máximo:" }, + "networkFee": { + "current": "Tarifa actual", + "duration": "Duración", + "title": "Tarifa de red" + }, + "period": { + "all": "TODO", + "day": "24 h", + "month": "1M", + "week": "1S", + "year": "1 año" + }, + "price": "Precio", + "priceNotAvailable": "Precio (no disponible)", + "readMore": "Leer más", "showLess": "Mostrar menos", "terminology": "Terminología", "tokenContract": "Contrato de token", @@ -520,6 +545,8 @@ "subheading": "Tu monedero contiene 0 NFT en todas las redes compatibles" }, "selectedNetworks": { + "blastHeading": "NFTs de Blast disponibles próximamente", + "blastSubheading": "Este monedero aún no permite ver tus NFT en la red Blast", "heading": "No hay NFT en las redes seleccionadas", "subheading": "Tu monedero contiene 0 NFT en las redes seleccionadas" } diff --git a/loc/fr-FR.json b/loc/fr-FR.json index 69b874d..d5d9424 100644 --- a/loc/fr-FR.json +++ b/loc/fr-FR.json @@ -149,6 +149,13 @@ "body": "Vous n’avez pas sauvegardé votre Phrase de récupération secrète. Nous vous conseillons de procéder à une sauvegarde pour éviter de perdre l’accès à vos fonds.", "header": "Avant de recevoir des fonds dans ce portefeuille, faites-en une sauvegarde" }, + "blastWelcoming": { + "boldBlastNetwork": "Réseau Blast", + "buttonText": "Cela me semble bien", + "part1": "Votre portefeuille prend désormais en charge {boldBlastNetwork}. L’Ethereum L2 avec un rendement natif pour l’ETH et les stablecoins.", + "part2": "Avec cette intégration, nous sommes prêts à ajouter rapidement d’autres réseaux de niveau 2, tout en conservant l’expérience de portefeuille mobile la plus sécurisée.", + "title": "Kraken Wallet accueille Blast !" + }, "broadcast": { "sent": "Envoyé" }, @@ -423,6 +430,7 @@ "title": "Gérer les portefeuilles" }, "marketData": { + "about": "À propos de {assetSymbol}", "allTimeHigh": { "details": "Le cours le plus élevé jamais atteint par une crypto-monnaie depuis son lancement.", "title": "Plus-haut historique :" @@ -443,7 +451,9 @@ "short": "FDV", "title": "Valorisation après effet de dilution :" }, + "high": "Élevé :", "links": "Liens", + "low": "Bas :", "marketCap": { "details": "La valeur totale du marché d’une crypto-monnaie, calculée en multipliant le cours actuel et l’offre en circulation.", "short": "Capitalisation boursière", @@ -453,6 +463,21 @@ "details": "Le nombre maximum de coins ou tokens qui existeront pour une crypto-monnaie, tel que défini par le protocole du projet.", "title": "Offre maximale :" }, + "networkFee": { + "current": "Frais actuel", + "duration": "Durée", + "title": "Frais de réseau" + }, + "period": { + "all": "TOUT", + "day": "24 h", + "month": "1M", + "week": "1S", + "year": "1A" + }, + "price": "Prix", + "priceNotAvailable": "Prix (non disponible)", + "readMore": "En savoir plus", "showLess": "Afficher moins", "terminology": "Terminologie", "tokenContract": "Contrat de tokens", @@ -520,6 +545,8 @@ "subheading": "Votre portefeuille contient 0 NFT sur tous les réseaux pris en charge" }, "selectedNetworks": { + "blastHeading": "NFT Blast bientôt disponibles", + "blastSubheading": "Ce portefeuille ne permet pas encore de visualiser vos NFT sur le réseau Blast", "heading": "Aucun NFT sur les réseaux sélectionnés", "subheading": "Votre portefeuille contient 0 NFT sur les réseaux sélectionnés" } diff --git a/loc/it-IT.json b/loc/it-IT.json index dadd5fb..c974f64 100644 --- a/loc/it-IT.json +++ b/loc/it-IT.json @@ -149,6 +149,13 @@ "body": "Non hai eseguito il backup della tua Frase di recupero segreta. Ti consigliamo di farlo per evitare di perdere l’accesso ai tuoi fondi.", "header": "Esegui il backup prima di ricevere fondi in questo wallet" }, + "blastWelcoming": { + "boldBlastNetwork": "Rete Blast", + "buttonText": "Perfetto", + "part1": "Il tuo wallet ora supporta la {boldBlastNetwork}. Ethereum L2 con rendimento native per ETH e stablecoin.", + "part2": "Con questa integrazione, abbiamo posto le basi per aggiungere rapidamente altre reti di livello 2, mantenendo più sicura possibile l’esperienza del wallet mobile.", + "title": "Kraken Wallet dà il benvenuto a Blast!" + }, "broadcast": { "sent": "Inviate" }, @@ -423,6 +430,7 @@ "title": "Gestisci wallet" }, "marketData": { + "about": "Informazioni su {assetSymbol}", "allTimeHigh": { "details": "il prezzo massimo a cui una criptovaluta è stata scambiata dal suo lancio.", "title": "Massimo storico:" @@ -443,7 +451,9 @@ "short": "FDV", "title": "Valutazione completamente diluita:" }, + "high": "Massimo:", "links": "Link", + "low": "Minimo:", "marketCap": { "details": "il valore totale di mercato di una criptovaluta, calcolato moltiplicando il prezzo attuale per la fornitura circolante.", "short": "Market cap", @@ -453,6 +463,21 @@ "details": "il numero massimo possibile di crypto o token per una criptovaluta, così come definito nel protocollo del progetto.", "title": "Fornitura massima:" }, + "networkFee": { + "current": "Commissione corrente", + "duration": "Durata", + "title": "Commissione del network" + }, + "period": { + "all": "TUTTI", + "day": "24 ore", + "month": "1M", + "week": "1W", + "year": "1 anno" + }, + "price": "Prezzo", + "priceNotAvailable": "Prezzo (non disponibile)", + "readMore": "Maggiori informazioni", "showLess": "Mostra meno", "terminology": "Terminologia", "tokenContract": "Contratto token", @@ -520,6 +545,8 @@ "subheading": "Il wallet contiene 0 NFT in tutti i network supportati" }, "selectedNetworks": { + "blastHeading": "Gli NFT di Blast stanno arrivando", + "blastSubheading": "Questo wallet non supporta ancora la visualizzazione dei tuoi NFT sulla rete Blast", "heading": "Nessun NFT nel wallet selezionato", "subheading": "Il wallet contiene 0 NFT nei network selezionati" } diff --git a/loc/nl-NL.json b/loc/nl-NL.json index d84ae87..6415695 100644 --- a/loc/nl-NL.json +++ b/loc/nl-NL.json @@ -149,6 +149,13 @@ "body": "Je hebt geen back-up gemaakt van je geheime herstelzin. We raden aan om een back-up te maken om te voorkomen dat je de toegang tot je geld verliest.", "header": "Maak een back-up voordat je geld ontvangt in deze wallet" }, + "blastWelcoming": { + "boldBlastNetwork": "Blast-netwerk", + "buttonText": "Klinkt goed", + "part1": "Je wallet ondersteunt nu de {boldBlastNetwork}. De Ethereum L2 met native yield voor ETH en stablecoins.", + "part2": "Met deze integratie zorgen we op korte tijd voor meer Level 2-netwerken en behouden we de veiligste mobiele wallet-ervaring.", + "title": "Kraken Wallet verwelkomt Blast!" + }, "broadcast": { "sent": "Verzonden" }, @@ -423,6 +430,7 @@ "title": "Wallets beheren" }, "marketData": { + "about": "Over {assetSymbol}", "allTimeHigh": { "details": "De hoogste prijs waartegen een cryptovaluta sinds zijn oprichting is verhandeld.", "title": "Historisch hoogtepunt:" @@ -443,7 +451,9 @@ "short": "FDV", "title": "Volledige verwaterde waardering:" }, + "high": "Hoog:", "links": "Koppelingen", + "low": "Laag:", "marketCap": { "details": "De totale marktwaarde van een cryptovaluta, berekend door de huidige koers te vermenigvuldigen met de circulerende voorraad.", "short": "Marktplafond", @@ -453,6 +463,21 @@ "details": "Het maximale aantal munten of tokens dat ooit zal bestaan voor een cryptovaluta, zoals gedefinieerd door het protocol van het project.", "title": "Max. voorraad:" }, + "networkFee": { + "current": "Huidig tarief", + "duration": "Duur", + "title": "Netwerkkosten" + }, + "period": { + "all": "ALLES", + "day": "24u", + "month": "1M", + "week": "1W", + "year": "1J" + }, + "price": "Koers", + "priceNotAvailable": "Prijs (niet beschikbaar)", + "readMore": "Meer weergeven", "showLess": "Minder weergeven", "terminology": "Terminologie", "tokenContract": "Token-contract", @@ -520,6 +545,8 @@ "subheading": "Je wallet bevat 0 NFT's op alle ondersteunde netwerken" }, "selectedNetworks": { + "blastHeading": "Binnenkort Blast NFT's", + "blastSubheading": "Deze wallet ondersteunt nog niet het bekijken van je NFT's op het Blast-netwerk", "heading": "Geen NFT's op geselecteerde netwerken", "subheading": "Je wallet bevat 0 NFT's op de geselecteerde netwerken" } diff --git a/loc/pt-BR.json b/loc/pt-BR.json index 0a1d4d0..38a5710 100644 --- a/loc/pt-BR.json +++ b/loc/pt-BR.json @@ -149,6 +149,13 @@ "body": "Você não fez backup da sua frase secreta de recuperação. Recomendamos fazer backup para evitar perder acesso ao seus fundos.", "header": "Faça o backup antes de receber os fundos nesta carteira" }, + "blastWelcoming": { + "boldBlastNetwork": "Rede Blast", + "buttonText": "Ótimo", + "part1": "Sua carteira agora suporta a {boldBlastNetwork}. O Ethereum L2 com rendimento nativo para ETH e stablecoins.", + "part2": "Com essa integração, definimos o cenário para adicionar mais redes de nível 2 rapidamente, mantendo a experiência de carteira móvel mais segura.", + "title": "A Kraken Wallet dá boas-vindas a Blast!" + }, "broadcast": { "sent": "Enviado" }, @@ -423,6 +430,7 @@ "title": "Gerenciar carteiras" }, "marketData": { + "about": "Sobre {assetSymbol}", "allTimeHigh": { "details": "O preço mais alto pelo qual uma criptomoeda foi negociada desde o seu início.", "title": "Preço mais alto:" @@ -443,7 +451,9 @@ "short": "FDV", "title": "Avaliação totalmente diluída:" }, + "high": "Alto:", "links": "Links", + "low": "Baixo:", "marketCap": { "details": "O valor total de mercado de uma criptomoeda, calculado multiplicando o preço atual pela oferta circulante.", "short": "Capitalização de mercado", @@ -453,6 +463,21 @@ "details": "O número máximo de moedas ou tokens que existirão para uma criptomoeda, conforme definido pelo protocolo do projeto.", "title": "Oferta máxima:" }, + "networkFee": { + "current": "Taxa atual", + "duration": "Duração", + "title": "Taxa de rede" + }, + "period": { + "all": "TUDO", + "day": "24H", + "month": "1M", + "week": "1S", + "year": "1A" + }, + "price": "Preço", + "priceNotAvailable": "Preço (indisponível)", + "readMore": "Saiba mais", "showLess": "Mostrar menos", "terminology": "Terminologia", "tokenContract": "Contrato de token", @@ -520,6 +545,8 @@ "subheading": "Sua carteira contém 0 NFTs em todas as redes compatíveis" }, "selectedNetworks": { + "blastHeading": "Blast NFTs em breve", + "blastSubheading": "Esta carteira ainda não suporta a visualização dos seus NFTs na rede Blast", "heading": "Sem NFTs nas redes selecionadas", "subheading": "Sua carteira contém 0 NFTs em todas as redes selecionadas" } diff --git a/loc/ru-RU.json b/loc/ru-RU.json index 5407fea..21d90e0 100644 --- a/loc/ru-RU.json +++ b/loc/ru-RU.json @@ -149,6 +149,13 @@ "body": "Вы не выполнили резервное копирование секретной фразы для восстановления. Рекомендуем вам выполнить резервное копирование, чтобы избежать потери доступа к своим средствам.", "header": "Выполните резервное копирование, прежде чем получать средства на этот кошелек" }, + "blastWelcoming": { + "boldBlastNetwork": "Сеть Blast", + "buttonText": "Отлично", + "part1": "Теперь ваш кошелек поддерживает {boldBlastNetwork}. Ethereum L2 с нативным доходом для ETH и стейблкоинов.", + "part2": "Благодаря этой интеграции мы подготовили почву для быстрого добавления большего количества сетей уровня 2, сохранив при этом наиболее высокий уровень безопасности для мобильного кошелька.", + "title": "Kraken Wallet приветствует Blast!" + }, "broadcast": { "sent": "Отправлено" }, @@ -423,6 +430,7 @@ "title": "Управление кошельками" }, "marketData": { + "about": "Подробнее о {assetSymbol}", "allTimeHigh": { "details": "Самая высокая цена, по которой торговалась криптовалюта с момента ее создания.", "title": "Самая высокая за все время:" @@ -443,7 +451,9 @@ "short": "FDV", "title": "Полностью разбавленная оценка:" }, + "high": "Высокие:", "links": "Ссылки", + "low": "Низкие:", "marketCap": { "details": "Общая рыночная стоимость криптовалюты, рассчитываемая путем умножения текущей цены на количество единиц в обращении.", "short": "Рыночная капитализация", @@ -453,6 +463,21 @@ "details": "Максимальное количество монет или токенов криптовалюты, которые когда-либо будут существовать, как определено протоколом проекта.", "title": "Максимальное предложение:" }, + "networkFee": { + "current": "Текущая комиссия", + "duration": "Продолжительность", + "title": "Комиссия сети" + }, + "period": { + "all": "Все", + "day": "24 ч", + "month": "1 мес.", + "week": "1 нед.", + "year": "1 г." + }, + "price": "Цена", + "priceNotAvailable": "Цена (недоступно)", + "readMore": "Развернуть", "showLess": "Показать меньше", "terminology": "Терминология", "tokenContract": "Контракт токена", @@ -520,6 +545,8 @@ "subheading": "В вашем кошельке 0 NFT во всех поддерживаемых сетях" }, "selectedNetworks": { + "blastHeading": "Blast NFT появятся совсем скоро", + "blastSubheading": "Этот кошелек пока не поддерживает просмотр NFT в сети Blast", "heading": "В выбранных сетях отсутствуют NFT", "subheading": "В вашем кошельке 0 NFT в выбранных сетях" } diff --git a/loc/tr-TR.json b/loc/tr-TR.json index fe08a50..826d033 100644 --- a/loc/tr-TR.json +++ b/loc/tr-TR.json @@ -149,6 +149,13 @@ "body": "Gizli Kurtarma İfadenizi yedeklemediniz. Fonlarınıza erişimi kaybetmemek için yedekleme yapmanızı öneririz.", "header": "Bu cüzdana fon almadan önce yedekleme yapın" }, + "blastWelcoming": { + "boldBlastNetwork": "Blast Ağı", + "buttonText": "Kulağa hoş geliyor", + "part1": "Cüzdanınız artık {boldBlastNetwork} desteği de sunuyor. ETH ve stabil coin’ler için yerel getiriye sahip Ethereum L2.", + "part2": "Bu entegrasyonla, en güvenli mobil cüzdan deneyimini korurken daha fazla Seviye 2 ağını hızla eklemek için zemin hazırladık.", + "title": "Kraken Wallet’a Blast Geliyor!" + }, "broadcast": { "sent": "Verilen" }, @@ -423,6 +430,7 @@ "title": "Cüzdanları yönet" }, "marketData": { + "about": "{assetSymbol} hakkında", "allTimeHigh": { "details": "Başlangıcından bu yana bir kripto para biriminin işlem gördüğü en yüksek fiyat.", "title": "Şimdiye Kadarki En Yüksek:" @@ -443,7 +451,9 @@ "short": "FDV", "title": "Tamamen Seyreltilmiş Değer:" }, + "high": "Yüksek:", "links": "Bağlantılar", + "low": "Düşük:", "marketCap": { "details": "Dolaşımda olan arzla mevcut fiyatın çarpılmasıyla elde edilen bir kripto para biriminin toplam piyasa değeri.", "short": "Piyasa Değeri", @@ -453,6 +463,21 @@ "details": "Projenin protokolünün tanımladığı üzere bir kripto para birimine ait var olacak maksimum coin veya token sayısı.", "title": "Maksimum Arz:" }, + "networkFee": { + "current": "Mevcut ücret", + "duration": "Süre", + "title": "Ağ ücreti" + }, + "period": { + "all": "TÜMÜ", + "day": "24 Saat", + "month": "1A", + "week": "1H", + "year": "1Y" + }, + "price": "Fiyat", + "priceNotAvailable": "Fiyat (yok)", + "readMore": "Daha fazla oku", "showLess": "Daha az göster", "terminology": "Terminoloji", "tokenContract": "Token sözleşmesi", @@ -520,6 +545,8 @@ "subheading": "Cüzdanınız desteklenen tüm ağlarda 0 NFT içeriyor" }, "selectedNetworks": { + "blastHeading": "Blast NFT’ler çok yakında geliyor", + "blastSubheading": "Bu cüzdan henüz Blast ağındaki NFT'lerinizi görüntülemeyi desteklemiyor", "heading": "Seçili ağlarda NFT yok", "subheading": "Cüzdanınız seçilen ağlarda 0 NFT içeriyor" } diff --git a/loc/uk-UA.json b/loc/uk-UA.json index e6dba2b..3cb1e4e 100644 --- a/loc/uk-UA.json +++ b/loc/uk-UA.json @@ -149,6 +149,13 @@ "body": "Ви не створили резервну копію секретної фрази для відновлення. Ми рекомендуємо створити резервну копію, щоб уникнути втрати доступу до ваших коштів.", "header": "Перш ніж отримати кошти на цей гаманець, зробіть його резервну копію" }, + "blastWelcoming": { + "boldBlastNetwork": "Мережа Blast", + "buttonText": "Звучить непогано", + "part1": "Ваш гаманець тепер підтримує {boldBlastNetwork}. Ethereum L2 з власним доходом для ETH і стейблкоїнів.", + "part2": "Завдяки цій інтеграції ми створили передумови для швидкого додавання нових мереж 2-го рівня, зберігаючи при цьому найбезпечніше робоче середовище мобільного гаманця.", + "title": "Kraken Wallet представляє Blast!" + }, "broadcast": { "sent": "Надіслано" }, @@ -423,6 +430,7 @@ "title": "Керувати гаманцями" }, "marketData": { + "about": "Про {assetSymbol}", "allTimeHigh": { "details": "Найвища ціна, за якою здійснювалася торгівля криптовалютою з моменту її появи.", "title": "Найвищий показник за весь час:" @@ -443,7 +451,9 @@ "short": "FDV", "title": "Повністю розведена вартість:" }, + "high": "Максимум:", "links": "Посилання", + "low": "Мінімум:", "marketCap": { "details": "Загальна ринкова вартість криптовалюти, розрахована шляхом множення поточної ціни на обсяг обігу.", "short": "Рин. капіталізація", @@ -453,6 +463,21 @@ "details": "Максимальна кількість монет або токенів, яка коли-небудь існуватиме для криптовалюти, за протоколом проєкту.", "title": "Макс. обсяг:" }, + "networkFee": { + "current": "Поточна комісія", + "duration": "Тривалість", + "title": "Комісія за користування мережею" + }, + "period": { + "all": "УСІ", + "day": "24Г", + "month": "1 хв.", + "week": "1 тижд.", + "year": "1 р." + }, + "price": "Ціна", + "priceNotAvailable": "Ціна (недоступна)", + "readMore": "Докладніше", "showLess": "Показати менше", "terminology": "Термінологія", "tokenContract": "Контракт токена", @@ -520,6 +545,8 @@ "subheading": "Ваш гаманець містить 0 NFT в усіх підтримуваних мережах" }, "selectedNetworks": { + "blastHeading": "NFT Blast уже незабаром", + "blastSubheading": "Цей гаманець поки що не підтримує перегляд ваших NFT у мережі Blast", "heading": "Немає NFT у вибраних мережах", "subheading": "Ваш гаманець містить 0 NFT в обраних мережах" } diff --git a/loc/vi-VN.json b/loc/vi-VN.json index 5a9d869..0650440 100644 --- a/loc/vi-VN.json +++ b/loc/vi-VN.json @@ -149,6 +149,13 @@ "body": "Bạn chưa sao lưu Cụm từ khôi phục bí mật của mình. Chúng tôi khuyên bạn nên sao lưu để tránh mất quyền truy cập vào khoản tiền của mình.", "header": "Trước khi nhận tiền vào ví này, hãy sao lưu cụm từ khôi phục" }, + "blastWelcoming": { + "boldBlastNetwork": "Blast Network", + "buttonText": "Nghe hay đấy", + "part1": "Ví của bạn hiện hỗ trợ {boldBlastNetwork}. Ethereum L2 với lợi suất gốc cho ETH và stablecoin.", + "part2": "Với sự tích hợp này, chúng tôi đã tạo tiền đề để nhanh chóng bổ sung thêm nhiều mạng Cấp 2 hơn, đồng thời duy trì trải nghiệm ví di động an toàn nhất.", + "title": "Kraken Wallet chào đón Blast!" + }, "broadcast": { "sent": "Đã gửi" }, @@ -423,6 +430,7 @@ "title": "Quản lý ví" }, "marketData": { + "about": "Giới thiệu về {assetSymbol}", "allTimeHigh": { "details": "Mức giá cao nhất mà một loại tiền điện tử đã được giao dịch kể từ khi ra đời.", "title": "Cao ở mọi thời điểm:" @@ -443,7 +451,9 @@ "short": "FDV", "title": "Định giá pha loãng hoàn toàn:" }, + "high": "Cao:", "links": "Liên kết", + "low": "Thấp:", "marketCap": { "details": "Tổng giá trị thị trường của tiền điện tử, được tính bằng cách nhân giá hiện tại với nguồn cung lưu hành.", "short": "Vốn hóa thị trường", @@ -453,6 +463,21 @@ "details": "Số lượng đồng tiền điện tử hoặc token tối đa sẽ tồn tại đối với một loại tiền điện tử, như được xác định bởi giao thức của dự án.", "title": "Nguồn cung tối đa:" }, + "networkFee": { + "current": "Phí hiện tại", + "duration": "Thời hạn", + "title": "Phí mạng" + }, + "period": { + "all": "TẤT CẢ", + "day": "24 GIỜ", + "month": "1 THÁNG", + "week": "1 tuần", + "year": "1 năm" + }, + "price": "Giá", + "priceNotAvailable": "Giá (không khả dụng)", + "readMore": "Đọc thêm", "showLess": "Ẩn bớt", "terminology": "Thuật ngữ", "tokenContract": "Hợp đồng token", @@ -520,6 +545,8 @@ "subheading": "Ví của bạn chứa 0 NFT trên tất cả các mạng được hỗ trợ" }, "selectedNetworks": { + "blastHeading": "NFT Blast sắp ra mắt", + "blastSubheading": "Ví này chưa hỗ trợ xem NFT của bạn trên Blast Network", "heading": "Không có NFT trên các mạng đã chọn", "subheading": "Ví của bạn chứa 0 NFT trên các mạng đã chọn" } diff --git a/modules/wallet-connect/web3Wallet/ethereum/types.ts b/modules/wallet-connect/web3Wallet/ethereum/types.ts index d10561d..57f0c49 100644 --- a/modules/wallet-connect/web3Wallet/ethereum/types.ts +++ b/modules/wallet-connect/web3Wallet/ethereum/types.ts @@ -15,6 +15,8 @@ export interface EIP712 { types: { [key: string]: { type: string; name: string }[] }; } +export type EIP712TypeDefinitions = EIP712['types'][keyof EIP712['types']]; + export type TransactionObject = { data: string; from: string; diff --git a/modules/wallet-connect/web3Wallet/ethereum/utils/adaptEIP712ToDefinitionList.ts b/modules/wallet-connect/web3Wallet/ethereum/utils/adaptEIP712ToDefinitionList.ts index 1cb3a7e..cff2454 100644 --- a/modules/wallet-connect/web3Wallet/ethereum/utils/adaptEIP712ToDefinitionList.ts +++ b/modules/wallet-connect/web3Wallet/ethereum/utils/adaptEIP712ToDefinitionList.ts @@ -3,32 +3,19 @@ import { isObject } from 'lodash'; import { DefinitionList } from '../../../types'; import { EIP712 } from '../types'; -import { handleError } from '/helpers/errorHandler'; +import { sanitizeEIP712 } from './sanitizeEIP712'; -export function adaptEIP712ToDefinitionList(data: EIP712): DefinitionList { +export function adaptEIP712ToDefinitionList(eip712: EIP712): DefinitionList { + const data = sanitizeEIP712(eip712); const domainEntries = Object.entries(data.domain); const messageEntries = Object.entries(data.message); const definitionList: DefinitionList = []; [...domainEntries, ...messageEntries].forEach(([domainOrMessageKey, domainOrMessageValue]) => { if (isObject(domainOrMessageValue)) { - const domainOrMessageValueEntries = Object.entries(domainOrMessageValue); - let description = ''; - domainOrMessageValueEntries.forEach(([domainOrMessageValueKey, domainOrMessageValueValue], i) => { - const isNotLast = i < domainOrMessageValueEntries.length - 1; - - try { - description += `${domainOrMessageValueKey}: ${ - typeof domainOrMessageValueValue === 'string' ? domainOrMessageValueValue : JSON.stringify(domainOrMessageValueValue) - }${isNotLast ? '\n' : ''}`; - } catch (error) { - handleError(error, 'ERROR_CONTEXT_PLACEHOLDER'); - } - }); - - definitionList.push({ title: domainOrMessageKey, description }); + definitionList.push({ title: domainOrMessageKey.trim(), description: JSON.stringify(domainOrMessageValue, null, 4).trim() }); } else { - definitionList.push({ title: domainOrMessageKey, description: '' + domainOrMessageValue }); + definitionList.push({ title: domainOrMessageKey.trim(), description: String(domainOrMessageValue).trim() }); } }); diff --git a/modules/wallet-connect/web3Wallet/ethereum/utils/sanitizeEIP712.ts b/modules/wallet-connect/web3Wallet/ethereum/utils/sanitizeEIP712.ts new file mode 100644 index 0000000..1d1f36e --- /dev/null +++ b/modules/wallet-connect/web3Wallet/ethereum/utils/sanitizeEIP712.ts @@ -0,0 +1,26 @@ +import { EIP712, EIP712TypeDefinitions } from '../types'; + +function sanitizeObject(object: EIP712['message' | 'domain'], typeDefinition: EIP712TypeDefinitions, types: EIP712['types']): Record { + const sanitizedObject: Record = {}; + typeDefinition.forEach(({ name, type }) => { + if (object.hasOwnProperty(name)) { + if (types[type]) { + sanitizedObject[name] = sanitizeObject(object[name] as Record, types[type], types); + } else { + sanitizedObject[name] = object[name]; + } + } + }); + return sanitizedObject; +} + +export function sanitizeEIP712(typedMessage: EIP712): EIP712 { + const primaryTypeDefinition = typedMessage.types[typedMessage.primaryType] || []; + + return { + types: typedMessage.types, + primaryType: typedMessage.primaryType, + domain: sanitizeObject(typedMessage.domain, typedMessage.types.EIP712Domain, typedMessage.types), + message: sanitizeObject(typedMessage.message, primaryTypeDefinition, typedMessage.types), + }; +} diff --git a/package.json b/package.json index c7ec89a..b75b8f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "superwallet", - "version": "1.4.0", + "version": "1.5.0", "private": true, "scripts": { "android": "react-native run-android", @@ -38,10 +38,10 @@ "@solana/web3.js": "1.91.7", "@taquito/signer": "12.1.0", "@taquito/utils": "12.1.0", - "@walletconnect/core": "2.12.2", - "@walletconnect/react-native-compat": "2.12.2", - "@walletconnect/types": "2.12.2", - "@walletconnect/web3wallet": "1.11.2", + "@walletconnect/core": "2.13.3", + "@walletconnect/react-native-compat": "2.13.3", + "@walletconnect/types": "2.13.3", + "@walletconnect/web3wallet": "1.12.3", "assert": "2.1.0", "big-integer": "1.6.51", "bignumber.js": "9.1.1", diff --git a/src/Navigation.tsx b/src/Navigation.tsx index 365a5a3..db90991 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -15,7 +15,6 @@ import { WalletConnectSignRequest_GenericTransactionScreen, WalletConnectSignRequest_StructuredTransactionScreen, } from '@/screens/AppSignRequest'; -import { BlastWelcomingScreen } from '@/screens/BlastWelcoming'; import { CoinsListScreen } from '@/screens/CoinsList'; import { ConnectAppScreen } from '@/screens/ConnectApp'; import { ConnectAppQRScanScreen } from '@/screens/ConnectAppQRScan'; @@ -40,6 +39,7 @@ import { TriggeredPushPromptScreen } from '@/screens/TriggerredPushPromptScreen' import { UniversalSendScreen } from '@/screens/UniversalSend'; import { WalletBackupPromptScreen } from '@/screens/WalletBackupPrompt'; import { WalletConnectExplainerScreen } from '@/screens/WalletConnectExplainer'; +import { WhatsNewAssetMarketDataScreen, WhatsNewBlastScreen } from '@/screens/WhatsNew'; import { useConnectionManager } from '@/utils/useConnectionManager'; import { DefaultBackButton } from './components/BackButton'; @@ -121,7 +121,8 @@ const NavigationStack = () => { - + + = ({ title, animation, onButtonPress, buttonText, children, animationHeight, contentOffset }) => { +export const SimpleSlide: React.FC = ({ + title, + animation, + onButtonPress, + buttonText, + children, + animationHeight, + contentOffset, + typeTitle, +}) => { const [lottieLayout, setLottieLayout] = useState(); const onAnimationLayout = (e: LayoutChangeEvent) => { @@ -36,7 +46,7 @@ export const SimpleSlide: React.FC = ({ title, animat - @@ -72,7 +72,7 @@ export const HighLowPriceChange = ({ highLow, currentPrice, color, period }: Pro {`${loc.marketData.high} `} diff --git a/src/components/TokenMarketData/HistoricalAssetPriceChart.tsx b/src/components/TokenMarketData/HistoricalAssetPriceChart.tsx index e4e6690..587c97d 100644 --- a/src/components/TokenMarketData/HistoricalAssetPriceChart.tsx +++ b/src/components/TokenMarketData/HistoricalAssetPriceChart.tsx @@ -1,5 +1,5 @@ import { LinearGradient, vec } from '@shopify/react-native-skia'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { StyleSheet, View } from 'react-native'; import Animated, { CurvedTransition } from 'react-native-reanimated'; import { CartesianChart, Line } from 'victory-native'; @@ -7,6 +7,7 @@ import { CartesianChart, Line } from 'victory-native'; import { AnimatedNumbers } from '@/components/AnimatedNumbers'; import { Label, Typography } from '@/components/Label'; import { CHART_PLACEHOLDER, HIGH_LOW_PRICE_PLACEHOLDER, PRICE_PLACEHOLDER, SheetPosition, getPercentageLabel } from '@/components/TokenMarketData/utils'; +import { useDeviceSize } from '@/hooks/useDeviceSize'; import { useAppCurrency } from '@/realm/settings'; import { PriceHistoryPeriod, @@ -41,6 +42,9 @@ const convertRealmArrayToChartData = (prices: Realm.List { const [period, setPeriod] = useState('DAY'); const data = useTokenPriceHistory(assetId, period); @@ -51,6 +55,13 @@ export const HistoricalAssetPriceChart = ({ assetId, tokenId, size, price }: Pro const { currency } = useAppCurrency(); const priceNotAvailable = !price; + const { height, size: deviceSize } = useDeviceSize(); + const chartHeight = useMemo(() => { + const diff = height - STANDARD_DEVICE_HEIGHT_FOR_CHART; + const chartHeightOffset = diff > 0 ? diff : 0; + return deviceSize === 'small' ? 100 : DEFAULT_CHART_HEIGHT + chartHeightOffset; + }, [height, deviceSize]); + useEffect(() => { if (data) { const prices = convertRealmArrayToChartData(data.prices); @@ -86,7 +97,7 @@ export const HistoricalAssetPriceChart = ({ assetId, tokenId, size, price }: Pro const priceChange = getPriceChange(period); const { label: percentageLabel, color } = getPercentageLabel(getPriceChange(period), currency); - const priceLabel = priceNotAvailable || !price ? PRICE_PLACEHOLDER : formatCurrency(price, { currency, highPrecision: true }); + const priceLabel = priceNotAvailable || !price ? PRICE_PLACEHOLDER : formatCurrency(price, { currency, findFirstNonZeroDigits: true }); const { colors } = useTheme(); @@ -97,9 +108,10 @@ export const HistoricalAssetPriceChart = ({ assetId, tokenId, size, price }: Pro }; const isHigh = size === SheetPosition.HIGH; + const style = deviceSize === 'small' ? styles.smallDeviceContainer : styles.container; return ( - + @@ -128,7 +140,7 @@ export const HistoricalAssetPriceChart = ({ assetId, tokenId, size, price }: Pro {!(priceNotAvailable && size === SheetPosition.HIGH) && ( <> - + {({ points }) => ( { const { currency } = useAppCurrency(); const { label, color } = getPercentageLabel(token?.marketData?.priceChangePercentage.day, currency); const priceNotAvailable = !price; - const priceLabel = priceNotAvailable ? PRICE_PLACEHOLDER : formatCurrency(price, { currency }); + const priceLabel = priceNotAvailable ? PRICE_PLACEHOLDER : formatCurrency(price, { currency, findFirstNonZeroDigits: true }); return ( - - diff --git a/src/components/TransactionsTokenHeader.tsx b/src/components/TransactionsTokenHeader.tsx index 8c5e7ef..c3359a1 100644 --- a/src/components/TransactionsTokenHeader.tsx +++ b/src/components/TransactionsTokenHeader.tsx @@ -5,6 +5,7 @@ import { StyleSheet, View } from 'react-native'; import { AnimatedNumbers } from '@/components/AnimatedNumbers'; import { Label } from '@/components/Label'; import { useTokenBalanceConvertedToAppCurrency } from '@/hooks/useAppCurrencyValue'; +import { useDeviceSize } from '@/hooks/useDeviceSize'; import { useAppCurrency } from '@/realm/settings'; import { RealmToken } from '@/realm/tokens'; import { getAvailableTokenBalance } from '@/realm/tokens/getAvailableTokenBalance'; @@ -26,26 +27,25 @@ export const TransactionsTokenHeader = ({ token, testID }: Props) => { const tokenBalance = getAvailableTokenBalance(token); const tokenAmount = unitConverter.smallUnit2TokenUnit(tokenBalance, token.metadata.decimals).toString(10); const tokenAmountFormatted = formatTokenAmount(tokenAmount, { compact: true, currency, highPrecision: true, isBtc: isBtc({ assetId: token.assetId }) }); + const { size } = useDeviceSize(); return ( - + - {!!fiatValue && ( - - )} + { - const { setIsBlastModalCompleted } = useSettingsMutations(); - const taskCompleted = useSettingsByKey(RealmSettingsKey.isBlastModalCompleted); - const navigation = useNavigation['navigation']>(); - - if (taskCompleted === false) { - InteractionManager.runAfterInteractions(() => { - navigation.navigate(Routes.BlastWelcoming); - setIsBlastModalCompleted(true); - }); - } -}; - -export const useAppInitBlastWelcoming = () => { - return useBlastWelcomingTask(); -}; diff --git a/src/hooks/useAppInitTasks.ts b/src/hooks/useAppInitTasks.ts index f073d3d..59f5fc4 100644 --- a/src/hooks/useAppInitTasks.ts +++ b/src/hooks/useAppInitTasks.ts @@ -1,3 +1,5 @@ +import { useWhatsNewQueue } from '@/hooks/whatsNewHooks/useWhatsNewQueue'; + import { useAppInitEffect } from './useAppInitEffect'; import { useStoreReviewTask } from './useStoreReviewTask'; import { useWalletConnectExplainerTask } from './useWalletConnectExplainerTask'; @@ -5,6 +7,7 @@ import { useWalletConnectExplainerTask } from './useWalletConnectExplainerTask'; export const useAppInitTasks = () => { const walletConnectExplainerTask = useWalletConnectExplainerTask(); const storeReviewTask = useStoreReviewTask(); + useWhatsNewQueue(); useAppInitEffect(count => { switch (count) { diff --git a/src/hooks/useCommonSnapPoints.ts b/src/hooks/useCommonSnapPoints.ts index 88b3f67..7085620 100644 --- a/src/hooks/useCommonSnapPoints.ts +++ b/src/hooks/useCommonSnapPoints.ts @@ -2,6 +2,8 @@ import { HeaderHeightContext } from '@react-navigation/elements'; import { useContext, useMemo } from 'react'; import { useSafeAreaFrame } from 'react-native-safe-area-context'; +import { useDeviceSize } from '@/hooks/useDeviceSize'; + import { useDeafultHeaderHeight } from './useDefaultHeaderHeight'; type Variant = 'full' | 'toHeader' | 'toHeaderTransparent' | 'toHeaderAndMainContent'; @@ -9,6 +11,7 @@ type Variant = 'full' | 'toHeader' | 'toHeaderTransparent' | 'toHeaderAndMainCon export const useCommonSnapPoints = (variant: Variant) => { const defaultHeaderHeight = useDeafultHeaderHeight(true); const actualHeaderHeight = useContext(HeaderHeightContext) ?? 0; + const { size } = useDeviceSize(); const { height } = useSafeAreaFrame(); @@ -19,9 +22,9 @@ export const useCommonSnapPoints = (variant: Variant) => { case 'toHeaderTransparent': return [height - defaultHeaderHeight]; case 'toHeaderAndMainContent': - return [height - actualHeaderHeight - 309, height - actualHeaderHeight]; + return [height - actualHeaderHeight - (size === 'small' ? 248 : 309), height - actualHeaderHeight]; default: return [height]; } - }, [actualHeaderHeight, defaultHeaderHeight, height, variant]); + }, [actualHeaderHeight, defaultHeaderHeight, height, size, variant]); }; diff --git a/src/hooks/useDeviceSize.ts b/src/hooks/useDeviceSize.ts new file mode 100644 index 0000000..2a31db7 --- /dev/null +++ b/src/hooks/useDeviceSize.ts @@ -0,0 +1,25 @@ +import { useMemo } from 'react'; +import { useWindowDimensions } from 'react-native'; + +const MAX_SMALL_HEIGHT = 700; +const MIN_BIG_HEIGHT = 850; + +type DeviceSize = 'small' | 'big' | 'standard'; + +export const useDeviceSize = () => { + const { height } = useWindowDimensions(); + const size: DeviceSize = useMemo(() => { + switch (true) { + case height < MAX_SMALL_HEIGHT: + return 'small'; + case height > MIN_BIG_HEIGHT: + return 'big'; + default: + return 'standard'; + } + }, [height]); + return { + size, + height, + }; +}; diff --git a/src/hooks/whatsNewHooks/useIsTaskCompleted.ts b/src/hooks/whatsNewHooks/useIsTaskCompleted.ts new file mode 100644 index 0000000..4df4e27 --- /dev/null +++ b/src/hooks/whatsNewHooks/useIsTaskCompleted.ts @@ -0,0 +1,7 @@ +import { SettingsType, useSettingsByKey } from '@/realm/settings'; + +export const useIsTaskCompleted = (taskKey: keyof SettingsType) => { + const taskCompleted = useSettingsByKey(taskKey); + + return !(taskCompleted === false); +}; diff --git a/src/hooks/whatsNewHooks/useWhatsNewQueue.ts b/src/hooks/whatsNewHooks/useWhatsNewQueue.ts new file mode 100644 index 0000000..b754c92 --- /dev/null +++ b/src/hooks/whatsNewHooks/useWhatsNewQueue.ts @@ -0,0 +1,27 @@ +import { useEffect, useMemo, useRef } from 'react'; + +import { RealmSettingsKey } from '@/realm/settings'; +import { Routes } from '@/Routes'; + +import { useWhatsNewTask } from './useWhatsNewTask'; + +export const useWhatsNewQueue = () => { + const blastTask = useWhatsNewTask(RealmSettingsKey.isBlastModalCompleted, Routes.WhatsNewBlast); + const assetMarketDataTask = useWhatsNewTask(RealmSettingsKey.whatsNewIsAssetMarketDataCompleted, Routes.WhatsNewAssetMarketData); + const isInitialised = useRef(false); + const queue = useMemo(() => [blastTask, assetMarketDataTask], [blastTask, assetMarketDataTask]); + + useEffect(() => { + if (isInitialised.current) { + return; + } + isInitialised.current = true; + + for (const welcomeTask of queue) { + if (!welcomeTask.isTaskCompleted) { + welcomeTask.task(); + break; + } + } + }, [queue]); +}; diff --git a/src/hooks/whatsNewHooks/useWhatsNewTask.ts b/src/hooks/whatsNewHooks/useWhatsNewTask.ts new file mode 100644 index 0000000..12ced15 --- /dev/null +++ b/src/hooks/whatsNewHooks/useWhatsNewTask.ts @@ -0,0 +1,28 @@ +import { useNavigation } from '@react-navigation/native'; +import { useCallback } from 'react'; +import { InteractionManager } from 'react-native'; + +import { useIsTaskCompleted } from '@/hooks/whatsNewHooks/useIsTaskCompleted'; +import { SettingsType } from '@/realm/settings'; + +import { NavigationProps, Routes } from '@/Routes'; + +type WhatsNewRoutes = Extract; + +export const useWhatsNewTask = (taskKey: keyof SettingsType, route: WhatsNewRoutes) => { + const navigation = useNavigation['navigation']>(); + const isTaskCompleted = useIsTaskCompleted(taskKey); + + const task = useCallback(() => { + if (!isTaskCompleted) { + InteractionManager.runAfterInteractions(() => { + navigation.navigate(route); + }); + } + }, [isTaskCompleted, navigation, route]); + + return { + task, + isTaskCompleted, + }; +}; diff --git a/src/realm/RealmContext.tsx b/src/realm/RealmContext.tsx index 4a8b969..3efe2fa 100644 --- a/src/realm/RealmContext.tsx +++ b/src/realm/RealmContext.tsx @@ -19,7 +19,7 @@ function useObject( primaryKey: K | undefined, primaryKeyName: Extract, ): K extends undefined ? (T & Realm.Object) | undefined : T & Realm.Object { - return useQuery(type).filtered(`${primaryKeyName} = '${primaryKey}'`)?.[0]; + return useQuery(type, o => o.filtered(`${primaryKeyName} = '${primaryKey}'`), [type, primaryKey, primaryKeyName])?.[0]; } export { useRealm, useObject, useQuery }; diff --git a/src/realm/defi/useDefi.ts b/src/realm/defi/useDefi.ts index 094d2a8..45ee7cc 100644 --- a/src/realm/defi/useDefi.ts +++ b/src/realm/defi/useDefi.ts @@ -1,4 +1,4 @@ -import { useMemo } from 'react'; +import Realm from 'realm'; import { useQuery } from '../RealmContext'; import { getWalletsForMutations, useRealmWallets } from '../wallets'; @@ -8,20 +8,24 @@ import { REALM_TYPE_DEFI, RealmDefi } from './schema'; export const useDefi = () => { const wallets = useRealmWallets(); - const phrase = useMemo(() => { - const walletIdString = wallets.map(x => `"${x.id}"`).join(','); - return `walletId IN {${walletIdString}}`; - }, [wallets]); - - const collection = useQuery(REALM_TYPE_DEFI); - - return useMemo(() => { - return collection.filtered(phrase).filtered('products.@count != 0').sorted('protocolUsdBalance', true); - }, [collection, phrase]); + return useQuery( + REALM_TYPE_DEFI, + defi => + defi + .filtered( + 'walletId IN $0', + wallets.map(w => w.id), + ) + .filtered('products.@count != 0') + .sorted('protocolUsdBalance', true), + [wallets], + ); }; export const getDefisForMutations = (realm: Realm) => { const wallets = getWalletsForMutations(realm); - const defiCollection = realm.objects(REALM_TYPE_DEFI); - return defiCollection.filtered(`walletId IN {${wallets.map(x => `"${x.id}"`).join(',')}}`); + return realm.objects(REALM_TYPE_DEFI).filtered( + 'walletId IN $0', + wallets.map(w => w.id), + ); }; diff --git a/src/realm/defi/useDefiMutations.ts b/src/realm/defi/useDefiMutations.ts index 6272aff..d169872 100644 --- a/src/realm/defi/useDefiMutations.ts +++ b/src/realm/defi/useDefiMutations.ts @@ -16,9 +16,10 @@ export const useDefiMutations = () => { const saveDefis = useCallback( (records: DeFiProtocol[], wallet: RealmWallet) => { realm.write(() => { - const newRecordsIds = records.map(r => `"${r.id}"`).join(','); - - const toDelete = getDefisForMutations(realm).filtered(`walletId = "${wallet.id}" AND NOT id IN {${newRecordsIds}}`); + const toDelete = getDefisForMutations(realm).filtered( + `walletId = "${wallet.id}" AND NOT id IN $0`, + records.map(r => r.id), + ); realm.delete(toDelete); for (const record of records) { diff --git a/src/realm/migrations/index.ts b/src/realm/migrations/index.ts index d47bec7..5318f89 100644 --- a/src/realm/migrations/index.ts +++ b/src/realm/migrations/index.ts @@ -3,4 +3,5 @@ export * from './migrationsSchemaVersion19'; export * from './migrationsSchemaVersion20'; export * from './migrationsSchemaVersion23'; export * from './migrationsSchemaVersion25'; +export * from './migrationsSchemaVersion26'; export * from './onMigration'; diff --git a/src/realm/migrations/migrationsSchemaVersion26.ts b/src/realm/migrations/migrationsSchemaVersion26.ts new file mode 100644 index 0000000..5860750 --- /dev/null +++ b/src/realm/migrations/migrationsSchemaVersion26.ts @@ -0,0 +1,16 @@ +import Realm from 'realm'; + +import { REALM_TYPE_SETTINGS, RealmSettings, RealmSettingsKey } from '../settings/schema'; + +export const migrationsSchemaVersion26 = (oldRealm: Realm, newRealm: Realm) => { + if (oldRealm.schemaVersion < 26) { + newRealm.create( + REALM_TYPE_SETTINGS, + { + name: RealmSettingsKey.whatsNewIsAssetMarketDataCompleted, + value: false, + }, + Realm.UpdateMode.Modified, + ); + } +}; diff --git a/src/realm/migrations/onMigration.ts b/src/realm/migrations/onMigration.ts index 34bbe56..2f88d2a 100644 --- a/src/realm/migrations/onMigration.ts +++ b/src/realm/migrations/onMigration.ts @@ -1,6 +1,13 @@ import Realm from 'realm'; -import { migrationsSchemaVersion18, migrationsSchemaVersion19, migrationsSchemaVersion20, migrationsSchemaVersion23, migrationsSchemaVersion25 } from './'; +import { + migrationsSchemaVersion18, + migrationsSchemaVersion19, + migrationsSchemaVersion20, + migrationsSchemaVersion23, + migrationsSchemaVersion25, + migrationsSchemaVersion26, +} from './'; export const onMigration = (oldRealm: Realm, newRealm: Realm) => { migrationsSchemaVersion18(oldRealm, newRealm); @@ -8,4 +15,5 @@ export const onMigration = (oldRealm: Realm, newRealm: Realm) => { migrationsSchemaVersion20(oldRealm, newRealm); migrationsSchemaVersion23(oldRealm, newRealm); migrationsSchemaVersion25(oldRealm, newRealm); + migrationsSchemaVersion26(oldRealm, newRealm); }; diff --git a/src/realm/nfts/useNfts.ts b/src/realm/nfts/useNfts.ts index 8d83b94..a545908 100644 --- a/src/realm/nfts/useNfts.ts +++ b/src/realm/nfts/useNfts.ts @@ -7,7 +7,7 @@ import { REALM_TYPE_NFT, RealmNft } from './schema'; export const useNfts = (archived = false, networkFilter: string[] = []) => { const walletIds = useRealmWallets().map(w => w.id); - const nfts = useQuery(REALM_TYPE_NFT).filtered("walletId IN $0 AND metadata.collectionId != ''", walletIds); + const nfts = useQuery(REALM_TYPE_NFT, nft => nft.filtered("walletId IN $0 AND metadata.collectionId != ''", walletIds), [walletIds]); return useMemo(() => { const nftsFilteredByNetwork = networkFilter.length ? nfts.filtered('assetId BEGINSWITH[c] ANY $0', networkFilter) : nfts; diff --git a/src/realm/realmSchema.ts b/src/realm/realmSchema.ts index e59ee94..98ec0da 100644 --- a/src/realm/realmSchema.ts +++ b/src/realm/realmSchema.ts @@ -71,7 +71,7 @@ export const RealmSchema = [ ]; export const realmConfig: Configuration = { - schemaVersion: 25, + schemaVersion: 26, schema: RealmSchema, onMigration, }; diff --git a/src/realm/settings/schema.ts b/src/realm/settings/schema.ts index be613ca..b49d158 100644 --- a/src/realm/settings/schema.ts +++ b/src/realm/settings/schema.ts @@ -19,7 +19,9 @@ export enum RealmSettingsKey { walletConnectTaskCompleted = 'walletConnectTaskCompleted', storeReviewTaskCompleted = 'storeReviewTaskCompleted', storeReviewSubmitted = 'storeReviewSubmitted', + isBlastModalCompleted = 'isBlastModalCompleted', + whatsNewIsAssetMarketDataCompleted = 'whatsNewIsAssetMarketDataCompleted', } export type SettingsType = { @@ -38,6 +40,7 @@ export type SettingsType = { [RealmSettingsKey.storeReviewTaskCompleted]: boolean; [RealmSettingsKey.storeReviewSubmitted]: boolean; [RealmSettingsKey.isBlastModalCompleted]: boolean; + [RealmSettingsKey.whatsNewIsAssetMarketDataCompleted]: boolean; }; export type Settings = { diff --git a/src/realm/settings/useSettingsByKey.ts b/src/realm/settings/useSettingsByKey.ts index 1e8dc98..b447001 100644 --- a/src/realm/settings/useSettingsByKey.ts +++ b/src/realm/settings/useSettingsByKey.ts @@ -3,7 +3,7 @@ import { useQuery } from '@/realm/RealmContext'; import { REALM_TYPE_SETTINGS, RealmSettings, SettingsType } from './schema'; export function useSettingsByKey(key: T): SettingsType[T] | undefined { - const results = useQuery(REALM_TYPE_SETTINGS).filtered(`name = "${key}"`); + const results = useQuery(REALM_TYPE_SETTINGS, settings => settings.filtered(`name = "${key}"`), [key]); if (results.isEmpty()) { return; } diff --git a/src/realm/settings/useSettingsMutations.ts b/src/realm/settings/useSettingsMutations.ts index 9a20616..386e27e 100644 --- a/src/realm/settings/useSettingsMutations.ts +++ b/src/realm/settings/useSettingsMutations.ts @@ -77,13 +77,6 @@ export const useSettingsMutations = () => { [setSettings], ); - const setIsBlastModalCompleted = useCallback( - (value: boolean) => { - setSettings(RealmSettingsKey.isBlastModalCompleted, value); - }, - [setSettings], - ); - return { setSettings, setAccountNumber, @@ -92,6 +85,5 @@ export const useSettingsMutations = () => { setAppCurrency, setWalletConnectExplainerTaskCompleted, setHasViewedWalletBackupPrompt, - setIsBlastModalCompleted, }; }; diff --git a/src/realm/tokens/useTokens.ts b/src/realm/tokens/useTokens.ts index 3b08785..6ceaf12 100644 --- a/src/realm/tokens/useTokens.ts +++ b/src/realm/tokens/useTokens.ts @@ -1,4 +1,3 @@ -import { useMemo } from 'react'; import Realm from 'realm'; import { useQuery } from '../RealmContext'; @@ -9,20 +8,23 @@ import { REALM_TYPE_TOKEN, RealmToken } from './schema'; export const useTokens = (getTokensFromAllWallets?: boolean) => { const wallets = useRealmWallets(getTokensFromAllWallets); - const phrase = useMemo(() => { - const walletIdString = wallets.map(x => `"${x.id}"`).join(','); - return `walletId IN {${walletIdString}}`; - }, [wallets]); - - const collection = useQuery(REALM_TYPE_TOKEN); - const filteredCollection = useMemo(() => collection.filtered(phrase), [collection, phrase]); - - return filteredCollection; + return useQuery( + REALM_TYPE_TOKEN, + tokens => + tokens.filtered( + 'walletId IN $0', + wallets.map(w => w.id), + ), + [wallets], + ); }; export const getTokensForMutations = (realm: Realm, getTokensFromAllWallets?: boolean) => { const wallets = getWalletsForMutations(realm, getTokensFromAllWallets); const tokensCollection = realm.objects(REALM_TYPE_TOKEN); - return tokensCollection.filtered(`walletId IN {${wallets.map(x => `"${x.id}"`).join(',')}}`); + return tokensCollection.filtered( + 'walletId IN $0', + wallets.map(w => w.id), + ); }; diff --git a/src/realm/transactions/transactionFilters.ts b/src/realm/transactions/transactionFilters.ts index 40d8196..8cbf77e 100644 --- a/src/realm/transactions/transactionFilters.ts +++ b/src/realm/transactions/transactionFilters.ts @@ -1,3 +1,5 @@ +import Realm from 'realm'; + import { Transaction } from '@/api/types'; import { NETWORK_FILTERS } from '@/components/NetworkFilter/types'; import { ChainAgnostic } from '@/onChain/wallets/utils/ChainAgnostic'; @@ -28,7 +30,7 @@ export function isNativeAssetInvolvedInTransaction(obj: Transaction, assetId: st } return true; } -export function filterTransactionsByNetwork(transactions: RealmResults, networkFilter: NETWORK_FILTERS[]) { +export function filterTransactionsByNetwork(transactions: Realm.Results, networkFilter: NETWORK_FILTERS[]) { const phrases = networkFilter.map((item, index) => `wallet.nativeTokenCaipId BEGINSWITH $${index}`); const filterPhrase = phrases.join(' OR '); return transactions.filtered(filterPhrase, ...networkFilter); diff --git a/src/realm/transactions/usePendingTransactions.ts b/src/realm/transactions/usePendingTransactions.ts index 46725f1..ec3fa7f 100644 --- a/src/realm/transactions/usePendingTransactions.ts +++ b/src/realm/transactions/usePendingTransactions.ts @@ -7,18 +7,22 @@ import { useQuery } from '@/realm/RealmContext'; import { REALM_TYPE_PENDING_TRANSACTION, RealmPendingTransaction } from '@/realm/transactions/schema'; import { filterTransactionsByNetwork } from '@/realm/transactions/transactionFilters'; -export const usePendingTransactions = (networkFilter?: NETWORK_FILTERS[]): RealmResults => { +export const usePendingTransactions = (networkFilter?: NETWORK_FILTERS[]) => { const currentAccountIdx = useCurrentAccountNumber(); - const pendingTransactions = useQuery(REALM_TYPE_PENDING_TRANSACTION); - return useMemo(() => { - let filteredTransactions = pendingTransactions - .filtered('wallet.accountIdx = $0 AND additionalStatus != "invalidated"', currentAccountIdx) - .sorted('time', true); - if (networkFilter && networkFilter.length > 0) { - return filterTransactionsByNetwork(filteredTransactions, networkFilter); - } - return filteredTransactions; - }, [pendingTransactions, currentAccountIdx, networkFilter]); + return useQuery( + REALM_TYPE_PENDING_TRANSACTION, + pendingTransactions => { + const filteredTransactions = pendingTransactions + .filtered('wallet.accountIdx = $0 AND additionalStatus != "invalidated"', currentAccountIdx) + .sorted('time', true); + + if (networkFilter && networkFilter.length > 0) { + return filterTransactionsByNetwork(filteredTransactions, networkFilter); + } + return filteredTransactions; + }, + [currentAccountIdx, networkFilter], + ); }; export const usePendingNftTransactions = (assetId?: string, walletId?: string, networkFilter?: NETWORK_FILTERS[]) => { @@ -32,9 +36,9 @@ export const usePendingNftTransactions = (assetId?: string, walletId?: string, n if (!isNativeCoin) { return []; } - let filteredTransactions = pendingTransactions.filtered(`walletId = "${walletId}" AND type = "nft"`).sorted('time', true); + const filteredTransactions = pendingTransactions.filtered(`walletId = "${walletId}" AND type = "nft"`).sorted('time', true); if (networkFilter && networkFilter.length > 0) { - return filterTransactionsByNetwork(filteredTransactions, networkFilter); + return filterTransactionsByNetwork(filteredTransactions, networkFilter); } return filteredTransactions; }, [isNativeCoin, pendingTransactions, walletId, networkFilter]); diff --git a/src/realm/transactions/useTransactions.ts b/src/realm/transactions/useTransactions.ts index b3d21fa..ccd0a94 100644 --- a/src/realm/transactions/useTransactions.ts +++ b/src/realm/transactions/useTransactions.ts @@ -19,31 +19,35 @@ interface Props { } export const useTransactions = ({ walletId, assetId, networkFilter, ignoredIds }: Props) => { - const allTransactions = useQuery(REALM_TYPE_WALLET_TRANSACTION); const accountNumber = useCurrentAccountNumber(); const realm = useRealm(); const filterInUnverifiedAssets = useFilterInUnverifiedAssets(); const filterInBlacklistedAssets = useFilterInBlacklistedAssets(); - return useMemo(() => { - let filteredTransactions = allTransactions.filtered('wallet.accountIdx = $0', accountNumber); + const sortedTransactions = useQuery( + REALM_TYPE_WALLET_TRANSACTION, + allTransactions => { + let filteredTransactions = allTransactions.filtered('wallet.accountIdx = $0', accountNumber); - if (networkFilter && networkFilter.length > 0) { - filteredTransactions = filterTransactionsByNetwork(filteredTransactions, networkFilter); - } + if (networkFilter && networkFilter.length > 0) { + filteredTransactions = filterTransactionsByNetwork(filteredTransactions, networkFilter); + } - if (walletId) { - filteredTransactions = filteredTransactions.filtered(`walletId = "${walletId}"`); - } + if (walletId) { + filteredTransactions = filteredTransactions.filtered(`walletId = "${walletId}"`); + } - filteredTransactions = filteredTransactions.filtered('NOT id IN $0', ignoredIds); + filteredTransactions = filteredTransactions.filtered('NOT id IN $0', ignoredIds); - let sortedTransactions = filteredTransactions.sorted('time', true); + return filteredTransactions.sorted('time', true); + }, + [networkFilter, ignoredIds, accountNumber, walletId], + ); - let transactionsFilteredByReputation = sortedTransactions.filter( + return useMemo(() => { + const transactionsFilteredByReputation = sortedTransactions.filter( tx => !getShouldFilterOutTransactionByReputation(realm, memoizedJSONParseTx(tx.data), filterInUnverifiedAssets, filterInBlacklistedAssets), ); - return filterTransactionsByAssetInvolvement(transactionsFilteredByReputation, assetId); - }, [allTransactions, accountNumber, ignoredIds, networkFilter, walletId, assetId, realm, filterInUnverifiedAssets, filterInBlacklistedAssets]); + }, [sortedTransactions, assetId, realm, filterInUnverifiedAssets, filterInBlacklistedAssets]); }; diff --git a/src/realm/wallets/useWallets.tsx b/src/realm/wallets/useWallets.tsx index a51ef2c..6831e98 100644 --- a/src/realm/wallets/useWallets.tsx +++ b/src/realm/wallets/useWallets.tsx @@ -1,4 +1,3 @@ -import { useMemo } from 'react'; import Realm from 'realm'; import { useCurrentAccountNumber } from '../accounts'; @@ -10,11 +9,14 @@ import { REALM_TYPE_WALLET, RealmWallet } from './schema'; export const useRealmWallets = (showAllWallets = false, accountNumber?: number) => { const currentAccountNumber = useCurrentAccountNumber(); - const wallets = useQuery(REALM_TYPE_WALLET); - return useMemo(() => { - const targetAccountNumber = accountNumber ?? currentAccountNumber; - return showAllWallets ? wallets : wallets.filtered(`accountIdx = ${targetAccountNumber}`); - }, [accountNumber, currentAccountNumber, showAllWallets, wallets]); + return useQuery( + REALM_TYPE_WALLET, + wallets => { + const targetAccountNumber = accountNumber ?? currentAccountNumber; + return showAllWallets ? wallets : wallets.filtered(`accountIdx = ${targetAccountNumber}`); + }, + [accountNumber, currentAccountNumber, showAllWallets], + ); }; export const getWalletsForMutations = (realm: Realm, showAllWallets = false) => { diff --git a/src/screens/AppSignRequest/components/GenericSignContent.tsx b/src/screens/AppSignRequest/components/GenericSignContent.tsx index f0a51fb..2f3501e 100644 --- a/src/screens/AppSignRequest/components/GenericSignContent.tsx +++ b/src/screens/AppSignRequest/components/GenericSignContent.tsx @@ -1,4 +1,4 @@ -import React, { Dispatch, useCallback, useRef, useState } from 'react'; +import React, { Dispatch, useCallback, useEffect, useRef, useState } from 'react'; import { NativeMethods, StyleSheet, View } from 'react-native'; import { ScrollView } from 'react-native-gesture-handler'; @@ -30,11 +30,17 @@ export const GenericSignContent = ({ content, setHasScrolledToEndOfContent }: Pr scrollViewRef.current?.scrollToEnd(); }, []); + useEffect(() => { + scrollViewRef.current?.flashScrollIndicators(); + }, []); + return ( <> { if (endOfContentRef.current && scrollViewRef.current) { endOfContentRef.current.measureLayout(scrollViewRef.current, (left, top, width, height) => { @@ -71,7 +77,7 @@ export const GenericSignContent = ({ content, setHasScrolledToEndOfContent }: Pr return description === '' ? ( ) : ( - + @@ -105,15 +111,14 @@ const styles = StyleSheet.create({ bodyText: { lineHeight: 22, }, + container: { + borderRadius: 16, + }, contentContainer: { paddingHorizontal: 16, paddingVertical: 12, - borderRadius: 16, gap: 16, }, - listItem: { - marginBottom: 16, - }, scrollToEndOfContentButton: { left: 16, paddingVertical: 6, diff --git a/src/screens/BlastWelcoming/index.ts b/src/screens/BlastWelcoming/index.ts deleted file mode 100644 index d851db3..0000000 --- a/src/screens/BlastWelcoming/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './BlastWelcomingScreen'; diff --git a/src/screens/DebugScreen.tsx b/src/screens/DebugScreen.tsx index bc3406d..a2db07f 100644 --- a/src/screens/DebugScreen.tsx +++ b/src/screens/DebugScreen.tsx @@ -48,8 +48,6 @@ import { SettingsBox } from '@/screens/Settings/components/SettingsBox'; import { isSecureDevice } from '@/secureStore/keychain'; import { useTheme } from '@/theme/themes'; -import { FeatureFlag, useFeatureFlag } from '@/utils/featureFlags'; - import { showToast } from '../components/Toast'; import { ALT_GROUNDCONTROL_BASE_URIS, ALT_HARMONY_BASE_URIS, DEFAULT_GROUNDCONTROL_BASE_URI, DEFAULT_HARMONY_BASE_URI } from '/config'; @@ -130,8 +128,6 @@ export const DebugScreen = () => { const deviceInfoRef = useRef(null); const backendConfigRef = useRef(null); - const { toggleFeature: toggleAssetMarketDataEnabled, isFeatureFlagEnabled: isAssetMarketDataEnabled } = useFeatureFlag(FeatureFlag.AssetMarketDataEnabled); - useEffect(() => { (async () => { setToken(await PushNotifications.getInstance().getDeviceToken()); @@ -259,9 +255,6 @@ export const DebugScreen = () => { - - -