From ac5231b15c5df3d1067c0ae7f15ac201d412dc72 Mon Sep 17 00:00:00 2001 From: Edgar Khanzadian Date: Fri, 15 Nov 2024 19:21:39 +0400 Subject: [PATCH] feat: approver ux ui --- apps/mobile/ios/Podfile.lock | 100 ++++++------ .../project.pbxproj | 8 +- apps/mobile/package.json | 2 + apps/mobile/src/app/(home)/_layout.tsx | 2 +- .../src/app/(home)/settings/display/index.tsx | 2 +- .../src/app/(home)/settings/help/index.tsx | 2 +- apps/mobile/src/app/(home)/settings/index.tsx | 2 +- .../app/(home)/settings/networks/index.tsx | 2 +- .../app/(home)/settings/security/index.tsx | 2 +- .../configure/[wallet]/[account]/index.tsx | 2 +- .../src/app/(home)/settings/wallet/index.tsx | 2 +- .../full-height-sheet/full-height-sheet.tsx | 2 +- apps/mobile/src/components/network-badge.tsx | 32 ---- .../components/approver-account-card.tsx | 45 ++++++ .../approver/components/code-card.tsx | 77 +++++++++ .../features/approver/components/fee-card.tsx | 67 ++++++++ .../components/inputs-outputs-card.tsx | 38 +++++ .../approver/components/outcomes-card.tsx | 37 +++++ .../features/approver/components/utxo-row.tsx | 19 +++ .../balances/bitcoin/bitcoin-balance.tsx | 10 +- .../balances/stacks/stacks-balance.tsx | 10 +- .../receive/receive-sheet-navigator.tsx | 9 +- .../receive/receive-sheets/select-account.tsx | 9 +- .../receive/receive-sheets/select-asset.tsx | 34 ++-- apps/mobile/src/features/receive/utils.ts | 29 ++++ apps/mobile/src/features/send/fee-badge.tsx | 43 +++++ .../components/send-form-amount-field.tsx | 7 +- .../send-form/components/send-form-asset.tsx | 12 +- .../send-form/components/send-form-memo.tsx | 7 +- .../components/send-form-recipient.tsx | 7 +- .../src/features/send/send-form/send-form.tsx | 2 + .../send/send-form/sheets/recipient-sheet.tsx | 12 +- .../features/send/send-sheet-navigator.tsx | 13 +- .../send/send-sheets/select-account-sheet.tsx | 9 +- .../send/send-sheets/select-asset-sheet.tsx | 12 +- .../send/send-sheets/send-form-btc-sheet.tsx | 31 ++-- .../send/send-sheets/send-form-stx-sheet.tsx | 31 ++-- .../features/send/send-sheets/sign-psbt.tsx | 105 ++++++++++++ apps/mobile/src/features/send/utils.ts | 32 ++++ .../src/features/settings/network-badge.tsx | 25 +++ packages/tokens/src/typography.ts | 2 +- packages/ui/native.ts | 6 +- packages/ui/package.json | 3 + .../fee-animals/animal-chameleon-32-32.svg | 34 ++++ .../icons/fee-animals/animal-eagle-32-32.svg | 16 ++ .../icons/fee-animals/animal-rabbit-32-32.svg | 8 + .../icons/fee-animals/animal-snail-32-32.svg | 29 ++++ .../components/approver/approver.native.tsx | 44 ++++++ .../components/approver-actions.native.tsx | 10 ++ .../components/approver-advanced.native.tsx | 34 ++++ .../components/approver-container.native.tsx | 28 ++++ .../components/approver-footer.native.tsx | 34 ++++ .../components/approver-header.native.tsx | 12 ++ .../components/approver-section.native.tsx | 22 +++ .../ui/src/components/badge/badge.native.tsx | 56 +++++++ .../highlighting/clarity-prism.shared.ts | 126 +++++++++++++++ .../highlighting/highlighter.native.tsx | 91 +++++++++++ .../highlighting/highlighter.web.tsx | 149 ++++++++++++++++++ .../highlighting/start-pad.shared.ts | 2 + .../components/highlighting/utils.shared.ts | 136 ++++++++++++++++ .../components/pressable/pressable.native.tsx | 5 +- packages/ui/src/exports.web.ts | 2 + .../fee-animals/animal-chameleon.native.tsx | 14 ++ .../icons/fee-animals/animal-eagle.native.tsx | 12 ++ .../fee-animals/animal-rabbit.native.tsx | 12 ++ .../icons/fee-animals/animal-snail.native.tsx | 12 ++ packages/ui/src/icons/index.native.ts | 7 + packages/ui/src/icons/unlock-icon.native.tsx | 19 +++ packages/utils/src/index.ts | 6 + pnpm-lock.yaml | 58 ++++++- 70 files changed, 1694 insertions(+), 187 deletions(-) delete mode 100644 apps/mobile/src/components/network-badge.tsx create mode 100644 apps/mobile/src/features/approver/components/approver-account-card.tsx create mode 100644 apps/mobile/src/features/approver/components/code-card.tsx create mode 100644 apps/mobile/src/features/approver/components/fee-card.tsx create mode 100644 apps/mobile/src/features/approver/components/inputs-outputs-card.tsx create mode 100644 apps/mobile/src/features/approver/components/outcomes-card.tsx create mode 100644 apps/mobile/src/features/approver/components/utxo-row.tsx create mode 100644 apps/mobile/src/features/receive/utils.ts create mode 100644 apps/mobile/src/features/send/fee-badge.tsx create mode 100644 apps/mobile/src/features/send/send-sheets/sign-psbt.tsx create mode 100644 apps/mobile/src/features/send/utils.ts create mode 100644 apps/mobile/src/features/settings/network-badge.tsx create mode 100644 packages/ui/src/assets/icons/fee-animals/animal-chameleon-32-32.svg create mode 100644 packages/ui/src/assets/icons/fee-animals/animal-eagle-32-32.svg create mode 100644 packages/ui/src/assets/icons/fee-animals/animal-rabbit-32-32.svg create mode 100644 packages/ui/src/assets/icons/fee-animals/animal-snail-32-32.svg create mode 100644 packages/ui/src/components/approver/approver.native.tsx create mode 100644 packages/ui/src/components/approver/components/approver-actions.native.tsx create mode 100644 packages/ui/src/components/approver/components/approver-advanced.native.tsx create mode 100644 packages/ui/src/components/approver/components/approver-container.native.tsx create mode 100644 packages/ui/src/components/approver/components/approver-footer.native.tsx create mode 100644 packages/ui/src/components/approver/components/approver-header.native.tsx create mode 100644 packages/ui/src/components/approver/components/approver-section.native.tsx create mode 100644 packages/ui/src/components/badge/badge.native.tsx create mode 100644 packages/ui/src/components/highlighting/clarity-prism.shared.ts create mode 100644 packages/ui/src/components/highlighting/highlighter.native.tsx create mode 100644 packages/ui/src/components/highlighting/highlighter.web.tsx create mode 100644 packages/ui/src/components/highlighting/start-pad.shared.ts create mode 100644 packages/ui/src/components/highlighting/utils.shared.ts create mode 100644 packages/ui/src/icons/fee-animals/animal-chameleon.native.tsx create mode 100644 packages/ui/src/icons/fee-animals/animal-eagle.native.tsx create mode 100644 packages/ui/src/icons/fee-animals/animal-rabbit.native.tsx create mode 100644 packages/ui/src/icons/fee-animals/animal-snail.native.tsx create mode 100644 packages/ui/src/icons/unlock-icon.native.tsx diff --git a/apps/mobile/ios/Podfile.lock b/apps/mobile/ios/Podfile.lock index 67af2e3b1..67f7fa645 100644 --- a/apps/mobile/ios/Podfile.lock +++ b/apps/mobile/ios/Podfile.lock @@ -1619,33 +1619,33 @@ PODS: DEPENDENCIES: - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) - - "EXApplication (from `../../../node_modules/.pnpm/expo-application@5.9.1_expo@51.0.26/node_modules/expo-application/ios`)" - - "EXConstants (from `../../../node_modules/.pnpm/expo-constants@16.0.2_expo@51.0.26/node_modules/expo-constants/ios`)" + - "EXApplication (from `../../../node_modules/.pnpm/expo-application@5.9.1_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7_7lz7kx4ithmpf53d4iw5wfty3a/node_modules/expo-application/ios`)" + - "EXConstants (from `../../../node_modules/.pnpm/expo-constants@16.0.2_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7._6hyhkvmxebmfkuqk4n7n33wbeu/node_modules/expo-constants/ios`)" - "EXJSONUtils (from `../../../node_modules/.pnpm/expo-json-utils@0.13.1/node_modules/expo-json-utils/ios`)" - - "EXManifests (from `../../../node_modules/.pnpm/expo-manifests@0.14.3_expo@51.0.26/node_modules/expo-manifests/ios`)" - - "EXNotifications (from `../../../node_modules/.pnpm/expo-notifications@0.28.14_expo@51.0.26/node_modules/expo-notifications/ios`)" - - "Expo (from `../../../node_modules/.pnpm/expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6__@react-native+as_rs6zimjzbnb5wo5qz3wb7samvq/node_modules/expo`)" - - "expo-dev-client (from `../../../node_modules/.pnpm/expo-dev-client@4.0.20_expo@51.0.26/node_modules/expo-dev-client/ios`)" - - "expo-dev-launcher (from `../../../node_modules/.pnpm/expo-dev-launcher@4.0.22_expo@51.0.26/node_modules/expo-dev-launcher`)" - - "expo-dev-menu (from `../../../node_modules/.pnpm/expo-dev-menu@5.0.16_expo@51.0.26/node_modules/expo-dev-menu`)" - - "expo-dev-menu-interface (from `../../../node_modules/.pnpm/expo-dev-menu-interface@1.8.3_expo@51.0.26/node_modules/expo-dev-menu-interface/ios`)" - - "ExpoAsset (from `../../../node_modules/.pnpm/expo-asset@10.0.6_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6__@react-nati_6amwmu4vugucqsw56blrmvig4e/node_modules/expo-asset/ios`)" - - "ExpoBlur (from `../../../node_modules/.pnpm/expo-blur@13.0.2_expo@51.0.26/node_modules/expo-blur/ios`)" - - "ExpoClipboard (from `../../../node_modules/.pnpm/expo-clipboard@6.0.3_expo@51.0.26/node_modules/expo-clipboard/ios`)" - - "ExpoCrypto (from `../../../node_modules/.pnpm/expo-crypto@13.0.2_expo@51.0.26/node_modules/expo-crypto/ios`)" - - "ExpoDevice (from `../../../node_modules/.pnpm/expo-device@6.0.2_expo@51.0.26/node_modules/expo-device/ios`)" - - "ExpoFileSystem (from `../../../node_modules/.pnpm/expo-file-system@17.0.1_expo@51.0.26/node_modules/expo-file-system/ios`)" - - "ExpoFont (from `../../../node_modules/.pnpm/expo-font@12.0.5_expo@51.0.26/node_modules/expo-font/ios`)" - - "ExpoHead (from `../../../node_modules/.pnpm/expo-router@3.5.14_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6__@react-nat_ulqj4esf6v7azt2eimpkxhoiuu/node_modules/expo-router/ios`)" - - "ExpoImage (from `../../../node_modules/.pnpm/expo-image@1.12.9_expo@51.0.26/node_modules/expo-image/ios`)" - - "ExpoKeepAwake (from `../../../node_modules/.pnpm/expo-keep-awake@13.0.2_expo@51.0.26/node_modules/expo-keep-awake/ios`)" - - "ExpoLocalAuthentication (from `../../../node_modules/.pnpm/expo-local-authentication@14.0.1_expo@51.0.26/node_modules/expo-local-authentication/ios`)" + - "EXManifests (from `../../../node_modules/.pnpm/expo-manifests@0.14.3_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7._kxmlgbanmij6z36l3pnsibhlha/node_modules/expo-manifests/ios`)" + - "EXNotifications (from `../../../node_modules/.pnpm/expo-notifications@0.28.14_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+co_34qdk7mejsopgk23vy7bbnsvsq/node_modules/expo-notifications/ios`)" + - "Expo (from `../../../node_modules/.pnpm/expo@51.0.26_f4nuazufu6irvgtd3prinuxkb4/node_modules/expo`)" + - "expo-dev-client (from `../../../node_modules/.pnpm/expo-dev-client@4.0.20_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7_gmps7dyuicvyrydfqbtht5hiam/node_modules/expo-dev-client/ios`)" + - "expo-dev-launcher (from `../../../node_modules/.pnpm/expo-dev-launcher@4.0.22_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core_4yn64zgy6nc4ta3qecehvlodhy/node_modules/expo-dev-launcher`)" + - "expo-dev-menu (from `../../../node_modules/.pnpm/expo-dev-menu@5.0.16_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.2_sv4q23kfwrr3e7xjv5gylxpsgq/node_modules/expo-dev-menu`)" + - "expo-dev-menu-interface (from `../../../node_modules/.pnpm/expo-dev-menu-interface@1.8.3_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel_3pff7gitcjyg3566uk7iek4nly/node_modules/expo-dev-menu-interface/ios`)" + - "ExpoAsset (from `../../../node_modules/.pnpm/expo-asset@10.0.6_b5dqityn7dtitewgaq3fc4hps4/node_modules/expo-asset/ios`)" + - "ExpoBlur (from `../../../node_modules/.pnpm/expo-blur@13.0.2_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6__7adgaqkt3gd55jdqlkye4ibxjq/node_modules/expo-blur/ios`)" + - "ExpoClipboard (from `../../../node_modules/.pnpm/expo-clipboard@6.0.3_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.2_ccxjrrzlt5s5uamvnr4nwtms4e/node_modules/expo-clipboard/ios`)" + - "ExpoCrypto (from `../../../node_modules/.pnpm/expo-crypto@13.0.2_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24._h2ulmuk5g5qgvgcwhyc4imwx24/node_modules/expo-crypto/ios`)" + - "ExpoDevice (from `../../../node_modules/.pnpm/expo-device@6.0.2_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6_ypbzdx34cdu4iu7nzusi7hd7eq/node_modules/expo-device/ios`)" + - "ExpoFileSystem (from `../../../node_modules/.pnpm/expo-file-system@17.0.1_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@_oh5zrhcvqmg5s6il5rvw6x2gya/node_modules/expo-file-system/ios`)" + - "ExpoFont (from `../../../node_modules/.pnpm/expo-font@12.0.5_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6__afwzzcqn4qtqhraani2se7asxi/node_modules/expo-font/ios`)" + - "ExpoHead (from `../../../node_modules/.pnpm/expo-router@3.5.14_ziqwy7qcm4nz5ldsjzzgjxs67m/node_modules/expo-router/ios`)" + - "ExpoImage (from `../../../node_modules/.pnpm/expo-image@1.12.9_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6_pqycbzooiimpwcftmzylw6b6ue/node_modules/expo-image/ios`)" + - "ExpoKeepAwake (from `../../../node_modules/.pnpm/expo-keep-awake@13.0.2_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7_w5fcokd4xqykouihhq65zfvhwu/node_modules/expo-keep-awake/ios`)" + - "ExpoLocalAuthentication (from `../../../node_modules/.pnpm/expo-local-authentication@14.0.1_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@ba_bcvjridgatxs26fiu2o33lgbby/node_modules/expo-local-authentication/ios`)" - "ExpoModulesCore (from `../../../node_modules/.pnpm/expo-modules-core@1.12.20/node_modules/expo-modules-core`)" - - "ExpoSecureStore (from `../../../node_modules/.pnpm/expo-secure-store@13.0.2_patch_hash=hl63v2r5dtztyuge4wydprmp6u_expo@51.0.26/node_modules/expo-secure-store/ios`)" - - "ExpoSystemUI (from `../../../node_modules/.pnpm/expo-system-ui@3.0.7_expo@51.0.26/node_modules/expo-system-ui/ios`)" - - "ExpoWebBrowser (from `../../../node_modules/.pnpm/expo-web-browser@13.0.3_expo@51.0.26/node_modules/expo-web-browser/ios`)" - - "EXSplashScreen (from `../../../node_modules/.pnpm/expo-splash-screen@0.27.4_expo-modules-autolinking@1.11.1_expo@51.0.26/node_modules/expo-splash-screen/ios`)" - - "EXUpdatesInterface (from `../../../node_modules/.pnpm/expo-updates-interface@0.16.2_expo@51.0.26/node_modules/expo-updates-interface/ios`)" + - "ExpoSecureStore (from `../../../node_modules/.pnpm/expo-secure-store@13.0.2_patch_hash=hl63v2r5dtztyuge4wydprmp6u_expo@51.0.26_@babel+core@7.24._qblhklgyytdrqryzqbjo45ylay/node_modules/expo-secure-store/ios`)" + - "ExpoSystemUI (from `../../../node_modules/.pnpm/expo-system-ui@3.0.7_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.2_36opljfl2csscygkp6xjaz2hv4/node_modules/expo-system-ui/ios`)" + - "ExpoWebBrowser (from `../../../node_modules/.pnpm/expo-web-browser@13.0.3_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@_rn7tpmwskp4kjoe2dtluysnlry/node_modules/expo-web-browser/ios`)" + - "EXSplashScreen (from `../../../node_modules/.pnpm/expo-splash-screen@0.27.4_expo-modules-autolinking@1.11.1_expo@51.0.26_@babel+core@7.24.6_@ba_rk6ye7ixhx2dscrdqo6c2gudcq/node_modules/expo-splash-screen/ios`)" + - "EXUpdatesInterface (from `../../../node_modules/.pnpm/expo-updates-interface@0.16.2_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel_f6sminjnqm3hizjnssizza27yu/node_modules/expo-updates-interface/ios`)" - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) - fmt (from `../node_modules/react-native/third-party-podspecs/fmt.podspec`) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) @@ -1731,59 +1731,59 @@ EXTERNAL SOURCES: DoubleConversion: :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" EXApplication: - :path: "../../../node_modules/.pnpm/expo-application@5.9.1_expo@51.0.26/node_modules/expo-application/ios" + :path: "../../../node_modules/.pnpm/expo-application@5.9.1_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7_7lz7kx4ithmpf53d4iw5wfty3a/node_modules/expo-application/ios" EXConstants: - :path: "../../../node_modules/.pnpm/expo-constants@16.0.2_expo@51.0.26/node_modules/expo-constants/ios" + :path: "../../../node_modules/.pnpm/expo-constants@16.0.2_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7._6hyhkvmxebmfkuqk4n7n33wbeu/node_modules/expo-constants/ios" EXJSONUtils: :path: "../../../node_modules/.pnpm/expo-json-utils@0.13.1/node_modules/expo-json-utils/ios" EXManifests: - :path: "../../../node_modules/.pnpm/expo-manifests@0.14.3_expo@51.0.26/node_modules/expo-manifests/ios" + :path: "../../../node_modules/.pnpm/expo-manifests@0.14.3_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7._kxmlgbanmij6z36l3pnsibhlha/node_modules/expo-manifests/ios" EXNotifications: - :path: "../../../node_modules/.pnpm/expo-notifications@0.28.14_expo@51.0.26/node_modules/expo-notifications/ios" + :path: "../../../node_modules/.pnpm/expo-notifications@0.28.14_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+co_34qdk7mejsopgk23vy7bbnsvsq/node_modules/expo-notifications/ios" Expo: - :path: "../../../node_modules/.pnpm/expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6__@react-native+as_rs6zimjzbnb5wo5qz3wb7samvq/node_modules/expo" + :path: "../../../node_modules/.pnpm/expo@51.0.26_f4nuazufu6irvgtd3prinuxkb4/node_modules/expo" expo-dev-client: - :path: "../../../node_modules/.pnpm/expo-dev-client@4.0.20_expo@51.0.26/node_modules/expo-dev-client/ios" + :path: "../../../node_modules/.pnpm/expo-dev-client@4.0.20_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7_gmps7dyuicvyrydfqbtht5hiam/node_modules/expo-dev-client/ios" expo-dev-launcher: - :path: "../../../node_modules/.pnpm/expo-dev-launcher@4.0.22_expo@51.0.26/node_modules/expo-dev-launcher" + :path: "../../../node_modules/.pnpm/expo-dev-launcher@4.0.22_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core_4yn64zgy6nc4ta3qecehvlodhy/node_modules/expo-dev-launcher" expo-dev-menu: - :path: "../../../node_modules/.pnpm/expo-dev-menu@5.0.16_expo@51.0.26/node_modules/expo-dev-menu" + :path: "../../../node_modules/.pnpm/expo-dev-menu@5.0.16_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.2_sv4q23kfwrr3e7xjv5gylxpsgq/node_modules/expo-dev-menu" expo-dev-menu-interface: - :path: "../../../node_modules/.pnpm/expo-dev-menu-interface@1.8.3_expo@51.0.26/node_modules/expo-dev-menu-interface/ios" + :path: "../../../node_modules/.pnpm/expo-dev-menu-interface@1.8.3_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel_3pff7gitcjyg3566uk7iek4nly/node_modules/expo-dev-menu-interface/ios" ExpoAsset: - :path: "../../../node_modules/.pnpm/expo-asset@10.0.6_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6__@react-nati_6amwmu4vugucqsw56blrmvig4e/node_modules/expo-asset/ios" + :path: "../../../node_modules/.pnpm/expo-asset@10.0.6_b5dqityn7dtitewgaq3fc4hps4/node_modules/expo-asset/ios" ExpoBlur: - :path: "../../../node_modules/.pnpm/expo-blur@13.0.2_expo@51.0.26/node_modules/expo-blur/ios" + :path: "../../../node_modules/.pnpm/expo-blur@13.0.2_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6__7adgaqkt3gd55jdqlkye4ibxjq/node_modules/expo-blur/ios" ExpoClipboard: - :path: "../../../node_modules/.pnpm/expo-clipboard@6.0.3_expo@51.0.26/node_modules/expo-clipboard/ios" + :path: "../../../node_modules/.pnpm/expo-clipboard@6.0.3_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.2_ccxjrrzlt5s5uamvnr4nwtms4e/node_modules/expo-clipboard/ios" ExpoCrypto: - :path: "../../../node_modules/.pnpm/expo-crypto@13.0.2_expo@51.0.26/node_modules/expo-crypto/ios" + :path: "../../../node_modules/.pnpm/expo-crypto@13.0.2_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24._h2ulmuk5g5qgvgcwhyc4imwx24/node_modules/expo-crypto/ios" ExpoDevice: - :path: "../../../node_modules/.pnpm/expo-device@6.0.2_expo@51.0.26/node_modules/expo-device/ios" + :path: "../../../node_modules/.pnpm/expo-device@6.0.2_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6_ypbzdx34cdu4iu7nzusi7hd7eq/node_modules/expo-device/ios" ExpoFileSystem: - :path: "../../../node_modules/.pnpm/expo-file-system@17.0.1_expo@51.0.26/node_modules/expo-file-system/ios" + :path: "../../../node_modules/.pnpm/expo-file-system@17.0.1_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@_oh5zrhcvqmg5s6il5rvw6x2gya/node_modules/expo-file-system/ios" ExpoFont: - :path: "../../../node_modules/.pnpm/expo-font@12.0.5_expo@51.0.26/node_modules/expo-font/ios" + :path: "../../../node_modules/.pnpm/expo-font@12.0.5_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6__afwzzcqn4qtqhraani2se7asxi/node_modules/expo-font/ios" ExpoHead: - :path: "../../../node_modules/.pnpm/expo-router@3.5.14_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6__@react-nat_ulqj4esf6v7azt2eimpkxhoiuu/node_modules/expo-router/ios" + :path: "../../../node_modules/.pnpm/expo-router@3.5.14_ziqwy7qcm4nz5ldsjzzgjxs67m/node_modules/expo-router/ios" ExpoImage: - :path: "../../../node_modules/.pnpm/expo-image@1.12.9_expo@51.0.26/node_modules/expo-image/ios" + :path: "../../../node_modules/.pnpm/expo-image@1.12.9_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.24.6_pqycbzooiimpwcftmzylw6b6ue/node_modules/expo-image/ios" ExpoKeepAwake: - :path: "../../../node_modules/.pnpm/expo-keep-awake@13.0.2_expo@51.0.26/node_modules/expo-keep-awake/ios" + :path: "../../../node_modules/.pnpm/expo-keep-awake@13.0.2_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7_w5fcokd4xqykouihhq65zfvhwu/node_modules/expo-keep-awake/ios" ExpoLocalAuthentication: - :path: "../../../node_modules/.pnpm/expo-local-authentication@14.0.1_expo@51.0.26/node_modules/expo-local-authentication/ios" + :path: "../../../node_modules/.pnpm/expo-local-authentication@14.0.1_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@ba_bcvjridgatxs26fiu2o33lgbby/node_modules/expo-local-authentication/ios" ExpoModulesCore: :path: "../../../node_modules/.pnpm/expo-modules-core@1.12.20/node_modules/expo-modules-core" ExpoSecureStore: - :path: "../../../node_modules/.pnpm/expo-secure-store@13.0.2_patch_hash=hl63v2r5dtztyuge4wydprmp6u_expo@51.0.26/node_modules/expo-secure-store/ios" + :path: "../../../node_modules/.pnpm/expo-secure-store@13.0.2_patch_hash=hl63v2r5dtztyuge4wydprmp6u_expo@51.0.26_@babel+core@7.24._qblhklgyytdrqryzqbjo45ylay/node_modules/expo-secure-store/ios" ExpoSystemUI: - :path: "../../../node_modules/.pnpm/expo-system-ui@3.0.7_expo@51.0.26/node_modules/expo-system-ui/ios" + :path: "../../../node_modules/.pnpm/expo-system-ui@3.0.7_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@7.2_36opljfl2csscygkp6xjaz2hv4/node_modules/expo-system-ui/ios" ExpoWebBrowser: - :path: "../../../node_modules/.pnpm/expo-web-browser@13.0.3_expo@51.0.26/node_modules/expo-web-browser/ios" + :path: "../../../node_modules/.pnpm/expo-web-browser@13.0.3_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel+core@_rn7tpmwskp4kjoe2dtluysnlry/node_modules/expo-web-browser/ios" EXSplashScreen: - :path: "../../../node_modules/.pnpm/expo-splash-screen@0.27.4_expo-modules-autolinking@1.11.1_expo@51.0.26/node_modules/expo-splash-screen/ios" + :path: "../../../node_modules/.pnpm/expo-splash-screen@0.27.4_expo-modules-autolinking@1.11.1_expo@51.0.26_@babel+core@7.24.6_@ba_rk6ye7ixhx2dscrdqo6c2gudcq/node_modules/expo-splash-screen/ios" EXUpdatesInterface: - :path: "../../../node_modules/.pnpm/expo-updates-interface@0.16.2_expo@51.0.26/node_modules/expo-updates-interface/ios" + :path: "../../../node_modules/.pnpm/expo-updates-interface@0.16.2_expo@51.0.26_@babel+core@7.24.6_@babel+preset-env@7.25.8_@babel_f6sminjnqm3hizjnssizza27yu/node_modules/expo-updates-interface/ios" FBLazyVector: :path: "../node_modules/react-native/Libraries/FBLazyVector" fmt: diff --git a/apps/mobile/ios/leatherwalletmobile.xcodeproj/project.pbxproj b/apps/mobile/ios/leatherwalletmobile.xcodeproj/project.pbxproj index f211e8e87..644c3d931 100644 --- a/apps/mobile/ios/leatherwalletmobile.xcodeproj/project.pbxproj +++ b/apps/mobile/ios/leatherwalletmobile.xcodeproj/project.pbxproj @@ -11,17 +11,17 @@ 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; + 1B12FD95F6504898B7BE8160 /* FiraCode-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = B66C2888E3BB47F7A5A88DEB /* FiraCode-Medium.otf */; }; 297A611EBADB4ED0B158576E /* ABCDiatype-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = F520EA8A657049D4A3392B8B /* ABCDiatype-Regular.otf */; }; 322D7CDF54DE4002AED225F1 /* ABCDiatype-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 6B54D2785B5E48D281A8E3C8 /* ABCDiatype-Medium.otf */; }; 3319885B547C452A9C635C5C /* ABCDiatype-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = A6CFA460F0F340ED95800EF2 /* ABCDiatype-Light.otf */; }; 3735F5722A7145C19BC65634 /* noop-file.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17F703D94F4B4BAE9007DC30 /* noop-file.swift */; }; 3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; }; + 639E76F5C6DD4F95BB83688D /* FiraCode-Retina.otf in Resources */ = {isa = PBXBuildFile; fileRef = 76B2513BA2D94EB6BA0D6194 /* FiraCode-Retina.otf */; }; 96905EF65AED1B983A6B3ABC /* libPods-leatherwalletmobile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58EEBF8E8E6FB1BC6CAF49B5 /* libPods-leatherwalletmobile.a */; }; B18059E884C0ABDD17F3DC3D /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC715A2D49A985799AEE119 /* ExpoModulesProvider.swift */; }; BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; }; EC07C78F575D4480A1321AFF /* SpaceMono-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 3F6687E7CB2942B0929D7833 /* SpaceMono-Regular.ttf */; }; - 639E76F5C6DD4F95BB83688D /* FiraCode-Retina.otf in Resources */ = {isa = PBXBuildFile; fileRef = 76B2513BA2D94EB6BA0D6194 /* FiraCode-Retina.otf */; }; - 1B12FD95F6504898B7BE8160 /* FiraCode-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = B66C2888E3BB47F7A5A88DEB /* FiraCode-Medium.otf */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -37,16 +37,16 @@ 6B54D2785B5E48D281A8E3C8 /* ABCDiatype-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "ABCDiatype-Medium.otf"; path = "../node_modules/@leather.io/ui/src/assets-native/fonts/ABCDiatype-Medium.otf"; sourceTree = ""; }; 6C2E3173556A471DD304B334 /* Pods-leatherwalletmobile.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-leatherwalletmobile.debug.xcconfig"; path = "Target Support Files/Pods-leatherwalletmobile/Pods-leatherwalletmobile.debug.xcconfig"; sourceTree = ""; }; 70C1354B3AEE44B3B957C23B /* leatherwalletmobile-Bridging-Header.h */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.c.h; name = "leatherwalletmobile-Bridging-Header.h"; path = "leatherwalletmobile/leatherwalletmobile-Bridging-Header.h"; sourceTree = ""; }; + 76B2513BA2D94EB6BA0D6194 /* FiraCode-Retina.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "FiraCode-Retina.otf"; path = "../node_modules/@leather.io/ui/dist-native/src/assets-native/fonts/FiraCode-Retina.otf"; sourceTree = ""; }; 7A4D352CD337FB3A3BF06240 /* Pods-leatherwalletmobile.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-leatherwalletmobile.release.xcconfig"; path = "Target Support Files/Pods-leatherwalletmobile/Pods-leatherwalletmobile.release.xcconfig"; sourceTree = ""; }; A6CFA460F0F340ED95800EF2 /* ABCDiatype-Light.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "ABCDiatype-Light.otf"; path = "../node_modules/@leather.io/ui/src/assets-native/fonts/ABCDiatype-Light.otf"; sourceTree = ""; }; AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = leatherwalletmobile/SplashScreen.storyboard; sourceTree = ""; }; + B66C2888E3BB47F7A5A88DEB /* FiraCode-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "FiraCode-Medium.otf"; path = "../node_modules/@leather.io/ui/dist-native/src/assets-native/fonts/FiraCode-Medium.otf"; sourceTree = ""; }; BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = ""; }; CFE8092428C64AA0AFE1A346 /* MarchePro-Super.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "MarchePro-Super.otf"; path = "../node_modules/@leather.io/ui/src/assets-native/fonts/MarchePro-Super.otf"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; F520EA8A657049D4A3392B8B /* ABCDiatype-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "ABCDiatype-Regular.otf"; path = "../node_modules/@leather.io/ui/src/assets-native/fonts/ABCDiatype-Regular.otf"; sourceTree = ""; }; FAC715A2D49A985799AEE119 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-leatherwalletmobile/ExpoModulesProvider.swift"; sourceTree = ""; }; - 76B2513BA2D94EB6BA0D6194 /* FiraCode-Retina.otf */ = {isa = PBXFileReference; name = "FiraCode-Retina.otf"; path = "../node_modules/@leather.io/ui/dist-native/src/assets-native/fonts/FiraCode-Retina.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - B66C2888E3BB47F7A5A88DEB /* FiraCode-Medium.otf */ = {isa = PBXFileReference; name = "FiraCode-Medium.otf"; path = "../node_modules/@leather.io/ui/dist-native/src/assets-native/fonts/FiraCode-Medium.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 58bb93f18..2fedd1bee 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -36,6 +36,7 @@ "dependencies": { "@crowdin/ota-client": "2.0.0", "@expo/vector-icons": "14.0.0", + "@gorhom/bottom-sheet": "4.6.3", "@hookform/resolvers": "3.9.1", "@leather.io/analytics": "workspace:*", "@leather.io/bitcoin": "workspace:*", @@ -103,6 +104,7 @@ "metro-cache": "0.80.5", "metro-config": "0.80.5", "metro-resolver": "0.80.5", + "prism-react-renderer": "2.4.0", "react": "18.2.0", "react-dom": "18.2.0", "react-hook-form": "7.53.2", diff --git a/apps/mobile/src/app/(home)/_layout.tsx b/apps/mobile/src/app/(home)/_layout.tsx index 9253d9767..36cb9f0a9 100644 --- a/apps/mobile/src/app/(home)/_layout.tsx +++ b/apps/mobile/src/app/(home)/_layout.tsx @@ -4,7 +4,7 @@ import { ActionBarMethods } from '@/components/action-bar/action-bar'; import { HomeHeader } from '@/components/headers/home-header'; import { NakedHeader } from '@/components/headers/naked-header'; import { TitleHeader } from '@/components/headers/title-header'; -import { NetworkBadge } from '@/components/network-badge'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { AppRoutes } from '@/routes'; import { t } from '@lingui/macro'; import { useLingui } from '@lingui/react'; diff --git a/apps/mobile/src/app/(home)/settings/display/index.tsx b/apps/mobile/src/app/(home)/settings/display/index.tsx index 829f713b9..ea4ede60d 100644 --- a/apps/mobile/src/app/(home)/settings/display/index.tsx +++ b/apps/mobile/src/app/(home)/settings/display/index.tsx @@ -1,10 +1,10 @@ import { useRef } from 'react'; import { AnimatedHeaderScreenLayout } from '@/components/headers/animated-header/animated-header-screen.layout'; -import { NetworkBadge } from '@/components/network-badge'; import { AccountIdentifierSheet } from '@/features/settings/account-identifier-sheet'; import { BitcoinUnitSheet } from '@/features/settings/bitcoin-unit-sheet'; import { ConversionUnitSheet } from '@/features/settings/conversion-unit-sheet'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { ThemeSheet } from '@/features/settings/theme-sheet'; import { useSettings } from '@/store/settings/settings'; import { t } from '@lingui/macro'; diff --git a/apps/mobile/src/app/(home)/settings/help/index.tsx b/apps/mobile/src/app/(home)/settings/help/index.tsx index 2493cb253..e17460ed1 100644 --- a/apps/mobile/src/app/(home)/settings/help/index.tsx +++ b/apps/mobile/src/app/(home)/settings/help/index.tsx @@ -1,5 +1,5 @@ import { AnimatedHeaderScreenLayout } from '@/components/headers/animated-header/animated-header-screen.layout'; -import { NetworkBadge } from '@/components/network-badge'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { t } from '@lingui/macro'; import { Cell, GraduateCapIcon, MagicBookIcon, SupportIcon } from '@leather.io/ui/native'; diff --git a/apps/mobile/src/app/(home)/settings/index.tsx b/apps/mobile/src/app/(home)/settings/index.tsx index c93b520a3..7f37384ab 100644 --- a/apps/mobile/src/app/(home)/settings/index.tsx +++ b/apps/mobile/src/app/(home)/settings/index.tsx @@ -2,9 +2,9 @@ import { useRef } from 'react'; import { Divider } from '@/components/divider'; import { AnimatedHeaderScreenLayout } from '@/components/headers/animated-header/animated-header-screen.layout'; -import { NetworkBadge } from '@/components/network-badge'; import { NotifyUserSheetLayout } from '@/components/sheets/notify-user-sheet.layout'; import { useAuthContext } from '@/components/splash-screen-guard/use-auth-context'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { AppRoutes } from '@/routes'; import { TestId } from '@/shared/test-id'; import { t } from '@lingui/macro'; diff --git a/apps/mobile/src/app/(home)/settings/networks/index.tsx b/apps/mobile/src/app/(home)/settings/networks/index.tsx index 8f0ea29a8..90168c65c 100644 --- a/apps/mobile/src/app/(home)/settings/networks/index.tsx +++ b/apps/mobile/src/app/(home)/settings/networks/index.tsx @@ -1,6 +1,6 @@ import { AnimatedHeaderScreenLayout } from '@/components/headers/animated-header/animated-header-screen.layout'; -import { NetworkBadge } from '@/components/network-badge'; import { useToastContext } from '@/components/toast/toast-context'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { useSettings } from '@/store/settings/settings'; import { defaultNetworkPreferences } from '@/store/settings/utils'; import { t } from '@lingui/macro'; diff --git a/apps/mobile/src/app/(home)/settings/security/index.tsx b/apps/mobile/src/app/(home)/settings/security/index.tsx index 113ee60e8..84f798ec8 100644 --- a/apps/mobile/src/app/(home)/settings/security/index.tsx +++ b/apps/mobile/src/app/(home)/settings/security/index.tsx @@ -1,9 +1,9 @@ import { useRef } from 'react'; import { AnimatedHeaderScreenLayout } from '@/components/headers/animated-header/animated-header-screen.layout'; -import { NetworkBadge } from '@/components/network-badge'; import { AnalyticsSheet } from '@/features/settings/analytics-sheet'; import { AppAuthenticationSheet } from '@/features/settings/app-authentication-sheet'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { useSettings } from '@/store/settings/settings'; import { SecurityLevelPreference } from '@/store/settings/utils'; import { t } from '@lingui/macro'; diff --git a/apps/mobile/src/app/(home)/settings/wallet/configure/[wallet]/[account]/index.tsx b/apps/mobile/src/app/(home)/settings/wallet/configure/[wallet]/[account]/index.tsx index 7881af123..269c0d79b 100644 --- a/apps/mobile/src/app/(home)/settings/wallet/configure/[wallet]/[account]/index.tsx +++ b/apps/mobile/src/app/(home)/settings/wallet/configure/[wallet]/[account]/index.tsx @@ -2,8 +2,8 @@ import { useRef } from 'react'; import { AvatarIcon } from '@/components/avatar-icon'; import { AnimatedHeaderScreenLayout } from '@/components/headers/animated-header/animated-header-screen.layout'; -import { NetworkBadge } from '@/components/network-badge'; import { useToastContext } from '@/components/toast/toast-context'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { AccountCard } from '@/features/settings/wallet-and-accounts/account-card'; import { AccountNameSheet } from '@/features/settings/wallet-and-accounts/account-name-sheet'; import { AccountId } from '@/models/domain.model'; diff --git a/apps/mobile/src/app/(home)/settings/wallet/index.tsx b/apps/mobile/src/app/(home)/settings/wallet/index.tsx index aa41c26e7..73db3ac3e 100644 --- a/apps/mobile/src/app/(home)/settings/wallet/index.tsx +++ b/apps/mobile/src/app/(home)/settings/wallet/index.tsx @@ -3,7 +3,7 @@ import { useRef } from 'react'; import { AddWalletSheet } from '@/components/add-wallet/'; import { Divider } from '@/components/divider'; import { AnimatedHeaderScreenLayout } from '@/components/headers/animated-header/animated-header-screen.layout'; -import { NetworkBadge } from '@/components/network-badge'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { WalletsList } from '@/features/settings/wallet-and-accounts/wallets-list'; import { AppRoutes } from '@/routes'; import { useAccounts } from '@/store/accounts/accounts.read'; diff --git a/apps/mobile/src/components/full-height-sheet/full-height-sheet.tsx b/apps/mobile/src/components/full-height-sheet/full-height-sheet.tsx index 30cb97cb0..6e4ecf657 100644 --- a/apps/mobile/src/components/full-height-sheet/full-height-sheet.tsx +++ b/apps/mobile/src/components/full-height-sheet/full-height-sheet.tsx @@ -13,8 +13,8 @@ export function FullHeightSheet({ children, sheetRef }: FullHeightSheetProps) { return ( diff --git a/apps/mobile/src/components/network-badge.tsx b/apps/mobile/src/components/network-badge.tsx deleted file mode 100644 index dd76315ce..000000000 --- a/apps/mobile/src/components/network-badge.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { AppRoutes } from '@/routes'; -import { useSettings } from '@/store/settings/settings'; -import { useLingui } from '@lingui/react'; -import { useRouter } from 'expo-router'; - -import { Box, Text, TouchableOpacity } from '@leather.io/ui/native'; - -export function NetworkBadge() { - const router = useRouter(); - const { i18n } = useLingui(); - const { networkPreference } = useSettings(); - - return ( - router.navigate(AppRoutes.SettingsNetworks)}> - - - {i18n._({ - id: 'settings.header_network', - message: '{network}', - values: { network: networkPreference.name }, - })} - - - - ); -} diff --git a/apps/mobile/src/features/approver/components/approver-account-card.tsx b/apps/mobile/src/features/approver/components/approver-account-card.tsx new file mode 100644 index 000000000..d444ea4ed --- /dev/null +++ b/apps/mobile/src/features/approver/components/approver-account-card.tsx @@ -0,0 +1,45 @@ +import { AvatarIcon } from '@/components/avatar-icon'; +import { AccountListItem } from '@/features/account-list/account-list-item'; +import { AccountAddress } from '@/features/account-list/components/account-address'; +import { AccountBalance } from '@/features/account-list/components/account-balance'; +import { useAccountsByFingerprint } from '@/store/accounts/accounts.read'; +import { useWallets } from '@/store/wallets/wallets.read'; +import { t } from '@lingui/macro'; +import { useTheme } from '@shopify/restyle'; + +import { Text, Theme } from '@leather.io/ui/native'; + +export function ApproverAccountCard() { + const theme = useTheme(); + const { list: walletsList } = useWallets(); + const wallet = walletsList[0]; + + if (!wallet) throw new Error('no wallet present in approver'); + + const { list: accountList } = useAccountsByFingerprint(wallet.fingerprint); + const account = accountList[0]; + + if (!account) throw new Error('no account present in approver'); + + return ( + <> + + {t({ + id: 'approver.account.title', + message: 'With account', + })} + + + } + balance={ + + } + icon={} + walletName={wallet.name} + /> + + ); +} diff --git a/apps/mobile/src/features/approver/components/code-card.tsx b/apps/mobile/src/features/approver/components/code-card.tsx new file mode 100644 index 000000000..96d00585d --- /dev/null +++ b/apps/mobile/src/features/approver/components/code-card.tsx @@ -0,0 +1,77 @@ +import { ScrollView } from 'react-native-gesture-handler'; + +import { t } from '@lingui/macro'; + +import { Highlighter, Prism, Text } from '@leather.io/ui/native'; + +/* eslint-disable-next-line lingui/no-unlocalized-strings */ +const sampleCode = ` +;; hello-world contract + +(define-constant sender 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR) +(define-constant recipient 'SM2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQVX8X0G) + +(define-fungible-token novel-token-19) +(ft-mint? novel-token-19 u12 sender) +(ft-transfer? novel-token-19 u2 sender recipient) + +(define-non-fungible-token hello-nft uint) + +(nft-mint? hello-nft u1 sender) +(nft-mint? hello-nft u2 sender) +(nft-transfer? hello-nft u1 sender recipient) + +(define-public (test-emit-event) + (begin + (print "Event! Hello world") + (ok u1) + ) +) + +(begin (test-emit-event)) + +(define-public (test-event-types) + (begin + (unwrap-panic (ft-mint? novel-token-19 u3 recipient)) + (unwrap-panic (nft-mint? hello-nft u2 recipient)) + (unwrap-panic (stx-transfer? u60 tx-sender 'SZ2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKQ9H6DPR)) + (unwrap-panic (stx-burn? u20 tx-sender)) + (ok u1) + ) +) + +(define-map store { key: (buff 32) } { value: (buff 32) }) + +(define-public (get-value (key (buff 32))) + (begin + (match (map-get? store { key: key }) + entry (ok (get value entry)) + (err 0) + ) + ) +) + +(define-public (set-value (key (buff 32)) (value (buff 32))) + (begin + (map-set store { key: key } { value: value }) + (ok u1) + ) +) + +`; + +export function CodeCard() { + return ( + <> + + {t({ + id: 'approver.code.title', + message: 'Code', + })} + + + + + + ); +} diff --git a/apps/mobile/src/features/approver/components/fee-card.tsx b/apps/mobile/src/features/approver/components/fee-card.tsx new file mode 100644 index 000000000..277474717 --- /dev/null +++ b/apps/mobile/src/features/approver/components/fee-card.tsx @@ -0,0 +1,67 @@ +import { ReactNode } from 'react'; + +import { FeeBadge } from '@/features/send/fee-badge'; +import { t } from '@lingui/macro'; + +import { FeeTypes } from '@leather.io/models'; +import { + AnimalChameleonIcon, + AnimalEagleIcon, + AnimalRabbitIcon, + AnimalSnailIcon, + Avatar, + Box, + ChevronRightIcon, + Flag, + ItemLayout, + Pressable, + Text, +} from '@leather.io/ui/native'; +import { match } from '@leather.io/utils'; + +export function FeeCard({ feeType }: { feeType: FeeTypes }) { + const matchFeeType = match(); + const feeIcon = matchFeeType(feeType, { + [FeeTypes.Low]: , + [FeeTypes.Middle]: , + [FeeTypes.High]: , + [FeeTypes.Custom]: , + [FeeTypes.Unknown]: , + }); + return ( + <> + + + {t({ + id: 'approver.fee.title', + message: 'Fee', + })} + + + + {}} py="3"> + + {feeIcon} + + } + > + } + /> + + + + ); +} diff --git a/apps/mobile/src/features/approver/components/inputs-outputs-card.tsx b/apps/mobile/src/features/approver/components/inputs-outputs-card.tsx new file mode 100644 index 000000000..217101a80 --- /dev/null +++ b/apps/mobile/src/features/approver/components/inputs-outputs-card.tsx @@ -0,0 +1,38 @@ +import { t } from '@lingui/macro'; + +import { Box, Text } from '@leather.io/ui/native'; + +import { UtxoRow } from './utxo-row'; + +export function InputsAndOutputsCard() { + return ( + <> + + {t({ + id: 'approver.inputs-outputs.title', + message: 'Inputs and Outputs', + })} + + + {t({ + id: 'approver.inputs-outputs.input.title', + message: 'Input', + })} + + + + + + + {t({ + id: 'approver.inputs-outputs.output.title', + message: 'Output', + })} + + + + + + + ); +} diff --git a/apps/mobile/src/features/approver/components/outcomes-card.tsx b/apps/mobile/src/features/approver/components/outcomes-card.tsx new file mode 100644 index 000000000..f40e9507a --- /dev/null +++ b/apps/mobile/src/features/approver/components/outcomes-card.tsx @@ -0,0 +1,37 @@ +import { BitcoinTokenBalance } from '@/features/balances/bitcoin/bitcoin-balance'; +import { useWalletTotalBitcoinBalance } from '@/queries/balance/bitcoin-balance.query'; +import { t } from '@lingui/macro'; + +import { AddressDisplayer, Avatar, Box, Flag, Text, UsersTwoIcon } from '@leather.io/ui/native'; + +export function OutcomesCard() { + const { availableBalance, fiatBalance } = useWalletTotalBitcoinBalance(); + return ( + <> + + {t({ + id: 'approver.outcomes.title1', + message: "You'll send", + })} + + + + + + {t({ + id: 'approver.outcomes.title2', + message: 'To address', + })} + + + + + } + > + + + + ); +} diff --git a/apps/mobile/src/features/approver/components/utxo-row.tsx b/apps/mobile/src/features/approver/components/utxo-row.tsx new file mode 100644 index 000000000..3e37cd85c --- /dev/null +++ b/apps/mobile/src/features/approver/components/utxo-row.tsx @@ -0,0 +1,19 @@ +import { Avatar, Flag, ItemLayout, LockIcon, UnlockIcon } from '@leather.io/ui/native'; + +export function UtxoRow({ isLocked }: { isLocked: boolean }) { + const icon = isLocked ? : ; + /* eslint-disable-next-line lingui/no-unlocalized-strings */ + const testAddress1 = 'F418...9e16'; + /* eslint-disable-next-line lingui/no-unlocalized-strings */ + const testAddress2 = 'bc1p...tsc0 6e'; + return ( + {icon}}> + + + ); +} diff --git a/apps/mobile/src/features/balances/bitcoin/bitcoin-balance.tsx b/apps/mobile/src/features/balances/bitcoin/bitcoin-balance.tsx index bb79bf6c7..ffeb598d0 100644 --- a/apps/mobile/src/features/balances/bitcoin/bitcoin-balance.tsx +++ b/apps/mobile/src/features/balances/bitcoin/bitcoin-balance.tsx @@ -23,8 +23,14 @@ export function BitcoinTokenBalance({ } - tokenName={t`Bitcoin`} - chain={t`Layer 1`} + tokenName={t({ + id: 'asset_name.bitcoin', + message: 'Bitcoin', + })} + chain={t({ + id: 'asset_name.layer_1', + message: 'Layer 1', + })} fiatBalance={fiatBalance} availableBalance={availableBalance} onPress={onPress} diff --git a/apps/mobile/src/features/balances/stacks/stacks-balance.tsx b/apps/mobile/src/features/balances/stacks/stacks-balance.tsx index 05f5223f0..4ca0b410a 100644 --- a/apps/mobile/src/features/balances/stacks/stacks-balance.tsx +++ b/apps/mobile/src/features/balances/stacks/stacks-balance.tsx @@ -21,8 +21,14 @@ export function StacksTokenBalance({ } - tokenName={t`Stacks`} - chain={t`Layer 1`} + tokenName={t({ + id: 'asset_name.stacks', + message: 'Stacks', + })} + chain={t({ + id: 'asset_name.layer_1', + message: 'Layer 1', + })} fiatBalance={fiatBalance} availableBalance={availableBalance} onPress={onPress} diff --git a/apps/mobile/src/features/receive/receive-sheet-navigator.tsx b/apps/mobile/src/features/receive/receive-sheet-navigator.tsx index a0eefbdb8..d3c3e625e 100644 --- a/apps/mobile/src/features/receive/receive-sheet-navigator.tsx +++ b/apps/mobile/src/features/receive/receive-sheet-navigator.tsx @@ -1,4 +1,3 @@ -import { Account } from '@/store/accounts/accounts'; import { ParamListBase } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import { useTheme } from '@shopify/restyle'; @@ -7,13 +6,9 @@ import { Theme } from '@leather.io/ui/native'; import { SelectAccount } from './receive-sheets/select-account'; import { SelectAsset } from './receive-sheets/select-asset'; +import { ReceiveSheetNavigatorParamList } from './utils'; -export interface ReceiveSheetNavigatorParamList extends ParamListBase { - 'receive-select-account': undefined; - 'receive-select-asset': { account: Account }; -} - -const Stack = createStackNavigator(); +const Stack = createStackNavigator(); export function ReceiveSheetNavigator() { const theme = useTheme(); diff --git a/apps/mobile/src/features/receive/receive-sheets/select-account.tsx b/apps/mobile/src/features/receive/receive-sheets/select-account.tsx index 7bb6418e3..3ef0ab88c 100644 --- a/apps/mobile/src/features/receive/receive-sheets/select-account.tsx +++ b/apps/mobile/src/features/receive/receive-sheets/select-account.tsx @@ -1,16 +1,17 @@ import { FullHeightSheetHeader } from '@/components/full-height-sheet/full-height-sheet-header'; import { FullHeightSheetLayout } from '@/components/full-height-sheet/full-height-sheet.layout'; -import { NetworkBadge } from '@/components/network-badge'; import { AccountList } from '@/features/account-list/account-list'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { Account } from '@/store/accounts/accounts'; import { useAccounts } from '@/store/accounts/accounts.read'; import { t } from '@lingui/macro'; -import { NavigationProp, useNavigation } from '@react-navigation/native'; -import { ReceiveSheetNavigatorParamList } from '../receive-sheet-navigator'; +import { CreateCurrentReceiveRoute, useReceiveSheetNavigation } from '../utils'; + +type CurrentRoute = CreateCurrentReceiveRoute<'receive-select-account'>; export function SelectAccount() { - const navigation = useNavigation>(); + const navigation = useReceiveSheetNavigation(); const accounts = useAccounts(); function onSelectAccount(account: Account) { diff --git a/apps/mobile/src/features/receive/receive-sheets/select-asset.tsx b/apps/mobile/src/features/receive/receive-sheets/select-asset.tsx index ed1c91c81..92c7e1034 100644 --- a/apps/mobile/src/features/receive/receive-sheets/select-asset.tsx +++ b/apps/mobile/src/features/receive/receive-sheets/select-asset.tsx @@ -3,28 +3,27 @@ import { ScrollView } from 'react-native-gesture-handler'; import { FullHeightSheetHeader } from '@/components/full-height-sheet/full-height-sheet-header'; import { FullHeightSheetLayout } from '@/components/full-height-sheet/full-height-sheet.layout'; -import { NetworkBadge } from '@/components/network-badge'; import { useToastContext } from '@/components/toast/toast-context'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { useBitcoinPayerAddressFromAccountIndex } from '@/store/keychains/bitcoin/bitcoin-keychains.read'; import { useStacksSignerAddressFromAccountIndex } from '@/store/keychains/stacks/stacks-keychains.read'; import { t } from '@lingui/macro'; import { useLingui } from '@lingui/react'; -import { RouteProp, useRoute } from '@react-navigation/native'; import { useTheme } from '@shopify/restyle'; import * as Clipboard from 'expo-clipboard'; import { BtcAvatarIcon, SheetRef, StxAvatarIcon, Theme } from '@leather.io/ui/native'; import { truncateMiddle } from '@leather.io/utils'; -import { ReceiveSheetNavigatorParamList } from '../receive-sheet-navigator'; +import { CreateCurrentReceiveRoute, useReceiveSheetRoute } from '../utils'; import { ReceiveAssetItem } from './receive-asset-item'; import { ReceiveAssetSheet } from './receive-asset-sheet'; -type SelectAssetScreenRouteProp = RouteProp; +type CurrentRoute = CreateCurrentReceiveRoute<'receive-select-asset'>; export function SelectAsset() { const { i18n } = useLingui(); - const route = useRoute(); + const route = useReceiveSheetRoute(); const theme = useTheme(); const { displayToast } = useToastContext(); const receiveSheetRef = useRef(null); @@ -69,8 +68,14 @@ export function SelectAsset() { } onCopy={() => onCopyAddress(nativeSegwitPayerAddress)} @@ -78,8 +83,14 @@ export function SelectAsset() { /> } onCopy={() => onCopyAddress(taprootPayerAddress)} @@ -87,7 +98,10 @@ export function SelectAsset() { /> } onCopy={() => onCopyAddress(stxAddress)} diff --git a/apps/mobile/src/features/receive/utils.ts b/apps/mobile/src/features/receive/utils.ts new file mode 100644 index 000000000..053441f42 --- /dev/null +++ b/apps/mobile/src/features/receive/utils.ts @@ -0,0 +1,29 @@ +import { Account } from '@/store/accounts/accounts'; +import { + NavigationProp, + ParamListBase, + RouteProp, + useNavigation, + useRoute, +} from '@react-navigation/native'; + +export interface ReceiveSheetNavigatorParamList { + 'receive-select-account': undefined; + 'receive-select-asset': { account: Account }; +} + +export type ReceiveSheetRouteKeys = keyof ReceiveSheetNavigatorParamList; + +export type ReceiveSheetRouteProp = RouteProp< + ReceiveSheetNavigatorParamList & ParamListBase, + RouteKey +>; +export function useReceiveSheetRoute() { + return useRoute>(); +} + +export function useReceiveSheetNavigation() { + return useNavigation>(); +} + +export type CreateCurrentReceiveRoute = RouteKey; diff --git a/apps/mobile/src/features/send/fee-badge.tsx b/apps/mobile/src/features/send/fee-badge.tsx new file mode 100644 index 000000000..ab6b17d35 --- /dev/null +++ b/apps/mobile/src/features/send/fee-badge.tsx @@ -0,0 +1,43 @@ +import { useLingui } from '@lingui/react'; + +import { Badge, BadgeVariant } from '@leather.io/ui/native'; +import { match } from '@leather.io/utils'; + +type FeeType = 'low' | 'normal' | 'high' | 'extremely-high'; + +interface FeeBadgeProps { + type: FeeType; +} + +export function FeeBadge(props: FeeBadgeProps) { + const { i18n } = useLingui(); + const matchVariant = match(); + + const variant = matchVariant(props.type, { + low: 'success', + normal: 'default', + high: 'error', + 'extremely-high': 'error', + }); + + const title = matchVariant(props.type, { + low: i18n._({ + id: 'approval-ux.fees.low', + message: 'currently low', + }), + normal: i18n._({ + id: 'approval-ux.fees.normal', + message: 'currently normal', + }), + high: i18n._({ + id: 'approval-ux.fees.high', + message: 'currently high', + }), + 'extremely-high': i18n._({ + id: 'approval-ux.fees.extremely-high', + message: 'currently extremely high', + }), + }); + + return ; +} diff --git a/apps/mobile/src/features/send/send-form/components/send-form-amount-field.tsx b/apps/mobile/src/features/send/send-form/components/send-form-amount-field.tsx index ff52e5de4..f6b9581af 100644 --- a/apps/mobile/src/features/send/send-form/components/send-form-amount-field.tsx +++ b/apps/mobile/src/features/send/send-form/components/send-form-amount-field.tsx @@ -29,7 +29,12 @@ export function SendFormAmountField() { value={value} /> )} - rules={{ required: t`Amount is required` }} + rules={{ + required: t({ + id: 'send-form.amount-field.error.amount-required', + message: 'Amount is required', + }), + }} /> ); } diff --git a/apps/mobile/src/features/send/send-form/components/send-form-asset.tsx b/apps/mobile/src/features/send/send-form/components/send-form-asset.tsx index 17cdda9a1..37d3ddd6d 100644 --- a/apps/mobile/src/features/send/send-form/components/send-form-asset.tsx +++ b/apps/mobile/src/features/send/send-form/components/send-form-asset.tsx @@ -1,26 +1,20 @@ import { TokenBalance } from '@/features/balances/token-balance'; -import { NavigationProp, useNavigation, useRoute } from '@react-navigation/native'; import { Box, Pressable } from '@leather.io/ui/native'; -import { SendSheetNavigatorParamList } from '../../send-sheet-navigator'; -import { SelectAssetRouteProp } from '../../send-sheets/select-asset-sheet'; import { useSendFormContext } from '../send-form-context'; interface SendFormAssetProps { assetName: string; chain: string; icon: React.ReactNode; + onPress(): void; } -export function SendFormAsset({ assetName, chain, icon }: SendFormAssetProps) { +export function SendFormAsset({ assetName, chain, icon, onPress }: SendFormAssetProps) { const { availableBalance, fiatBalance, symbol } = useSendFormContext(); - const navigation = useNavigation>(); - const route = useRoute(); return ( - navigation.navigate('send-select-asset', { account: route.params.account })} - > + - {t`Add memo`} + + {t({ + id: 'send-form.memo.input.label', + message: 'Add memo', + })} + diff --git a/apps/mobile/src/features/send/send-form/components/send-form-recipient.tsx b/apps/mobile/src/features/send/send-form/components/send-form-recipient.tsx index 39a9e3a02..93bd972ac 100644 --- a/apps/mobile/src/features/send/send-form/components/send-form-recipient.tsx +++ b/apps/mobile/src/features/send/send-form/components/send-form-recipient.tsx @@ -47,7 +47,12 @@ export function SendFormRecipient() { ) : ( - {t`Enter recipient`} + + {t({ + id: 'send-form.recipient.input.label', + message: 'Enter recipient', + })} + )} diff --git a/apps/mobile/src/features/send/send-form/send-form.tsx b/apps/mobile/src/features/send/send-form/send-form.tsx index 7b6168ec1..0e0db7829 100644 --- a/apps/mobile/src/features/send/send-form/send-form.tsx +++ b/apps/mobile/src/features/send/send-form/send-form.tsx @@ -4,6 +4,7 @@ import { SendFormAmountField } from './components/send-form-amount-field'; import { SendFormAsset } from './components/send-form-asset'; import { SendFormButton } from './components/send-form-button'; import { SendFormContainer } from './components/send-form-container'; +import { SendFormFooterLayout } from './components/send-form-footer.layout'; import { SendFormMemo } from './components/send-form-memo'; import { SendFormNumpad } from './components/send-form-numpad'; import { SendFormRecipient } from './components/send-form-recipient'; @@ -35,5 +36,6 @@ SendForm.RecipientField = SendFormRecipient; SendForm.Memo = SendFormMemo; SendForm.Numpad = SendFormNumpad; SendForm.Button = SendFormButton; +SendForm.Footer = SendFormFooterLayout; export { SendForm }; diff --git a/apps/mobile/src/features/send/send-form/sheets/recipient-sheet.tsx b/apps/mobile/src/features/send/send-form/sheets/recipient-sheet.tsx index 62f45f831..9b22e408e 100644 --- a/apps/mobile/src/features/send/send-form/sheets/recipient-sheet.tsx +++ b/apps/mobile/src/features/send/send-form/sheets/recipient-sheet.tsx @@ -33,12 +33,20 @@ export function RecipientSheet({ sheetRef }: RecipientSheetProps) { inputState="focused" onBlur={onBlur} onChangeText={value => onChange(value)} - placeholder={t`Enter recipient`} + placeholder={t({ + id: 'recipient-sheet.recipient.input.placeholder', + message: 'Enter recipient', + })} TextInputComponent={UIBottomSheetTextInput} value={value} /> )} - rules={{ required: t`Recipient is required` }} + rules={{ + required: t({ + id: 'recipient-sheet.recipient.error.recipient_required', + message: 'Recipient is required', + }), + }} /> diff --git a/apps/mobile/src/features/send/send-sheet-navigator.tsx b/apps/mobile/src/features/send/send-sheet-navigator.tsx index d70b1a3a6..3c43b38bd 100644 --- a/apps/mobile/src/features/send/send-sheet-navigator.tsx +++ b/apps/mobile/src/features/send/send-sheet-navigator.tsx @@ -1,4 +1,3 @@ -import { Account } from '@/store/accounts/accounts'; import { ParamListBase } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; import { useTheme } from '@shopify/restyle'; @@ -9,15 +8,10 @@ import { SelectAccountSheet } from './send-sheets/select-account-sheet'; import { SelectAssetSheet } from './send-sheets/select-asset-sheet'; import { SendFormBtcSheet } from './send-sheets/send-form-btc-sheet'; import { SendFormStxSheet } from './send-sheets/send-form-stx-sheet'; +import { SignPsbt } from './send-sheets/sign-psbt'; +import { SendSheetNavigatorParamList } from './utils'; -export interface SendSheetNavigatorParamList extends ParamListBase { - 'send-select-account': undefined; - 'send-select-asset': { account: Account }; - 'send-form-btc': { account: Account }; - 'send-form-stx': { account: Account }; -} - -const Stack = createStackNavigator(); +const Stack = createStackNavigator(); export function SendSheetNavigator() { const theme = useTheme(); @@ -36,6 +30,7 @@ export function SendSheetNavigator() { + ); } diff --git a/apps/mobile/src/features/send/send-sheets/select-account-sheet.tsx b/apps/mobile/src/features/send/send-sheets/select-account-sheet.tsx index cc17aa90a..bd0f17307 100644 --- a/apps/mobile/src/features/send/send-sheets/select-account-sheet.tsx +++ b/apps/mobile/src/features/send/send-sheets/select-account-sheet.tsx @@ -1,16 +1,17 @@ import { FullHeightSheetHeader } from '@/components/full-height-sheet/full-height-sheet-header'; import { FullHeightSheetLayout } from '@/components/full-height-sheet/full-height-sheet.layout'; -import { NetworkBadge } from '@/components/network-badge'; import { AccountList } from '@/features/account-list/account-list'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { Account } from '@/store/accounts/accounts'; import { useAccounts } from '@/store/accounts/accounts.read'; import { t } from '@lingui/macro'; -import { NavigationProp, useNavigation } from '@react-navigation/native'; -import { SendSheetNavigatorParamList } from '../send-sheet-navigator'; +import { CreateCurrentSendRoute, useSendSheetNavigation } from '../utils'; + +type CurrentRoute = CreateCurrentSendRoute<'send-select-account'>; export function SelectAccountSheet() { - const navigation = useNavigation>(); + const navigation = useSendSheetNavigation(); const accounts = useAccounts(); function onSelectAccount(account: Account) { diff --git a/apps/mobile/src/features/send/send-sheets/select-asset-sheet.tsx b/apps/mobile/src/features/send/send-sheets/select-asset-sheet.tsx index 9cd782c7f..e76bb7e17 100644 --- a/apps/mobile/src/features/send/send-sheets/select-asset-sheet.tsx +++ b/apps/mobile/src/features/send/send-sheets/select-asset-sheet.tsx @@ -2,26 +2,24 @@ import { ScrollView } from 'react-native-gesture-handler'; import { FullHeightSheetHeader } from '@/components/full-height-sheet/full-height-sheet-header'; import { FullHeightSheetLayout } from '@/components/full-height-sheet/full-height-sheet.layout'; -import { NetworkBadge } from '@/components/network-badge'; import { BitcoinBalanceByAccount } from '@/features/balances/bitcoin/bitcoin-balance'; import { StacksBalanceByAccount } from '@/features/balances/stacks/stacks-balance'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { t } from '@lingui/macro'; import { useLingui } from '@lingui/react'; -import { NavigationProp, RouteProp, useNavigation, useRoute } from '@react-navigation/native'; import { useTheme } from '@shopify/restyle'; import { Theme } from '@leather.io/ui/native'; -import { SendSheetNavigatorParamList } from '../send-sheet-navigator'; +import { CreateCurrentSendRoute, useSendSheetNavigation, useSendSheetRoute } from '../utils'; -export type SelectAssetRouteProp = RouteProp; +type CurrentRoute = CreateCurrentSendRoute<'send-select-asset'>; export function SelectAssetSheet() { const { i18n } = useLingui(); - const route = useRoute(); - const navigation = useNavigation>(); + const route = useSendSheetRoute(); + const navigation = useSendSheetNavigation(); const theme = useTheme(); - const account = route.params.account; const { accountIndex, fingerprint, name } = account; diff --git a/apps/mobile/src/features/send/send-sheets/send-form-btc-sheet.tsx b/apps/mobile/src/features/send/send-sheets/send-form-btc-sheet.tsx index f97d14210..ab93fbcd7 100644 --- a/apps/mobile/src/features/send/send-sheets/send-form-btc-sheet.tsx +++ b/apps/mobile/src/features/send/send-sheets/send-form-btc-sheet.tsx @@ -2,29 +2,27 @@ import { FormProvider, useForm } from 'react-hook-form'; import { FullHeightSheetHeader } from '@/components/full-height-sheet/full-height-sheet-header'; import { FullHeightSheetLayout } from '@/components/full-height-sheet/full-height-sheet.layout'; -import { NetworkBadge } from '@/components/network-badge'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { useBitcoinAccountTotalBitcoinBalance } from '@/queries/balance/bitcoin-balance.query'; import { zodResolver } from '@hookform/resolvers/zod'; import { t } from '@lingui/macro'; import { useLingui } from '@lingui/react'; -import { RouteProp, useRoute } from '@react-navigation/native'; import { BtcAvatarIcon } from '@leather.io/ui/native'; -import { SendFormFooterLayout } from '../send-form/components/send-form-footer.layout'; import { SendFormBtcSchema, defaultSendFormBtcValues, sendFormBtcSchema, } from '../send-form/schemas/send-form-btc.schema'; import { SendForm } from '../send-form/send-form'; -import { SendSheetNavigatorParamList } from '../send-sheet-navigator'; - -type SendFormRouteProp = RouteProp; +import { CreateCurrentSendRoute, useSendSheetNavigation, useSendSheetRoute } from '../utils'; +type CurrentRoute = CreateCurrentSendRoute<'send-form-btc'>; export function SendFormBtcSheet() { const { i18n } = useLingui(); - const route = useRoute(); + const route = useSendSheetRoute(); + const navigation = useSendSheetNavigation(); const formMethods = useForm({ defaultValues: defaultSendFormBtcValues, @@ -62,14 +60,27 @@ export function SendFormBtcSheet() { defaultValues={defaultSendFormBtcValues} schema={sendFormBtcSchema} > - } assetName={t`Bitcoin`} chain={t`Layer 1`} /> + + navigation.navigate('send-select-asset', { account: route.params.account }) + } + icon={} + assetName={t({ + id: 'asset_name.bitcoin', + message: 'Bitcoin', + })} + chain={t({ + id: 'asset_name.layer_1', + message: 'Layer 1', + })} + /> - + - + diff --git a/apps/mobile/src/features/send/send-sheets/send-form-stx-sheet.tsx b/apps/mobile/src/features/send/send-sheets/send-form-stx-sheet.tsx index f29bee508..c222160e1 100644 --- a/apps/mobile/src/features/send/send-sheets/send-form-stx-sheet.tsx +++ b/apps/mobile/src/features/send/send-sheets/send-form-stx-sheet.tsx @@ -2,31 +2,29 @@ import { FormProvider, useForm } from 'react-hook-form'; import { FullHeightSheetHeader } from '@/components/full-height-sheet/full-height-sheet-header'; import { FullHeightSheetLayout } from '@/components/full-height-sheet/full-height-sheet.layout'; -import { NetworkBadge } from '@/components/network-badge'; import { useGetStacksAddresses } from '@/features/balances/stacks/use-get-stacks-addresses'; +import { NetworkBadge } from '@/features/settings/network-badge'; import { useStxBalance } from '@/queries/balance/stacks-balance.query'; import { zodResolver } from '@hookform/resolvers/zod'; import { t } from '@lingui/macro'; import { useLingui } from '@lingui/react'; -import { RouteProp, useRoute } from '@react-navigation/native'; import { StxAvatarIcon } from '@leather.io/ui/native'; -import { SendFormFooterLayout } from '../send-form/components/send-form-footer.layout'; import { SendFormStxSchema, defaultSendFormStxValues, sendFormStxSchema, } from '../send-form/schemas/send-form-stx.schema'; import { SendForm } from '../send-form/send-form'; -import { SendSheetNavigatorParamList } from '../send-sheet-navigator'; +import { CreateCurrentSendRoute, useSendSheetNavigation, useSendSheetRoute } from '../utils'; -type SendFormRouteProp = RouteProp; +type CurrentRoute = CreateCurrentSendRoute<'send-form-stx'>; export function SendFormStxSheet() { const { i18n } = useLingui(); - const route = useRoute(); - + const route = useSendSheetRoute(); + const navigation = useSendSheetNavigation(); const formMethods = useForm({ defaultValues: defaultSendFormStxValues, resolver: zodResolver(sendFormStxSchema), @@ -64,14 +62,27 @@ export function SendFormStxSheet() { defaultValues={defaultSendFormStxValues} schema={sendFormStxSchema} > - } assetName={t`Stacks`} chain={t`Layer 1`} /> + + navigation.navigate('send-select-asset', { account: route.params.account }) + } + icon={} + assetName={t({ + id: 'asset_name.stacks', + message: 'Stacks', + })} + chain={t({ + id: 'asset_name.layer_1', + message: 'Layer 1', + })} + /> - + - + diff --git a/apps/mobile/src/features/send/send-sheets/sign-psbt.tsx b/apps/mobile/src/features/send/send-sheets/sign-psbt.tsx new file mode 100644 index 000000000..1e721a8c3 --- /dev/null +++ b/apps/mobile/src/features/send/send-sheets/sign-psbt.tsx @@ -0,0 +1,105 @@ +import { ApproverAccountCard } from '@/features/approver/components/approver-account-card'; +import { CodeCard } from '@/features/approver/components/code-card'; +import { FeeCard } from '@/features/approver/components/fee-card'; +import { InputsAndOutputsCard } from '@/features/approver/components/inputs-outputs-card'; +import { OutcomesCard } from '@/features/approver/components/outcomes-card'; +import { t } from '@lingui/macro'; +import { useTheme } from '@shopify/restyle'; + +import { FeeTypes } from '@leather.io/models'; +import { Approver, ArrowLeftIcon, Box, Button, Text, Theme } from '@leather.io/ui/native'; + +export function SignPsbt() { + const theme = useTheme(); + + function getButtons(buttonState: 'start' | 'approving' | 'success') { + switch (buttonState) { + case 'start': + return ( + <> +