From 54ac7d58feb8663482c17df6a99eec3f9ac9d9c5 Mon Sep 17 00:00:00 2001 From: Charon-Fan Date: Mon, 7 Jul 2025 10:12:32 +0800 Subject: [PATCH 01/25] feat: Keystone integration --- .../core-mobile/app/assets/icons/keystone.svg | 6 + .../app/assets/icons/keystone_logo_dark.svg | 4 + .../app/assets/icons/keystone_logo_light.svg | 4 + .../core-mobile/app/assets/icons/qrcode.svg | 3 + .../app/hardware/services/KeystoneService.ts | 24 + .../hardware/storage/KeystoneDataStorage.ts | 37 ++ .../app/hardware/wallet/KeystoneWallet.ts | 397 ++++++++++++++ .../core-mobile/app/hardware/wallet/utils.ts | 31 ++ .../common/components/KeystoneQrScanner.tsx | 138 +++++ .../common/components/NavigationRedirect.tsx | 1 + .../new/common/components/QrCodeScanner.tsx | 23 +- .../KeystoneSignerScreen.tsx | 206 ++++++++ .../screens/keystoneTroubleshooting/index.tsx | 128 +++++ .../components/KeystoneTroubleshooting.tsx | 58 ++ .../components/RecoveryUsingKeystone.tsx | 31 ++ .../(modals)/keystoneSigner/_layout.tsx | 12 + .../(modals)/keystoneSigner/index.tsx | 1 + .../keystoneTroubleshooting/_layout.tsx | 12 + .../keystoneTroubleshooting/index.tsx | 1 + .../app/new/routes/(signedIn)/_layout.tsx | 8 + .../app/new/routes/accessWallet.tsx | 13 + .../routes/onboarding/keystone/_layout.tsx | 48 ++ .../onboarding/keystone/analyticsConsent.tsx | 28 + .../onboarding/keystone/confirmation.tsx | 15 + .../routes/onboarding/keystone/createPin.tsx | 51 ++ .../keystone/keystoneTroubleshooting.tsx | 16 + .../keystone/recoveryUsingKeystone.tsx | 53 ++ .../onboarding/keystone/selectAvatar.tsx | 40 ++ .../onboarding/keystone/setWalletName.tsx | 25 + .../keystone/termsAndConditions.tsx | 14 + .../app/security/SecureStorageService.ts | 3 +- .../app/services/wallet/WalletFactory.ts | 7 + .../app/services/wallet/WalletService.tsx | 2 +- .../core-mobile/app/services/wallet/types.ts | 3 +- .../walletConnectCache/types.ts | 13 + .../walletConnectCache/walletConnectCache.ts | 10 +- .../app/store/account/listeners.ts | 15 +- .../e2e/locators/onboarding.loc.ts | 1 + packages/core-mobile/package.json | 7 + yarn.lock | 497 +++++++++++++++++- 40 files changed, 1954 insertions(+), 32 deletions(-) create mode 100644 packages/core-mobile/app/assets/icons/keystone.svg create mode 100644 packages/core-mobile/app/assets/icons/keystone_logo_dark.svg create mode 100644 packages/core-mobile/app/assets/icons/keystone_logo_light.svg create mode 100644 packages/core-mobile/app/assets/icons/qrcode.svg create mode 100644 packages/core-mobile/app/hardware/services/KeystoneService.ts create mode 100644 packages/core-mobile/app/hardware/storage/KeystoneDataStorage.ts create mode 100644 packages/core-mobile/app/hardware/wallet/KeystoneWallet.ts create mode 100644 packages/core-mobile/app/hardware/wallet/utils.ts create mode 100644 packages/core-mobile/app/new/common/components/KeystoneQrScanner.tsx create mode 100644 packages/core-mobile/app/new/features/hardware/screens/KeystoneSignerScreen/KeystoneSignerScreen.tsx create mode 100644 packages/core-mobile/app/new/features/hardware/screens/keystoneTroubleshooting/index.tsx create mode 100644 packages/core-mobile/app/new/features/onboarding/components/KeystoneTroubleshooting.tsx create mode 100644 packages/core-mobile/app/new/features/onboarding/components/RecoveryUsingKeystone.tsx create mode 100644 packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneSigner/_layout.tsx create mode 100644 packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneSigner/index.tsx create mode 100644 packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneTroubleshooting/_layout.tsx create mode 100644 packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneTroubleshooting/index.tsx create mode 100644 packages/core-mobile/app/new/routes/onboarding/keystone/_layout.tsx create mode 100644 packages/core-mobile/app/new/routes/onboarding/keystone/analyticsConsent.tsx create mode 100644 packages/core-mobile/app/new/routes/onboarding/keystone/confirmation.tsx create mode 100644 packages/core-mobile/app/new/routes/onboarding/keystone/createPin.tsx create mode 100644 packages/core-mobile/app/new/routes/onboarding/keystone/keystoneTroubleshooting.tsx create mode 100644 packages/core-mobile/app/new/routes/onboarding/keystone/recoveryUsingKeystone.tsx create mode 100644 packages/core-mobile/app/new/routes/onboarding/keystone/selectAvatar.tsx create mode 100644 packages/core-mobile/app/new/routes/onboarding/keystone/setWalletName.tsx create mode 100644 packages/core-mobile/app/new/routes/onboarding/keystone/termsAndConditions.tsx diff --git a/packages/core-mobile/app/assets/icons/keystone.svg b/packages/core-mobile/app/assets/icons/keystone.svg new file mode 100644 index 0000000000..864eb636b9 --- /dev/null +++ b/packages/core-mobile/app/assets/icons/keystone.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/core-mobile/app/assets/icons/keystone_logo_dark.svg b/packages/core-mobile/app/assets/icons/keystone_logo_dark.svg new file mode 100644 index 0000000000..327f33a89f --- /dev/null +++ b/packages/core-mobile/app/assets/icons/keystone_logo_dark.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/packages/core-mobile/app/assets/icons/keystone_logo_light.svg b/packages/core-mobile/app/assets/icons/keystone_logo_light.svg new file mode 100644 index 0000000000..5066b1532e --- /dev/null +++ b/packages/core-mobile/app/assets/icons/keystone_logo_light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/core-mobile/app/assets/icons/qrcode.svg b/packages/core-mobile/app/assets/icons/qrcode.svg new file mode 100644 index 0000000000..77c7f7ba09 --- /dev/null +++ b/packages/core-mobile/app/assets/icons/qrcode.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/core-mobile/app/hardware/services/KeystoneService.ts b/packages/core-mobile/app/hardware/services/KeystoneService.ts new file mode 100644 index 0000000000..67210c462c --- /dev/null +++ b/packages/core-mobile/app/hardware/services/KeystoneService.ts @@ -0,0 +1,24 @@ +import { + KeystoneDataStorage, + KeystoneDataStorageType +} from '../storage/KeystoneDataStorage' + +class KeystoneService { + private walletInfo = { + evm: '', + xp: '', + mfp: '' + } + + init({ evm, xp, mfp }: KeystoneDataStorageType): void { + this.walletInfo.evm = evm + this.walletInfo.xp = xp + this.walletInfo.mfp = mfp + } + + async refreshPublicKeys(): Promise { + await KeystoneDataStorage.save(this.walletInfo) + } +} + +export default new KeystoneService() diff --git a/packages/core-mobile/app/hardware/storage/KeystoneDataStorage.ts b/packages/core-mobile/app/hardware/storage/KeystoneDataStorage.ts new file mode 100644 index 0000000000..524a6ac0f8 --- /dev/null +++ b/packages/core-mobile/app/hardware/storage/KeystoneDataStorage.ts @@ -0,0 +1,37 @@ +import SecureStorageService, { KeySlot } from 'security/SecureStorageService' +import { assertNotUndefined } from 'utils/assertions' + +export type KeystoneDataStorageType = { + evm: string + xp: string + mfp: string +} + +export class KeystoneDataStorage { + private static cache: KeystoneDataStorageType | undefined = undefined + + static async save(keystoneData: KeystoneDataStorageType): Promise { + await SecureStorageService.store(KeySlot.KeystoneData, keystoneData) + + this.cache = keystoneData + } + + static async retrieve(): Promise { + if (this.cache?.mfp && this.cache?.xp && this.cache?.evm) { + return this.cache + } + + const walletInfo = await SecureStorageService.load( + KeySlot.KeystoneData + ) + assertNotUndefined(walletInfo.mfp, 'no mfp found') + assertNotUndefined(walletInfo.xp, 'no xp found') + assertNotUndefined(walletInfo.evm, 'no evm found') + + return walletInfo + } + + static clearCache(): void { + this.cache = undefined + } +} diff --git a/packages/core-mobile/app/hardware/wallet/KeystoneWallet.ts b/packages/core-mobile/app/hardware/wallet/KeystoneWallet.ts new file mode 100644 index 0000000000..ab3bc6edad --- /dev/null +++ b/packages/core-mobile/app/hardware/wallet/KeystoneWallet.ts @@ -0,0 +1,397 @@ +import { + AvalancheTransactionRequest, + BtcTransactionRequest, + Wallet +} from 'services/wallet/types' +import { + TypedDataV1, + TypedData, + MessageTypes, + RpcMethod +} from '@avalabs/vm-module-types' +import { Curve } from 'utils/publicKeys' +import { assertNotUndefined } from 'utils/assertions' +import { + Avalanche, + BitcoinProvider, + createPsbt, + DerivationPath, + getAddressDerivationPath, + getAddressPublicKeyFromXPub, + JsonRpcBatchInternal +} from '@avalabs/core-wallets-sdk' +import { + CryptoPSBT, + RegistryTypes, + DataType, + ETHSignature, + EthSignRequest +} from '@keystonehq/bc-ur-registry-eth' +import { Common, Hardfork } from '@ethereumjs/common' +import { + AvalancheSignRequest, + AvalancheSignature +} from '@keystonehq/bc-ur-registry-avalanche' +import { + FeeMarketEIP1559Transaction, + FeeMarketEIP1559TxData, + LegacyTransaction +} from '@ethereumjs/tx' +import { UR } from '@ngraveio/bc-ur' +import { rlp } from 'ethereumjs-util' +import { KeystoneDataStorageType } from 'hardware/storage/KeystoneDataStorage' +import { Network } from '@avalabs/core-chains-sdk' +import { Psbt } from 'bitcoinjs-lib' +import { requestKeystoneSigner } from 'features/hardware/screens/KeystoneSignerScreen/KeystoneSignerScreen' +import { v4 } from 'uuid' +import { TransactionRequest } from 'ethers' +import { URType } from '@keystonehq/animated-qr' +import { BigIntLike, BytesLike, AddressLike } from '@ethereumjs/util' +import { convertTxData, makeBigIntLike } from './utils' + +export const EVM_DERIVATION_PATH = `m/44'/60'/0'` +export const AVAX_DERIVATION_PATH = `m/44'/9000'/0'` + +const signer = async ( + request: UR, + responseURTypes: string[], + handleResult: (cbor: Buffer) => Promise +): Promise => { + return new Promise((resolve, reject) => { + requestKeystoneSigner({ + request, + responseURTypes, + onReject: (message?: string) => { + reject(message ?? 'User rejected') + }, + onApprove: (cbor: Buffer) => { + return handleResult(cbor).then(resolve).catch(reject) + } + }) + }) +} + +export default class KeystoneWallet implements Wallet { + #mfp: string + #xpub: string + #xpubXP: string + + constructor(keystoneData: KeystoneDataStorageType) { + this.#mfp = keystoneData.mfp + this.#xpub = keystoneData.evm + this.#xpubXP = keystoneData.xp + } + + public get xpub(): string { + assertNotUndefined(this.#xpub, 'no public key (xpub) available') + return this.#xpub + } + + public get xpubXP(): string { + assertNotUndefined(this.#xpubXP, 'no public key (xpubXP) available') + return this.#xpubXP + } + + public get mfp(): string { + assertNotUndefined(this.#mfp, 'no master fingerprint available') + return this.#mfp + } + + public async signMessage({ + rpcMethod + }: { + rpcMethod: RpcMethod + data: string | TypedDataV1 | TypedData + accountIndex: number + network: Network + provider: JsonRpcBatchInternal + }): Promise { + switch (rpcMethod) { + case RpcMethod.AVALANCHE_SIGN_MESSAGE: { + throw new Error( + '[KeystoneWallet-signMessage] AVALANCHE_SIGN_MESSAGE not implemented.' + ) + } + case RpcMethod.ETH_SIGN: + case RpcMethod.PERSONAL_SIGN: { + throw new Error( + '[KeystoneWallet-signMessage] ETH_SIGN/PERSONAL_SIGN not implemented.' + ) + } + case RpcMethod.SIGN_TYPED_DATA: + case RpcMethod.SIGN_TYPED_DATA_V1: { + throw new Error( + '[KeystoneWallet-signMessage] SIGN_TYPED_DATA/SIGN_TYPED_DATA_V1 not implemented.' + ) + } + case RpcMethod.SIGN_TYPED_DATA_V3: { + throw new Error( + '[KeystoneWallet-signMessage] SIGN_TYPED_DATA_V3 not implemented.' + ) + } + case RpcMethod.SIGN_TYPED_DATA_V4: { + throw new Error( + '[KeystoneWallet-signMessage] SIGN_TYPED_DATA_V4 not implemented.' + ) + } + default: + throw new Error('unknown method') + } + } + + public async signBtcTransaction({ + accountIndex, + transaction, + provider + }: { + accountIndex: number + transaction: BtcTransactionRequest + network: Network + provider: BitcoinProvider + }): Promise { + const { inputs, outputs } = transaction + const psbt = createPsbt(inputs, outputs, provider.getNetwork()) + + inputs.forEach((_, index) => { + psbt.updateInput(index, { + bip32Derivation: [ + { + masterFingerprint: Buffer.from(this.mfp, 'hex'), + pubkey: getAddressPublicKeyFromXPub(this.xpub, accountIndex), + path: getAddressDerivationPath( + accountIndex, + DerivationPath.BIP44, + 'EVM' + ) + } + ] + }) + }) + + const cryptoPSBT = new CryptoPSBT(psbt.toBuffer()) + const ur = cryptoPSBT.toUR() + + return await signer(ur, [RegistryTypes.CRYPTO_PSBT.getType()], cbor => { + const signedTx = CryptoPSBT.fromCBOR(cbor).getPSBT() + return Promise.resolve( + Psbt.fromBuffer(signedTx) + .finalizeAllInputs() + .extractTransaction() + .toHex() + ) + }) + } + + public async signAvalancheTransaction({ + accountIndex, + transaction + }: { + accountIndex: number + transaction: AvalancheTransactionRequest + network: Network + provider: Avalanche.JsonRpcProvider + }): Promise { + const tx = transaction.tx + const isEvmChain = tx.getVM() === 'EVM' + + const requestUR = AvalancheSignRequest.constructAvalancheRequest( + Buffer.from(tx.toBytes()), + this.mfp, + isEvmChain ? this.xpub : this.xpubXP, + accountIndex + ).toUR() + + return await signer(requestUR, ['avax-signature'], cbor => { + const response = AvalancheSignature.fromCBOR(cbor) + const sig = response.getSignature() + tx.addSignature(sig as any) + return Promise.resolve(JSON.stringify(tx.toJSON())) + }) + } + + private txRequestToFeeMarketTxData( + txRequest: TransactionRequest + ): FeeMarketEIP1559TxData { + const { + to, + nonce, + gasLimit, + value, + data, + type, + maxFeePerGas, + maxPriorityFeePerGas + } = txRequest + + return { + to: (to?.toString() || undefined) as AddressLike, + nonce: makeBigIntLike(nonce), + maxFeePerGas: makeBigIntLike(maxFeePerGas), + maxPriorityFeePerGas: makeBigIntLike(maxPriorityFeePerGas), + gasLimit: makeBigIntLike(gasLimit), + value: makeBigIntLike(value), + data: data as BytesLike, + type: type || undefined + } + } + + private async getTxFromTransactionRequest( + txRequest: TransactionRequest, + signature?: { r: BigIntLike; s: BigIntLike; v: BigIntLike } + ): Promise { + return typeof txRequest.gasPrice !== 'undefined' + ? LegacyTransaction.fromTxData( + { + ...convertTxData(txRequest), + ...signature + }, + { + common: Common.custom({ + chainId: Number(txRequest.chainId) + }) + } + ) + : FeeMarketEIP1559Transaction.fromTxData( + { ...this.txRequestToFeeMarketTxData(txRequest), ...signature }, + { + common: Common.custom( + { chainId: Number(txRequest.chainId) }, + { + // "London" hardfork introduced EIP-1559 proposal. Setting it here allows us + // to use the new TX props (maxFeePerGas and maxPriorityFeePerGas) in combination + // with the custom chainId. + hardfork: Hardfork.London + } + ) + } + ) + } + + private async buildSignatureUR( + txRequest: TransactionRequest, + fingerprint: string, + activeAccountIndex: number + ): Promise { + const chainId = txRequest.chainId + const isLegacyTx = typeof txRequest.gasPrice !== 'undefined' + + const tx = await this.getTxFromTransactionRequest(txRequest) + + const message = + tx instanceof FeeMarketEIP1559Transaction + ? tx.getMessageToSign() + : rlp.encode(tx.getMessageToSign()) // Legacy transactions are not RLP-encoded + + const dataType = isLegacyTx + ? DataType.transaction + : DataType.typedTransaction + + // The keyPath below will depend on how the user onboards and should come from WalletService probably, + // based on activeAccount.index, or fetched based on the address passed in params.from. + // This here is BIP44 for the first account (index 0). 2nd account should be M/44'/60'/0'/0/1, etc.. + const keyPath = `M/44'/60'/0'/0/${activeAccountIndex}` + const ethSignRequest = EthSignRequest.constructETHRequest( + Buffer.from(message as any), + dataType, + keyPath, + fingerprint, + v4(), + Number(chainId) + ) + + return ethSignRequest.toUR() + } + + public async signEvmTransaction({ + accountIndex, + transaction + }: { + accountIndex: number + transaction: TransactionRequest + network: Network + provider: JsonRpcBatchInternal + }): Promise { + const ur = await this.buildSignatureUR(transaction, this.mfp, accountIndex) + + return await signer( + ur, + [URType.ETH_SIGNATURE, URType.EVM_SIGNATURE], + async cbor => { + const signature: any = ETHSignature.fromCBOR(cbor).getSignature() + + const r = makeBigIntLike( + Buffer.from(signature.slice(0, 32)).toString('hex') + )! + const s = makeBigIntLike( + Buffer.from(signature.slice(32, 64)).toString('hex') + )! + const v = signature.slice(64) + + const signedTx = await this.getTxFromTransactionRequest(transaction, { + r, + s, + v + }) + + return '0x' + Buffer.from(signedTx.serialize()).toString('hex') + } + ) + } + + private async getAvaSigner( + accountIndex: number, + provider: Avalanche.JsonRpcProvider + ): Promise { + const evmPub = getAddressPublicKeyFromXPub(this.xpub, accountIndex) + const xpPub = Avalanche.getAddressPublicKeyFromXpub( + this.xpubXP, + accountIndex + ) + return Avalanche.StaticSigner.fromPublicKey(xpPub, evmPub, provider) + } + + public async getReadOnlyAvaSigner({ + accountIndex, + provXP + }: { + accountIndex: number + provXP: Avalanche.JsonRpcProvider + }): Promise { + return (await this.getAvaSigner( + accountIndex, + provXP + )) as Avalanche.StaticSigner + } + + private getPublicKey(path: string): Buffer { + const accountIndex = this.getAccountIndex(path) + + if (path.startsWith(EVM_DERIVATION_PATH)) { + return getAddressPublicKeyFromXPub(this.xpub, accountIndex) + } + if (path.startsWith(AVAX_DERIVATION_PATH)) { + return Avalanche.getAddressPublicKeyFromXpub(this.xpubXP, accountIndex) + } + throw new Error(`Unknown path: ${path}`) + } + + private getAccountIndex(path: string): number { + const accountIndex = path.split('/').pop() + if (!accountIndex) { + throw new Error(`Invalid path: ${path}`) + } + return Number(accountIndex) + } + + public async getPublicKeyFor(path: string, curve: Curve): Promise { + const publicKey = this.getPublicKey(path).toString('hex') + + if (!publicKey) { + throw new Error( + `Public key not found for path: ${path} and curve: ${curve}` + ) + } + + return publicKey + } +} diff --git a/packages/core-mobile/app/hardware/wallet/utils.ts b/packages/core-mobile/app/hardware/wallet/utils.ts new file mode 100644 index 0000000000..aa817b35a6 --- /dev/null +++ b/packages/core-mobile/app/hardware/wallet/utils.ts @@ -0,0 +1,31 @@ +import { BigNumberish, TransactionRequest } from 'ethers' +import { BigIntLike, BytesLike, AddressLike } from '@ethereumjs/util' +import isString from 'lodash.isstring' +import { LegacyTxData } from '@ethereumjs/tx' + +const convertToHexString = (n: string): string => { + if (n.startsWith('0x')) return n + return `0x${n}` +} + +export function makeBigIntLike( + n: BigNumberish | undefined | null +): BigIntLike | undefined { + if (n == null) return undefined + if (isString(n)) { + n = convertToHexString(n) + } + return ('0x' + BigInt(n).toString(16)) as BigIntLike +} + +export function convertTxData(txData: TransactionRequest): LegacyTxData { + return { + to: txData.to?.toString() as AddressLike, + nonce: makeBigIntLike(txData.nonce), + gasPrice: makeBigIntLike(txData.gasPrice), + gasLimit: makeBigIntLike(txData.gasLimit), + value: makeBigIntLike(txData.value), + data: txData.data as BytesLike, + type: makeBigIntLike(txData.type) + } +} diff --git a/packages/core-mobile/app/new/common/components/KeystoneQrScanner.tsx b/packages/core-mobile/app/new/common/components/KeystoneQrScanner.tsx new file mode 100644 index 0000000000..84b8c494ef --- /dev/null +++ b/packages/core-mobile/app/new/common/components/KeystoneQrScanner.tsx @@ -0,0 +1,138 @@ +import React, { useState, useCallback, useEffect } from 'react' +import { UR, URDecoder } from '@ngraveio/bc-ur' +import * as Progress from 'react-native-progress' +import { View, Text, SCREEN_WIDTH, useTheme } from '@avalabs/k2-alpine' +import { showKeystoneTroubleshooting } from 'features/hardware/screens/keystoneTroubleshooting' +import { QrCodeScanner } from './QrCodeScanner' +import { Space } from './Space' + +const SCANNER_WIDTH = SCREEN_WIDTH - 64 + +interface Props { + urTypes: string[] + onSuccess: (ur: UR) => void + onError?: () => void + info?: string +} + +export const KeystoneQrScanner: (props: Props) => JSX.Element = ({ + info, + urTypes, + onSuccess, + onError +}) => { + const [urDecoder, setUrDecoder] = useState(new URDecoder()) + const [progress, setProgress] = useState(0) + const [showTroubleshooting, setShowTroubleshooting] = useState(false) + const { theme } = useTheme() + + const progressColor = theme.isDark ? theme.colors.$white : theme.colors.$black + const handleError = useCallback(() => { + setUrDecoder(new URDecoder()) + setShowTroubleshooting(true) + if (onError) { + onError() + } + // if (onError) { + // onError() + // // setProgress(0) + // setShowTroubleshooting(false) + // } else { + // setShowTroubleshooting(true) + // } + }, [onError]) + + const showErrorSheet = useCallback(() => { + showKeystoneTroubleshooting({ + errorCode: -1, + retry: () => { + setShowTroubleshooting(false) + setProgress(0) + } + }) + }, []) + + useEffect(() => { + if (showTroubleshooting && !onError) { + showErrorSheet() + } + }, [showTroubleshooting, showErrorSheet, onError]) + + const handleScan = useCallback( + (code: string) => { + if (showTroubleshooting) { + return + } + try { + urDecoder.receivePart(code) + if (!urDecoder.isComplete()) { + setProgress(urDecoder.estimatedPercentComplete()) + return + } + + if (urDecoder.isError()) { + handleError() + } + + if (urDecoder.isSuccess()) { + const ur = urDecoder.resultUR() + + if (urTypes.includes(ur.type)) { + setProgress(1) + + onSuccess(ur) + } else { + throw new Error('Invalid qr code') + } + } + } catch (error) { + handleError() + } + }, + [ + setProgress, + onSuccess, + urDecoder, + urTypes, + handleError, + showTroubleshooting + ] + ) + + return ( + + + + + + {info && ( + <> + + {info} + + )} + + + ) +} diff --git a/packages/core-mobile/app/new/common/components/NavigationRedirect.tsx b/packages/core-mobile/app/new/common/components/NavigationRedirect.tsx index 5c643ee77f..f873b65c44 100644 --- a/packages/core-mobile/app/new/common/components/NavigationRedirect.tsx +++ b/packages/core-mobile/app/new/common/components/NavigationRedirect.tsx @@ -68,6 +68,7 @@ export const NavigationRedirect = (): null => { } else if ( pathName === '/onboarding/mnemonic/confirmation' || pathName === '/onboarding/seedless/confirmation' || + pathName === '/onboarding/keystone/confirmation' || (pathName === '/loginWithPinOrBiometry' && !isSignedIn) ) { // must call dismissAll() here diff --git a/packages/core-mobile/app/new/common/components/QrCodeScanner.tsx b/packages/core-mobile/app/new/common/components/QrCodeScanner.tsx index 44374f4263..9e43d4f578 100644 --- a/packages/core-mobile/app/new/common/components/QrCodeScanner.tsx +++ b/packages/core-mobile/app/new/common/components/QrCodeScanner.tsx @@ -24,12 +24,14 @@ type Props = { onSuccess: (data: string) => void vibrate?: boolean sx?: SxProp + paused?: boolean } export const QrCodeScanner = ({ onSuccess, vibrate = false, - sx + sx, + paused = false }: Props): React.JSX.Element | undefined => { const { theme: { colors } @@ -40,20 +42,27 @@ export const QrCodeScanner = ({ ) const [data, setData] = useState() - const handleSuccess = (scanningResult: BarcodeScanningResult): void => { - // expo-camera's onBarcodeScanned callback is not debounced, so we need to debounce it ourselves - setData(scanningResult.data) - } + useEffect(() => { + if (paused) { + setData(undefined) + } + }, [paused, setData]) useEffect(() => { - if (data) { + if (data && !paused) { onSuccess(data) if (vibrate) { notificationAsync(NotificationFeedbackType.Success) } } - }, [data, onSuccess, vibrate]) + }, [data, onSuccess, vibrate, paused]) + + const handleSuccess = (scanningResult: BarcodeScanningResult): void => { + if (paused) return + // expo-camera's onBarcodeScanned callback is not debounced, so we need to debounce it ourselves + setData(scanningResult.data) + } const checkIosPermission = useCallback(async () => { if ( diff --git a/packages/core-mobile/app/new/features/hardware/screens/KeystoneSignerScreen/KeystoneSignerScreen.tsx b/packages/core-mobile/app/new/features/hardware/screens/KeystoneSignerScreen/KeystoneSignerScreen.tsx new file mode 100644 index 0000000000..5d138f71c9 --- /dev/null +++ b/packages/core-mobile/app/new/features/hardware/screens/KeystoneSignerScreen/KeystoneSignerScreen.tsx @@ -0,0 +1,206 @@ +import { Button, Text, useTheme, View } from '@avalabs/k2-alpine' +import React, { FC, useCallback, useEffect, useState } from 'react' +import { withWalletConnectCache } from 'common/components/withWalletConnectCache' +import { KeystoneSignerParams } from 'services/walletconnectv2/walletConnectCache/types' +import { walletConnectCache } from 'services/walletconnectv2/walletConnectCache/walletConnectCache' +import { router, useNavigation } from 'expo-router' +import { ScrollScreen } from 'common/components/ScrollScreen' +import { UREncoder } from '@ngraveio/bc-ur' +import { Space } from 'common/components/Space' +import QRCode from 'react-native-qrcode-svg' +import { Dimensions, BackHandler } from 'react-native' +import { KeystoneQrScanner } from 'common/components/KeystoneQrScanner' +import KeystoneLogoLight from 'assets/icons/keystone_logo_light.svg' +import KeystoneLogoDark from 'assets/icons/keystone_logo_dark.svg' + +export const requestKeystoneSigner = (params: KeystoneSignerParams): void => { + walletConnectCache.keystoneSignerParams.set(params) + + router.navigate({ + // @ts-ignore + pathname: '/keystoneSigner' + }) +} + +enum KeystoneSignerStep { + QR, + Scanner +} + +const KeystoneSignerScreen = ({ + params +}: { + params: KeystoneSignerParams +}): JSX.Element => { + const navigation = useNavigation() + const { request, responseURTypes, onApprove, onReject } = params + const [currentStep, setCurrentStep] = useState(KeystoneSignerStep.QR) + const [signningUr, setSigningUr] = useState('(null)') + + useEffect(() => { + const urEncoder = new UREncoder(request, 150) + const timer = setInterval(() => { + setSigningUr(urEncoder.nextPart()) + }, 200) + return () => { + clearInterval(timer) + } + }, [request]) + + const rejectAndClose = useCallback( + (message?: string) => { + onReject(message) + navigation.goBack() + }, + [navigation, onReject] + ) + + useEffect(() => { + const onBackPress = (): boolean => { + // modal is being dismissed via physical back button + rejectAndClose() + return false + } + + const backHandler = BackHandler.addEventListener( + 'hardwareBackPress', + onBackPress + ) + + return () => backHandler.remove() + }, [rejectAndClose]) + + useEffect(() => { + return navigation.addListener('beforeRemove', e => { + if ( + e.data.action.type === 'POP' // gesture dismissed + ) { + // modal is being dismissed via gesture or back button + rejectAndClose() + } + }) + }, [navigation, rejectAndClose]) + + return ( + + + {currentStep === KeystoneSignerStep.QR && ( + <> + + + + )} + {currentStep === KeystoneSignerStep.Scanner && ( + <> +
Scan the QR Code
+ + + )} +
+
+ ) +} + +const { width: screenWidth } = Dimensions.get('window') + +const Header: FC<{ + children: React.ReactNode +}> = ({ children }) => { + const { theme } = useTheme() + + return ( + <> + {theme.isDark ? : } + + {children} + + + ) +} + +const QRRenderer: FC<{ + data: string +}> = ({ data }) => { + const { theme } = useTheme() + const borderWidth = 16 + const containerSize = screenWidth * 0.7 + const qrCodeSize = containerSize - borderWidth * 2 + + return ( + <> +
Scan the QR Code
+ Scan the QR code via your Keystone device + + + + + Click on the 'Get Signature' button after signing the transaction with + your Keystone device. + + + ) +} + +const QRScanner: FC> = ({ + onApprove, + responseURTypes +}) => { + const navigation = useNavigation() + + return ( + + onApprove(ur.cbor).finally(navigation.goBack)} + info={ + 'Place the QR code from your Keystone device in front of the camera.' + } + /> + + ) +} + +export default withWalletConnectCache('keystoneSignerParams')( + KeystoneSignerScreen +) diff --git a/packages/core-mobile/app/new/features/hardware/screens/keystoneTroubleshooting/index.tsx b/packages/core-mobile/app/new/features/hardware/screens/keystoneTroubleshooting/index.tsx new file mode 100644 index 0000000000..58f22b570b --- /dev/null +++ b/packages/core-mobile/app/new/features/hardware/screens/keystoneTroubleshooting/index.tsx @@ -0,0 +1,128 @@ +import React, { useCallback, useEffect } from 'react' +import { withWalletConnectCache } from 'common/components/withWalletConnectCache' +import { KeystoneTroubleshootingParams } from 'services/walletconnectv2/walletConnectCache/types' +import { walletConnectCache } from 'services/walletconnectv2/walletConnectCache/walletConnectCache' +import { router, useNavigation, Link } from 'expo-router' +import { ScrollScreen } from 'common/components/ScrollScreen' +import { BackHandler } from 'react-native' +import { View, Text, SCREEN_WIDTH, Button } from '@avalabs/k2-alpine' +import { Space } from 'common/components/Space' +import QRCode from 'assets/icons/qrcode.svg' + +export const showKeystoneTroubleshooting = ( + params: KeystoneTroubleshootingParams +): void => { + walletConnectCache.keystoneTroubleshootingParams.set(params) + + router.navigate({ + // @ts-ignore + pathname: '/keystoneTroubleshooting' + }) +} + +const KeystoneTroubleshootingScreen = ({ + params +}: { + params: KeystoneTroubleshootingParams +}): JSX.Element => { + const navigation = useNavigation() + const { retry } = params + + const closeAndRetry = useCallback(() => { + retry() + navigation.goBack() + }, [navigation, retry]) + + useEffect(() => { + const onBackPress = (): boolean => { + // modal is being dismissed via physical back button + closeAndRetry() + return false + } + + const backHandler = BackHandler.addEventListener( + 'hardwareBackPress', + onBackPress + ) + + return () => backHandler.remove() + }, [closeAndRetry]) + + useEffect(() => { + return navigation.addListener('beforeRemove', e => { + if ( + e.data.action.type === 'POP' // gesture dismissed + ) { + // modal is being dismissed via gesture or back button + closeAndRetry() + } + }) + }, [navigation, closeAndRetry]) + + return ( + + + + Invalid QR Code + + Please ensure you have selected a valid QR code from your Keystone + device. + + + + + + + + + + Keystone Support + + + + + + ) +} + +export default withWalletConnectCache('keystoneTroubleshootingParams')( + KeystoneTroubleshootingScreen +) diff --git a/packages/core-mobile/app/new/features/onboarding/components/KeystoneTroubleshooting.tsx b/packages/core-mobile/app/new/features/onboarding/components/KeystoneTroubleshooting.tsx new file mode 100644 index 0000000000..a1586c6ce6 --- /dev/null +++ b/packages/core-mobile/app/new/features/onboarding/components/KeystoneTroubleshooting.tsx @@ -0,0 +1,58 @@ +import { Button, Text, View } from '@avalabs/k2-alpine' +import { ScrollScreen } from 'common/components/ScrollScreen' +import { Link } from 'expo-router' +import React, { useCallback } from 'react' + +export const KeystoneTroubleshooting = ({ + retry +}: { + retry: () => void +}): JSX.Element => { + const renderFooter = useCallback(() => { + return ( + + + + + + Keystone Support + + + + + + + ) + }, [retry]) + + return ( + + + + Please ensure you have selected a valid QR code from your Keystone + device. + + + + ) +} diff --git a/packages/core-mobile/app/new/features/onboarding/components/RecoveryUsingKeystone.tsx b/packages/core-mobile/app/new/features/onboarding/components/RecoveryUsingKeystone.tsx new file mode 100644 index 0000000000..eb555affd0 --- /dev/null +++ b/packages/core-mobile/app/new/features/onboarding/components/RecoveryUsingKeystone.tsx @@ -0,0 +1,31 @@ +import React from 'react' +import { View } from '@avalabs/k2-alpine' +import { ScrollScreen } from 'common/components/ScrollScreen' +import { UR, URType } from '@keystonehq/keystone-sdk' +import { KeystoneQrScanner } from 'common/components/KeystoneQrScanner' + +export const RecoveryUsingKeystone = ({ + onSuccess, + onError +}: { + onSuccess: (ur: UR) => void + onError: () => void +}): JSX.Element => { + return ( + + + + + + ) +} diff --git a/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneSigner/_layout.tsx b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneSigner/_layout.tsx new file mode 100644 index 0000000000..4a96eda371 --- /dev/null +++ b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneSigner/_layout.tsx @@ -0,0 +1,12 @@ +import React from 'react' +import { Stack } from 'common/components/Stack' +import { useModalScreenOptions } from 'common/hooks/useModalScreenOptions' +export default function KeystoneSignerLayout(): JSX.Element { + const { modalStackNavigatorScreenOptions, modalFirstScreenOptions } = + useModalScreenOptions() + return ( + + + + ) +} diff --git a/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneSigner/index.tsx b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneSigner/index.tsx new file mode 100644 index 0000000000..18e31a2b23 --- /dev/null +++ b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneSigner/index.tsx @@ -0,0 +1 @@ +export { default } from 'features/hardware/screens/KeystoneSignerScreen/KeystoneSignerScreen' diff --git a/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneTroubleshooting/_layout.tsx b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneTroubleshooting/_layout.tsx new file mode 100644 index 0000000000..4a96eda371 --- /dev/null +++ b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneTroubleshooting/_layout.tsx @@ -0,0 +1,12 @@ +import React from 'react' +import { Stack } from 'common/components/Stack' +import { useModalScreenOptions } from 'common/hooks/useModalScreenOptions' +export default function KeystoneSignerLayout(): JSX.Element { + const { modalStackNavigatorScreenOptions, modalFirstScreenOptions } = + useModalScreenOptions() + return ( + + + + ) +} diff --git a/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneTroubleshooting/index.tsx b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneTroubleshooting/index.tsx new file mode 100644 index 0000000000..0b79bd9568 --- /dev/null +++ b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneTroubleshooting/index.tsx @@ -0,0 +1 @@ +export { default } from 'features/hardware/screens/keystoneTroubleshooting' diff --git a/packages/core-mobile/app/new/routes/(signedIn)/_layout.tsx b/packages/core-mobile/app/new/routes/(signedIn)/_layout.tsx index 356e6152de..e5646a9c0b 100644 --- a/packages/core-mobile/app/new/routes/(signedIn)/_layout.tsx +++ b/packages/core-mobile/app/new/routes/(signedIn)/_layout.tsx @@ -43,6 +43,14 @@ export default function WalletLayout(): JSX.Element { return modalScreensOptions }} /> + + { }) } + const handleEnterKeystone = (): void => { + navigate({ + // @ts-ignore TODO: make routes typesafe + pathname: '/onboarding/keystone/' + }) + } + const handleCreateMnemonicWallet = (): void => { navigate({ // @ts-ignore TODO: make routes typesafe @@ -38,6 +46,11 @@ const AccessWalletScreen = (): JSX.Element => { leftIcon: , onPress: handleEnterRecoveryPhrase }, + { + title: 'Add using Keystone', + leftIcon: , + onPress: handleEnterKeystone + }, { title: 'Create a new wallet', leftIcon: , diff --git a/packages/core-mobile/app/new/routes/onboarding/keystone/_layout.tsx b/packages/core-mobile/app/new/routes/onboarding/keystone/_layout.tsx new file mode 100644 index 0000000000..abcf51732c --- /dev/null +++ b/packages/core-mobile/app/new/routes/onboarding/keystone/_layout.tsx @@ -0,0 +1,48 @@ +import React, { useEffect, useMemo, useState } from 'react' +import { Stack } from 'common/components/Stack' +import { PageControl } from '@avalabs/k2-alpine' +import { stackNavigatorScreenOptions } from 'common/consts/screenOptions' +import { useNavigationContainerRef } from 'expo-router' + +export default function KeystoneOnboardingLayout(): JSX.Element { + const [currentPage, setCurrentPage] = useState(0) + const rootState = useNavigationContainerRef().getRootState() + + const screens = useMemo(() => KEYSTONE_ONBOARDING_SCREENS, []) + + useEffect(() => { + const keystoneOnboardingRoute = rootState.routes + .find(route => route.name === 'onboarding') + ?.state?.routes.find(route => route.name === 'keystone') + if (keystoneOnboardingRoute?.state?.index !== undefined) { + setCurrentPage(keystoneOnboardingRoute.state.index) + } + }, [rootState]) + + const renderPageControl = (): React.ReactNode => ( + + ) + + return ( + + {screens.map(screen => { + return + })} + + ) +} + +const KEYSTONE_ONBOARDING_SCREENS = [ + 'termsAndConditions', + 'analyticsConsent', + 'recoveryUsingKeystone', + 'keystoneTroubleshooting', + 'createPin', + 'setWalletName', + 'selectAvatar', + 'confirmation' +] diff --git a/packages/core-mobile/app/new/routes/onboarding/keystone/analyticsConsent.tsx b/packages/core-mobile/app/new/routes/onboarding/keystone/analyticsConsent.tsx new file mode 100644 index 0000000000..9278f1a5ee --- /dev/null +++ b/packages/core-mobile/app/new/routes/onboarding/keystone/analyticsConsent.tsx @@ -0,0 +1,28 @@ +import React from 'react' +import { useAnalyticsConsent } from 'hooks/useAnalyticsConsent' +import { useRouter } from 'expo-router' +import { AnalyticsConsent as Component } from 'features/onboarding/components/AnalyticsConsent' + +export default function AnalyticsConsent(): JSX.Element { + const { navigate } = useRouter() + const { accept, reject } = useAnalyticsConsent() + + const nextPathname = './recoveryUsingKeystone' + + function handleAcceptAnalytics(): void { + accept() + navigate(nextPathname) + } + + function handleRejectAnalytics(): void { + reject() + navigate(nextPathname) + } + + return ( + + ) +} diff --git a/packages/core-mobile/app/new/routes/onboarding/keystone/confirmation.tsx b/packages/core-mobile/app/new/routes/onboarding/keystone/confirmation.tsx new file mode 100644 index 0000000000..771001240f --- /dev/null +++ b/packages/core-mobile/app/new/routes/onboarding/keystone/confirmation.tsx @@ -0,0 +1,15 @@ +import { Confirmation as Component } from 'features/onboarding/components/Confirmation' +import { useWallet } from 'hooks/useWallet' +import React from 'react' +import { WalletType } from 'services/wallet/types' +import Logger from 'utils/Logger' + +export default function Confirmation(): JSX.Element { + const { login } = useWallet() + + const handleNext = (): void => { + login(WalletType.KEYSTONE).catch(Logger.error) + } + + return +} diff --git a/packages/core-mobile/app/new/routes/onboarding/keystone/createPin.tsx b/packages/core-mobile/app/new/routes/onboarding/keystone/createPin.tsx new file mode 100644 index 0000000000..2944f0ac5d --- /dev/null +++ b/packages/core-mobile/app/new/routes/onboarding/keystone/createPin.tsx @@ -0,0 +1,51 @@ +import { useStoredBiometrics } from 'common/hooks/useStoredBiometrics' +import { useRouter } from 'expo-router' +import { CreatePin as Component } from 'features/onboarding/components/CreatePin' +import { useWallet } from 'hooks/useWallet' +import React, { useCallback } from 'react' +import AnalyticsService from 'services/analytics/AnalyticsService' +import { WalletType } from 'services/wallet/types' +import BiometricsSDK from 'utils/BiometricsSDK' +import Logger from 'utils/Logger' +import { uuid } from 'utils/uuid' + +export default function CreatePin(): JSX.Element { + const { navigate } = useRouter() + const { onPinCreated } = useWallet() + const { isBiometricAvailable, useBiometrics, setUseBiometrics } = + useStoredBiometrics() + + const handleEnteredValidPin = useCallback( + (pin: string): void => { + AnalyticsService.capture('OnboardingPasswordSet') + onPinCreated({ + mnemonic: uuid(), + pin, + walletType: WalletType.KEYSTONE + }) + .then(() => { + if (useBiometrics) { + BiometricsSDK.enableBiometry().catch(Logger.error) + } + navigate({ + // @ts-ignore TODO: make routes typesafe + pathname: '/onboarding/keystone/setWalletName' + }) + }) + .catch(Logger.error) + }, + [navigate, onPinCreated, useBiometrics] + ) + + return ( + + ) +} diff --git a/packages/core-mobile/app/new/routes/onboarding/keystone/keystoneTroubleshooting.tsx b/packages/core-mobile/app/new/routes/onboarding/keystone/keystoneTroubleshooting.tsx new file mode 100644 index 0000000000..5c031b80bf --- /dev/null +++ b/packages/core-mobile/app/new/routes/onboarding/keystone/keystoneTroubleshooting.tsx @@ -0,0 +1,16 @@ +import React, { useCallback } from 'react' +import { useRouter } from 'expo-router' +import { KeystoneTroubleshooting as Component } from 'features/onboarding/components/KeystoneTroubleshooting' + +export default function KeystoneTroubleshooting(): JSX.Element { + const { replace } = useRouter() + + const retry = useCallback(() => { + replace({ + // @ts-ignore TODO: make routes typesafe + pathname: '/onboarding/keystone/recoveryUsingKeystone' + }) + }, [replace]) + + return +} diff --git a/packages/core-mobile/app/new/routes/onboarding/keystone/recoveryUsingKeystone.tsx b/packages/core-mobile/app/new/routes/onboarding/keystone/recoveryUsingKeystone.tsx new file mode 100644 index 0000000000..ecc223d7b3 --- /dev/null +++ b/packages/core-mobile/app/new/routes/onboarding/keystone/recoveryUsingKeystone.tsx @@ -0,0 +1,53 @@ +import React from 'react' +import { useRouter } from 'expo-router' +import KeytoneSDK, { UR } from '@keystonehq/keystone-sdk' +import { RecoveryUsingKeystone as Component } from 'features/onboarding/components/RecoveryUsingKeystone' +import Logger from 'utils/Logger' +import { fromPublicKey } from 'bip32' +import KeystoneService from 'hardware/services/KeystoneService' + +export default function RecoveryUsingKeystone(): JSX.Element { + const { navigate, replace } = useRouter() + + function handleNext(ur: UR): void { + try { + const sdk = new KeytoneSDK() + const accounts = sdk.parseMultiAccounts(ur) + const mfp = accounts.masterFingerprint + const ethAccount = accounts.keys.find(key => key.chain === 'ETH') + const avaxAccount = accounts.keys.find(key => key.chain === 'AVAX') + if (!ethAccount || !avaxAccount) { + throw new Error('No ETH or AVAX account found') + } + + KeystoneService.init({ + evm: fromPublicKey( + Buffer.from(ethAccount.publicKey, 'hex'), + Buffer.from(ethAccount.chainCode, 'hex') + ).toBase58(), + xp: fromPublicKey( + Buffer.from(avaxAccount.publicKey, 'hex'), + Buffer.from(avaxAccount.chainCode, 'hex') + ).toBase58(), + mfp + }) + + navigate({ + // @ts-ignore TODO: make routes typesafe + pathname: '/onboarding/keystone/createPin' + }) + } catch (error: any) { + Logger.error(error.message) + throw new Error('Failed to parse UR') + } + } + + function handleError(): void { + replace({ + // @ts-ignore TODO: make routes typesafe + pathname: '/onboarding/keystone/keystoneTroubleshooting' + }) + } + + return +} diff --git a/packages/core-mobile/app/new/routes/onboarding/keystone/selectAvatar.tsx b/packages/core-mobile/app/new/routes/onboarding/keystone/selectAvatar.tsx new file mode 100644 index 0000000000..47015545c2 --- /dev/null +++ b/packages/core-mobile/app/new/routes/onboarding/keystone/selectAvatar.tsx @@ -0,0 +1,40 @@ +import { SelectAvatar as Component } from 'common/components/SelectAvatar' +import { useAvatar } from 'common/hooks/useAvatar' +import { useRouter } from 'expo-router' +import { useRandomAvatar } from 'features/onboarding/hooks/useRandomAvatar' +import { useRandomizedAvatars } from 'features/onboarding/hooks/useRandomizedAvatars' +import React, { useState } from 'react' + +export default function SelectAvatar(): JSX.Element { + const { navigate } = useRouter() + const { saveLocalAvatar } = useAvatar() + + const randomizedAvatars = useRandomizedAvatars() + const randomAvatar = useRandomAvatar(randomizedAvatars) + + const [selectedAvatar, setSelectedAvatar] = useState(randomAvatar) + + const onSubmit = (): void => { + if (selectedAvatar) { + saveLocalAvatar(selectedAvatar.id) + } + + navigate({ + // @ts-ignore TODO: make routes typesafe + pathname: '/onboarding/keystone/confirmation', + params: { selectedAvatarId: selectedAvatar?.id } + }) + } + + return ( + + ) +} diff --git a/packages/core-mobile/app/new/routes/onboarding/keystone/setWalletName.tsx b/packages/core-mobile/app/new/routes/onboarding/keystone/setWalletName.tsx new file mode 100644 index 0000000000..9e68e06ac0 --- /dev/null +++ b/packages/core-mobile/app/new/routes/onboarding/keystone/setWalletName.tsx @@ -0,0 +1,25 @@ +import React, { useState } from 'react' +import AnalyticsService from 'services/analytics/AnalyticsService' +import { useDispatch } from 'react-redux' +import { useRouter } from 'expo-router' +import { SetWalletName as Component } from 'features/onboarding/components/SetWalletName' +import { setWalletName } from 'store/wallet/slice' +import { useActiveWallet } from 'common/hooks/useActiveWallet' + +export default function SetWalletName(): JSX.Element { + const [name, setName] = useState('Wallet 1') + const dispatch = useDispatch() + const { navigate } = useRouter() + const activeWallet = useActiveWallet() + + const handleNext = (): void => { + AnalyticsService.capture('Onboard:WalletNameSet') + dispatch(setWalletName({ walletId: activeWallet.id, name })) + navigate({ + // @ts-ignore TODO: make routes typesafe + pathname: '/onboarding/keystone/selectAvatar' + }) + } + + return +} diff --git a/packages/core-mobile/app/new/routes/onboarding/keystone/termsAndConditions.tsx b/packages/core-mobile/app/new/routes/onboarding/keystone/termsAndConditions.tsx new file mode 100644 index 0000000000..490bdbefad --- /dev/null +++ b/packages/core-mobile/app/new/routes/onboarding/keystone/termsAndConditions.tsx @@ -0,0 +1,14 @@ +import React from 'react' +import { TermsAndConditions as Component } from 'features/onboarding/components/TermsAndConditions' +import { useRouter } from 'expo-router' + +export default function TermsAndConditions(): JSX.Element { + const { navigate } = useRouter() + + const handleAgreeAndContinue = (): void => { + // @ts-ignore TODO: make routes typesafe + navigate('/onboarding/keystone/analyticsConsent') + } + + return +} diff --git a/packages/core-mobile/app/security/SecureStorageService.ts b/packages/core-mobile/app/security/SecureStorageService.ts index 704ae78690..6c7f32de25 100644 --- a/packages/core-mobile/app/security/SecureStorageService.ts +++ b/packages/core-mobile/app/security/SecureStorageService.ts @@ -9,7 +9,8 @@ export enum KeySlot { SignerSessionData = 'SignerSessionData', SeedlessPubKeys = 'SeedlessPubKeysV2', OidcProvider = 'OidcProvider', - OidcUserId = 'OidcUserId' + OidcUserId = 'OidcUserId', + KeystoneData = 'KeystoneData' } /** diff --git a/packages/core-mobile/app/services/wallet/WalletFactory.ts b/packages/core-mobile/app/services/wallet/WalletFactory.ts index 1d68b1e8aa..0e0cc1bfa2 100644 --- a/packages/core-mobile/app/services/wallet/WalletFactory.ts +++ b/packages/core-mobile/app/services/wallet/WalletFactory.ts @@ -3,6 +3,8 @@ import SeedlessService from 'seedless/services/SeedlessService' import BiometricsSDK from 'utils/BiometricsSDK' import { PrivateKeyWallet } from 'services/wallet/PrivateKeyWallet' import { SeedlessPubKeysStorage } from 'seedless/services/storage/SeedlessPubKeysStorage' +import { KeystoneDataStorage } from 'hardware/storage/KeystoneDataStorage' +import KeystoneWallet from 'hardware/wallet/KeystoneWallet' import { Wallet, WalletType } from './types' import { MnemonicWallet } from './MnemonicWallet' @@ -31,6 +33,11 @@ class WalletFactory { } return new MnemonicWallet(walletSecret.value) } + case WalletType.KEYSTONE: { + const keystoneData = await KeystoneDataStorage.retrieve() + + return new KeystoneWallet(keystoneData) + } case WalletType.PRIVATE_KEY: { const walletSecret = await BiometricsSDK.loadWalletSecret(walletId) if (!walletSecret.success) { diff --git a/packages/core-mobile/app/services/wallet/WalletService.tsx b/packages/core-mobile/app/services/wallet/WalletService.tsx index d7d90b115f..f61e1ce847 100644 --- a/packages/core-mobile/app/services/wallet/WalletService.tsx +++ b/packages/core-mobile/app/services/wallet/WalletService.tsx @@ -312,7 +312,7 @@ class WalletService { return [] } - if (walletType === WalletType.MNEMONIC) { + if ([WalletType.MNEMONIC, WalletType.KEYSTONE].includes(walletType)) { const provXP = await NetworkService.getAvalancheProviderXP(isTestnet) const publicKeys = await this.getPublicKey(walletId, walletType, account) const xpubXP = publicKeys.xp diff --git a/packages/core-mobile/app/services/wallet/types.ts b/packages/core-mobile/app/services/wallet/types.ts index ad96bafe3d..54c77f3c40 100644 --- a/packages/core-mobile/app/services/wallet/types.ts +++ b/packages/core-mobile/app/services/wallet/types.ts @@ -115,7 +115,8 @@ export enum WalletType { UNSET = 'UNSET', SEEDLESS = 'SEEDLESS', MNEMONIC = 'MNEMONIC', - PRIVATE_KEY = 'PRIVATE_KEY' + PRIVATE_KEY = 'PRIVATE_KEY', + KEYSTONE = 'KEYSTONE' } /** diff --git a/packages/core-mobile/app/services/walletconnectv2/walletConnectCache/types.ts b/packages/core-mobile/app/services/walletconnectv2/walletConnectCache/types.ts index 130b78d4fe..85df48eb35 100644 --- a/packages/core-mobile/app/services/walletconnectv2/walletConnectCache/types.ts +++ b/packages/core-mobile/app/services/walletconnectv2/walletConnectCache/types.ts @@ -12,6 +12,7 @@ import { Contact } from 'store/addressBook/types' import { WalletAddEthereumChainRpcRequest } from 'store/rpc/handlers/chain/wallet_addEthereumChain/wallet_addEthereumChain' import { Account } from 'store/account' import { WalletType } from 'services/wallet/types' +import { UR } from '@ngraveio/bc-ur' export type SessionProposalParams = { request: WCSessionProposal @@ -43,6 +44,18 @@ export type ApprovalParams = { onReject: (message?: string) => void } +export type KeystoneSignerParams = { + request: UR + responseURTypes: string[] + onApprove: (cbor: Buffer) => Promise + onReject: (message?: string) => void +} + +export type KeystoneTroubleshootingParams = { + errorCode: number + retry: () => void +} + export type SetDeveloperModeParams = { request: AvalancheSetDeveloperModeRpcRequest data: AvalancheSetDeveloperModeApproveData diff --git a/packages/core-mobile/app/services/walletconnectv2/walletConnectCache/walletConnectCache.ts b/packages/core-mobile/app/services/walletconnectv2/walletConnectCache/walletConnectCache.ts index e7874773e9..4c79408b65 100644 --- a/packages/core-mobile/app/services/walletconnectv2/walletConnectCache/walletConnectCache.ts +++ b/packages/core-mobile/app/services/walletconnectv2/walletConnectCache/walletConnectCache.ts @@ -3,7 +3,9 @@ import { SetDeveloperModeParams, SessionProposalParams, EditContactParams, - AddEthereumChainParams + AddEthereumChainParams, + KeystoneSignerParams, + KeystoneTroubleshootingParams } from './types' // a simple in-memory cache (no reactivity or persistence support) @@ -15,7 +17,11 @@ export const walletConnectCache = { createCache('set developer mode'), editContactParams: createCache('edit contact'), addEthereumChainParams: - createCache('add ethereum chain') + createCache('add ethereum chain'), + keystoneSignerParams: createCache('keystone signer'), + keystoneTroubleshootingParams: createCache( + 'keystone troubleshooting' + ) } function createCache(key: string): { diff --git a/packages/core-mobile/app/store/account/listeners.ts b/packages/core-mobile/app/store/account/listeners.ts index 710964a578..5e404c2df5 100644 --- a/packages/core-mobile/app/store/account/listeners.ts +++ b/packages/core-mobile/app/store/account/listeners.ts @@ -20,6 +20,7 @@ import WalletFactory from 'services/wallet/WalletFactory' import SeedlessWallet from 'seedless/services/wallet/SeedlessWallet' import { transactionSnackbar } from 'common/utils/toast' import Logger from 'utils/Logger' +import KeystoneService from 'hardware/services/KeystoneService' import { selectAccounts, setAccounts, @@ -59,6 +60,17 @@ const initAccounts = async ( } } + if (activeWallet.type === WalletType.KEYSTONE) { + try { + await KeystoneService.refreshPublicKeys() + } catch (error) { + Logger.error( + 'Failed to fetch and save public keys for Keystone wallet', + error + ) + } + } + const acc = await accountService.createNextAccount({ index: 0, walletType: activeWallet.type, @@ -95,7 +107,8 @@ const initAccounts = async ( } } else if ( activeWallet.type === WalletType.MNEMONIC || - activeWallet.type === WalletType.PRIVATE_KEY + activeWallet.type === WalletType.PRIVATE_KEY || + activeWallet.type === WalletType.KEYSTONE ) { accounts[acc.id] = acc diff --git a/packages/core-mobile/e2e/locators/onboarding.loc.ts b/packages/core-mobile/e2e/locators/onboarding.loc.ts index 0ff0c006dc..4483e38d30 100644 --- a/packages/core-mobile/e2e/locators/onboarding.loc.ts +++ b/packages/core-mobile/e2e/locators/onboarding.loc.ts @@ -14,6 +14,7 @@ export default { "Add a display avatar for your wallet. You can change it at any time in the app's settings", selectedAvatar: 'selected_avatar', chooseWalletTitle: 'How would you like to access your existing wallet?', + addWalletUsingKeystone: 'Add using Keystone', typeRecoverPhase: 'Type in a recovery phrase', createNewWalletBtn: 'Create a new wallet', noThanksBtn: 'No thanks', diff --git a/packages/core-mobile/package.json b/packages/core-mobile/package.json index 9023ab936f..814efc2977 100644 --- a/packages/core-mobile/package.json +++ b/packages/core-mobile/package.json @@ -49,12 +49,16 @@ "@date-fns/utc": "2.1.0", "@ethereumjs/common": "4.4.0", "@ethereumjs/tx": "5.4.0", + "@ethereumjs/util": "9.1.0", "@gorhom/bottom-sheet": "4.6.4", "@hookform/resolvers": "3.9.0", "@invertase/react-native-apple-authentication": "2.4.0", + "@keystonehq/animated-qr": "0.10.0", + "@keystonehq/keystone-sdk": "0.11.3", "@lavamoat/preinstall-always-fail": "2.1.0", "@metamask/eth-sig-util": "7.0.3", "@metamask/rpc-errors": "6.3.0", + "@ngraveio/bc-ur": "1.1.13", "@noble/secp256k1": "2.1.0", "@notifee/react-native": "9.1.8", "@openzeppelin/contracts": "5.0.2", @@ -149,6 +153,7 @@ "react-native-big-list": "1.6.1", "react-native-bootsplash": "6.1.4", "react-native-bottom-tabs": "0.9.0", + "react-native-camera": "4.2.1", "react-native-chart-kit": "6.12.0", "react-native-circular-progress": "1.4.0", "react-native-collapsible": "1.6.2", @@ -176,6 +181,8 @@ "react-native-permissions": "4.1.5", "react-native-popable": "0.4.3", "react-native-popover-view": "6.1.0", + "react-native-progress": "5.0.1", + "react-native-qrcode-scanner": "1.5.5", "react-native-qrcode-svg": "6.3.2", "react-native-quick-base64": "2.1.2", "react-native-quick-crypto": "0.7.11", diff --git a/yarn.lock b/yarn.lock index 3846fdaed2..5eda410a6e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -234,13 +234,17 @@ __metadata: "@dlenroc/testrail": 1.9.1 "@ethereumjs/common": 4.4.0 "@ethereumjs/tx": 5.4.0 + "@ethereumjs/util": 9.1.0 "@gorhom/bottom-sheet": 4.6.4 "@hookform/resolvers": 3.9.0 "@invertase/react-native-apple-authentication": 2.4.0 + "@keystonehq/animated-qr": 0.10.0 + "@keystonehq/keystone-sdk": 0.11.3 "@lavamoat/allow-scripts": 3.2.1 "@lavamoat/preinstall-always-fail": 2.1.0 "@metamask/eth-sig-util": 7.0.3 "@metamask/rpc-errors": 6.3.0 + "@ngraveio/bc-ur": 1.1.13 "@noble/secp256k1": 2.1.0 "@notifee/react-native": 9.1.8 "@openzeppelin/contracts": 5.0.2 @@ -377,6 +381,7 @@ __metadata: react-native-big-list: 1.6.1 react-native-bootsplash: 6.1.4 react-native-bottom-tabs: 0.9.0 + react-native-camera: 4.2.1 react-native-chart-kit: 6.12.0 react-native-circular-progress: 1.4.0 react-native-collapsible: 1.6.2 @@ -404,6 +409,8 @@ __metadata: react-native-permissions: 4.1.5 react-native-popable: 0.4.3 react-native-popover-view: 6.1.0 + react-native-progress: 5.0.1 + react-native-qrcode-scanner: 1.5.5 react-native-qrcode-svg: 6.3.2 react-native-quick-base64: 2.1.2 react-native-quick-crypto: 0.7.11 @@ -4189,6 +4196,13 @@ __metadata: languageName: node linkType: hard +"@bufbuild/protobuf@npm:^1.2.0": + version: 1.10.1 + resolution: "@bufbuild/protobuf@npm:1.10.1" + checksum: 403838ad278d504e33e72ec0f64ce1bac9f5025ee6396253382e821a1fe0c371a58ffe45a0e8f23306205b6890c5f83e85828168a35dae118915cd4c3d091177 + languageName: node + linkType: hard + "@coinbase/cbpay-js@npm:2.2.1": version: 2.2.1 resolution: "@coinbase/cbpay-js@npm:2.2.1" @@ -4624,6 +4638,16 @@ __metadata: languageName: node linkType: hard +"@ethereumjs/util@npm:9.1.0, @ethereumjs/util@npm:^9.0.3, @ethereumjs/util@npm:^9.1.0": + version: 9.1.0 + resolution: "@ethereumjs/util@npm:9.1.0" + dependencies: + "@ethereumjs/rlp": ^5.0.2 + ethereum-cryptography: ^2.2.1 + checksum: 594e009c3001ca1ca658b4ded01b38e72f5dd5dd76389efd90cb020de099176a3327685557df268161ac3144333cfe8abaae68cda8ae035d9cc82409d386d79a + languageName: node + linkType: hard + "@ethereumjs/util@npm:^8.1.0": version: 8.1.0 resolution: "@ethereumjs/util@npm:8.1.0" @@ -4635,16 +4659,6 @@ __metadata: languageName: node linkType: hard -"@ethereumjs/util@npm:^9.1.0": - version: 9.1.0 - resolution: "@ethereumjs/util@npm:9.1.0" - dependencies: - "@ethereumjs/rlp": ^5.0.2 - ethereum-cryptography: ^2.2.1 - checksum: 594e009c3001ca1ca658b4ded01b38e72f5dd5dd76389efd90cb020de099176a3327685557df268161ac3144333cfe8abaae68cda8ae035d9cc82409d386d79a - languageName: node - linkType: hard - "@ethersproject/abi@npm:^5.5.0": version: 5.7.0 resolution: "@ethersproject/abi@npm:5.7.0" @@ -7060,6 +7074,250 @@ __metadata: languageName: node linkType: hard +"@keystonehq/alias-sampling@npm:^0.1.1": + version: 0.1.2 + resolution: "@keystonehq/alias-sampling@npm:0.1.2" + checksum: 4dfdfb91e070b1d9f28058c92b5b8fad81696ac63bd432cd6bd359f2ab92eb50df75e8c5da1f75a351756387e9902f043b3ecc2cbf662c9c9456ecacc848abfd + languageName: node + linkType: hard + +"@keystonehq/animated-qr-base@npm:^0.0.1": + version: 0.0.1 + resolution: "@keystonehq/animated-qr-base@npm:0.0.1" + dependencies: + "@ngraveio/bc-ur": ^1.1.13 + checksum: 5058f7e21b12f3c429e5c0c37c9c9adf718d7c397a13bd75c7bc4f81820754d6a01ca12a8f955472189b3d9fc452f117846db45dcc045108b9211abcfb2cc89c + languageName: node + linkType: hard + +"@keystonehq/animated-qr@npm:0.10.0": + version: 0.10.0 + resolution: "@keystonehq/animated-qr@npm:0.10.0" + dependencies: + "@keystonehq/animated-qr-base": ^0.0.1 + "@ngraveio/bc-ur": ^1.1.6 + "@zxing/browser": ^0.1.1 + "@zxing/library": ^0.19.1 + qrcode.react: ^3.1.0 + peerDependencies: + react: ">= 16.8" + react-dom: ">= 16.8" + checksum: f0657d3c600ea4bc3d0c76dc78c1e6242bf43f5a2ecb34bc3e1de3428dd00f8f8a2c0728a63fc2606294c51a75af50d99d8f0fe4443761cd14fd74db8bf80e76 + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-aptos@npm:^0.6.3": + version: 0.6.3 + resolution: "@keystonehq/bc-ur-registry-aptos@npm:0.6.3" + dependencies: + "@keystonehq/bc-ur-registry": ^0.6.4 + bs58check: ^2.1.2 + uuid: ^8.3.2 + checksum: 5be87f8aaefd038121c049fd725b3fce7867122642042299b690bce7c0b40ea98cc2d5f17c187d511e03d24d3e617ef0df70fcb1d40a5b6877710c03e3630801 + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-arweave@npm:^0.5.3": + version: 0.5.3 + resolution: "@keystonehq/bc-ur-registry-arweave@npm:0.5.3" + dependencies: + "@keystonehq/bc-ur-registry": ^0.6.4 + uuid: ^8.3.2 + checksum: 0a967f318343022dc1201561bb3cd7f5a889135bf65bb48e959153802207b0693dd9a1f6cc653eb40e0dc8e3675471df4584dc287ff7a2b7e6d6d128e38a52d4 + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-avalanche@npm:^0.0.4": + version: 0.0.4 + resolution: "@keystonehq/bc-ur-registry-avalanche@npm:0.0.4" + dependencies: + "@keystonehq/bc-ur-registry": ^0.6.4 + buffer: ^6.0.3 + uuid: ^8.3.2 + checksum: c8bff304d1bf2430572d07408e8fdbcacf5f769fc885fc094c248c7c4a7a771cde427f385dd4bb1a38d864361829f6ba2f4f0104e46ce37c251720dfd0ec2336 + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-btc@npm:^0.1.1": + version: 0.1.1 + resolution: "@keystonehq/bc-ur-registry-btc@npm:0.1.1" + dependencies: + "@keystonehq/bc-ur-registry": ^0.6.4 + uuid: ^8.3.2 + checksum: d0d7ec983db55374715c04226a7fd70c82b5758c64eae8e70fb3285f8fa3e6d3f124cadb409c3371f7ae18862494ed0fa60cea4c55099eb6ba9cebda9bf2c89d + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-cardano@npm:^0.5.0": + version: 0.5.0 + resolution: "@keystonehq/bc-ur-registry-cardano@npm:0.5.0" + dependencies: + "@keystonehq/bc-ur-registry": ^0.6.4 + uuid: ^8.3.2 + checksum: b8c72bd44a086b41763f8fa3ddbe3cc7227b5e1c42fe22f76ee35abec6acc1df106d74453c928ffcc6afed75abf045cc74db82c66803d141d98be5e52d7532bf + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-cosmos@npm:^0.5.3": + version: 0.5.3 + resolution: "@keystonehq/bc-ur-registry-cosmos@npm:0.5.3" + dependencies: + "@keystonehq/bc-ur-registry": ^0.6.4 + bs58check: ^2.1.2 + uuid: ^8.3.2 + checksum: 6ca85a739cd2c15f2534735c996fbd888a42b81691cbf34c5421bde4a1bad93cd99d1ea09b6a691305d4656aa2904f592e248498e631470a17d00ed800d6a3e0 + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-eth@npm:^0.22.0": + version: 0.22.1 + resolution: "@keystonehq/bc-ur-registry-eth@npm:0.22.1" + dependencies: + "@ethereumjs/util": ^9.0.3 + "@keystonehq/bc-ur-registry": ^0.7.0 + hdkey: ^2.0.1 + uuid: ^8.3.2 + checksum: d8effcca1443464c8cd7e2247dd7a49cc8221cb9f34377400a0bba4363a02cd818ed8125f9106a95146174d170959e917ddbe1eabb1376f07f90d71148b1aea5 + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-evm@npm:^0.5.3": + version: 0.5.3 + resolution: "@keystonehq/bc-ur-registry-evm@npm:0.5.3" + dependencies: + "@keystonehq/bc-ur-registry": ^0.6.4 + bs58check: ^2.1.2 + uuid: ^9.0.0 + checksum: a98251b7164397edc7dcda154ebfe2adf239954bf7acb42af42162ffefec648df2384908766780ab729b8264bffc99ed4dd8de4bded74e229a281620671a326c + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-iota@npm:^0.1.4": + version: 0.1.4 + resolution: "@keystonehq/bc-ur-registry-iota@npm:0.1.4" + dependencies: + "@keystonehq/bc-ur-registry": ^0.6.4 + uuid: ^9.0.0 + checksum: c3a3ee3573e9acb03acf8c7679af8c61c5345469ef0e2dc9f3c18c9ff921ad9e681347401af0894939dd0625b7948346dee67df8deb2e490dc3743319be174df + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-keystone@npm:^0.4.3": + version: 0.4.3 + resolution: "@keystonehq/bc-ur-registry-keystone@npm:0.4.3" + dependencies: + "@keystonehq/bc-ur-registry": ^0.6.4 + checksum: 04848bad6fe149bebbb18113e13249acad15b1eea96cee667966f6f8ba568595d40927e46ee1202c5ea02fa475d1aff25b1c797f1ce88152804795ccb3487718 + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-near@npm:^0.9.3": + version: 0.9.3 + resolution: "@keystonehq/bc-ur-registry-near@npm:0.9.3" + dependencies: + "@keystonehq/bc-ur-registry": ^0.6.4 + bs58check: ^2.1.2 + uuid: ^8.3.2 + checksum: 494bc0842b63c701797b6cf8d06e7e980584b8efe42f9b1f3ef2d064157c4cc1b01a3c27ab74089bbfd4111c1879ede39c697ee7a11a5556aed858220878ad3d + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-sol@npm:^0.9.3": + version: 0.9.5 + resolution: "@keystonehq/bc-ur-registry-sol@npm:0.9.5" + dependencies: + "@keystonehq/bc-ur-registry": ^0.7.0 + bs58check: ^2.1.2 + uuid: ^8.3.2 + checksum: f8002e74b4fcad5fe3d67b3d2d462d8a6e6a80ed6dc2cb14815da827ccde18772f0b6595da8e79311a3b81bf273891ab524c981d7c705b24ec8dc977508259a5 + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-stellar@npm:^0.0.4": + version: 0.0.4 + resolution: "@keystonehq/bc-ur-registry-stellar@npm:0.0.4" + dependencies: + "@keystonehq/bc-ur-registry": ^0.6.4 + bs58check: ^2.1.2 + uuid: ^8.3.2 + checksum: 25366676d1987f05398cc7094d59020596db76c621facc1e6dc40119a3e35f231befea9911194e7c869d9177ff9704aa74033963cf90cef824c113dbffc335e5 + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-sui@npm:0.4.0-alpha.0": + version: 0.4.0-alpha.0 + resolution: "@keystonehq/bc-ur-registry-sui@npm:0.4.0-alpha.0" + dependencies: + "@keystonehq/bc-ur-registry": ^0.6.4 + uuid: ^9.0.0 + checksum: 193385f60751fbc261299233f37e01ecc130d67c63f805b811043e03409f06e6ecc03c6d8effab17728a4174cc3eb210c3fbeeeacac058bef2bc301e47be2a1c + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-ton@npm:^0.1.2": + version: 0.1.2 + resolution: "@keystonehq/bc-ur-registry-ton@npm:0.1.2" + dependencies: + "@keystonehq/bc-ur-registry": ^0.6.4 + uuid: ^9.0.0 + checksum: 28458a641d02366187e9ec8f2498fc0a7ba31125b072e50ec7bfc1328dcbcbd0fc005fa29411400b5ea27ab5ba1baf53e3259516aa7346c5a2556e7deb3dc431 + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry@npm:^0.6.4": + version: 0.6.4 + resolution: "@keystonehq/bc-ur-registry@npm:0.6.4" + dependencies: + "@ngraveio/bc-ur": ^1.1.5 + bs58check: ^2.1.2 + tslib: ^2.3.0 + checksum: 8b73edd304fc2c6a7faa3fae320348e9fc58493c2d75276b792ef37560534e18117c114bfb9edddd90639e81710dd660fb1a405d7c5de05e17d44613c691fdb3 + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry@npm:^0.7.0": + version: 0.7.0 + resolution: "@keystonehq/bc-ur-registry@npm:0.7.0" + dependencies: + "@ngraveio/bc-ur": ^1.1.5 + bs58check: ^2.1.2 + tslib: ^2.3.0 + checksum: d6017e8fda67fc01e28aa1c047b20cce8f07b026f110a5771920879fbd658b845f529b054d1dce2fbabadcfd8da47a2160ab50c73f0bd56678aab4d83899ffcc + languageName: node + linkType: hard + +"@keystonehq/keystone-sdk@npm:0.11.3": + version: 0.11.3 + resolution: "@keystonehq/keystone-sdk@npm:0.11.3" + dependencies: + "@bufbuild/protobuf": ^1.2.0 + "@keystonehq/bc-ur-registry": ^0.7.0 + "@keystonehq/bc-ur-registry-aptos": ^0.6.3 + "@keystonehq/bc-ur-registry-arweave": ^0.5.3 + "@keystonehq/bc-ur-registry-avalanche": ^0.0.4 + "@keystonehq/bc-ur-registry-btc": ^0.1.1 + "@keystonehq/bc-ur-registry-cardano": ^0.5.0 + "@keystonehq/bc-ur-registry-cosmos": ^0.5.3 + "@keystonehq/bc-ur-registry-eth": ^0.22.0 + "@keystonehq/bc-ur-registry-evm": ^0.5.3 + "@keystonehq/bc-ur-registry-iota": ^0.1.4 + "@keystonehq/bc-ur-registry-keystone": ^0.4.3 + "@keystonehq/bc-ur-registry-near": ^0.9.3 + "@keystonehq/bc-ur-registry-sol": ^0.9.3 + "@keystonehq/bc-ur-registry-stellar": ^0.0.4 + "@keystonehq/bc-ur-registry-sui": 0.4.0-alpha.0 + "@keystonehq/bc-ur-registry-ton": ^0.1.2 + "@ngraveio/bc-ur": ^1.1.6 + "@noble/hashes": ^1.5.0 + bs58check: ^3.0.1 + buffer: ^6.0.3 + pako: ^2.1.0 + ripple-binary-codec: ^1.4.3 + uuid: ^9.0.0 + checksum: c4acc2e14853ba70d8ab53a79ac4426bccb6c1a6b391f428cc2942ab8c0fbbfb34dde38ebe691ccf0c76a6b7ac5cd3fac4f170a59371813e94bcea749f466287 + languageName: node + linkType: hard + "@lavamoat/aa@npm:^4.3.0": version: 4.3.0 resolution: "@lavamoat/aa@npm:4.3.0" @@ -7729,6 +7987,21 @@ __metadata: languageName: node linkType: hard +"@ngraveio/bc-ur@npm:1.1.13, @ngraveio/bc-ur@npm:^1.1.13, @ngraveio/bc-ur@npm:^1.1.5, @ngraveio/bc-ur@npm:^1.1.6": + version: 1.1.13 + resolution: "@ngraveio/bc-ur@npm:1.1.13" + dependencies: + "@keystonehq/alias-sampling": ^0.1.1 + assert: ^2.0.0 + bignumber.js: ^9.0.1 + cbor-sync: ^1.0.4 + crc: ^3.8.0 + jsbi: ^3.1.5 + sha.js: ^2.4.11 + checksum: 3f8e565c6a6dd7af7489a884f7d4d85d274ce7ce41f9fdb7e362b8a75ccbb2c934b369fd4ea58b2214d6039462ee0e933de61f372c04c551a47a75e1cad14cfd + languageName: node + linkType: hard + "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1": version: 5.1.1-v1 resolution: "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1" @@ -9349,6 +9622,17 @@ __metadata: languageName: node linkType: hard +"@react-native-async-storage/async-storage@npm:^1.13.4": + version: 1.24.0 + resolution: "@react-native-async-storage/async-storage@npm:1.24.0" + dependencies: + merge-options: ^3.0.4 + peerDependencies: + react-native: ^0.0.0-0 || >=0.60 <1.0 + checksum: 7e56a2e97f48332f57c56ebf473b763c7ca2b1ef82f4b5f8e1c73350231ec91b8eafc4e4d1f972c4c1005da0d304816fa725dc6f07a8a7543e90f8bd16c22ab4 + languageName: node + linkType: hard + "@react-native-clipboard/clipboard@npm:1.15.0": version: 1.15.0 resolution: "@react-native-clipboard/clipboard@npm:1.15.0" @@ -14225,7 +14509,34 @@ __metadata: languageName: node linkType: hard -"@zxing/text-encoding@npm:0.9.0": +"@zxing/browser@npm:^0.1.1": + version: 0.1.5 + resolution: "@zxing/browser@npm:0.1.5" + dependencies: + "@zxing/text-encoding": ^0.9.0 + peerDependencies: + "@zxing/library": ^0.21.0 + dependenciesMeta: + "@zxing/text-encoding": + optional: true + checksum: 27bfddd707e8e643624b432666a956f1e7e283e20963243f7050c781fd80daad9f54408acdf46d809c64586983f7b02a4981c1d3b0251519e0566c165f6b3924 + languageName: node + linkType: hard + +"@zxing/library@npm:^0.19.1": + version: 0.19.3 + resolution: "@zxing/library@npm:0.19.3" + dependencies: + "@zxing/text-encoding": ~0.9.0 + ts-custom-error: ^3.2.1 + dependenciesMeta: + "@zxing/text-encoding": + optional: true + checksum: 2a3adaccbde0e075ee4c3c73ab7fa9306be979dafeff6d373204470ea3cddab88608c6eca5e891c7d5e693c5df0f0664e14ea0a74d38e0658fc7464f5c986474 + languageName: node + linkType: hard + +"@zxing/text-encoding@npm:0.9.0, @zxing/text-encoding@npm:^0.9.0, @zxing/text-encoding@npm:~0.9.0": version: 0.9.0 resolution: "@zxing/text-encoding@npm:0.9.0" checksum: c23b12aee7639382e4949961304a1294776afaffa40f579e09ffecd0e5e68cf26ef3edd75009de46da8a536e571448755ca68b3e2ea707d53793c0edb2e2c34a @@ -14862,7 +15173,7 @@ __metadata: languageName: node linkType: hard -"assert@npm:2.1.0, assert@npm:^2.1.0": +"assert@npm:2.1.0, assert@npm:^2.0.0, assert@npm:^2.1.0": version: 2.1.0 resolution: "assert@npm:2.1.0" dependencies: @@ -15311,6 +15622,15 @@ __metadata: languageName: node linkType: hard +"base-x@npm:^3.0.9": + version: 3.0.11 + resolution: "base-x@npm:3.0.11" + dependencies: + safe-buffer: ^5.0.1 + checksum: c2e3c443fd07cb9b9d3e179a9e9c581daa31881005841fe8d6a834e534505890fedf03465ccf14512da60e3f7be00fe66167806b159ba076d2c03952ae7460c4 + languageName: node + linkType: hard + "base-x@npm:^4.0.0": version: 4.0.0 resolution: "base-x@npm:4.0.0" @@ -15355,7 +15675,7 @@ __metadata: languageName: node linkType: hard -"big-integer@npm:1.6.x, big-integer@npm:^1.6.52": +"big-integer@npm:1.6.x, big-integer@npm:^1.6.48, big-integer@npm:^1.6.52": version: 1.6.52 resolution: "big-integer@npm:1.6.52" checksum: 6e86885787a20fed96521958ae9086960e4e4b5e74d04f3ef7513d4d0ad631a9f3bde2730fc8aaa4b00419fc865f6ec573e5320234531ef37505da7da192c40b @@ -15376,6 +15696,13 @@ __metadata: languageName: node linkType: hard +"bignumber.js@npm:^9.0.1": + version: 9.3.0 + resolution: "bignumber.js@npm:9.3.0" + checksum: 580d783d60246e758e527fa879ae0d282d8f250f555dd0fcee1227d680186ceba49ed7964c6d14e2e8d8eac7a2f4dd6ef1b7925dc52f5fc28a5a87639dd2dbd1 + languageName: node + linkType: hard + "bignumber.js@npm:^9.1.1, bignumber.js@npm:^9.1.2": version: 9.1.2 resolution: "bignumber.js@npm:9.1.2" @@ -15873,7 +16200,7 @@ __metadata: languageName: node linkType: hard -"buffer@npm:^5.4.3, buffer@npm:^5.5.0": +"buffer@npm:^5.1.0, buffer@npm:^5.4.3, buffer@npm:^5.5.0": version: 5.7.1 resolution: "buffer@npm:5.7.1" dependencies: @@ -16161,6 +16488,13 @@ __metadata: languageName: node linkType: hard +"cbor-sync@npm:^1.0.4": + version: 1.0.4 + resolution: "cbor-sync@npm:1.0.4" + checksum: 147834c64b43511b2ea601f02bc2cc4190ec8d41a7b8dc3e9037c636b484ca2124bc7d49da7a0f775ea5153ff799d57e45992816851dbb1d61335f308a0d0120 + languageName: node + linkType: hard + "chalk@npm:^2.0.1, chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -16881,6 +17215,15 @@ __metadata: languageName: node linkType: hard +"crc@npm:^3.8.0": + version: 3.8.0 + resolution: "crc@npm:3.8.0" + dependencies: + buffer: ^5.1.0 + checksum: dabbc4eba223b206068b92ca82bb471d583eb6be2384a87f5c3712730cfd6ba4b13a45e8ba3ef62174d5a781a2c5ac5c20bf36cf37bba73926899bd0aa19186f + languageName: node + linkType: hard + "create-hash@npm:1.2.0, create-hash@npm:^1.1.0, create-hash@npm:^1.1.2, create-hash@npm:^1.2.0": version: 1.2.0 resolution: "create-hash@npm:1.2.0" @@ -17559,6 +17902,13 @@ __metadata: languageName: node linkType: hard +"decimal.js@npm:^10.2.0": + version: 10.5.0 + resolution: "decimal.js@npm:10.5.0" + checksum: 91c6b53b5dd2f39a05535349ced6840f591d1f914e3c025c6dcec6ffada6e3cfc8dc3f560d304b716be9a9aece3567a7f80f6aff8f38d11ab6f78541c3a91a01 + languageName: node + linkType: hard + "decode-uri-component@npm:^0.2.2": version: 0.2.2 resolution: "decode-uri-component@npm:0.2.2" @@ -21294,6 +21644,18 @@ __metadata: languageName: node linkType: hard +"hdkey@npm:^2.0.1": + version: 2.1.0 + resolution: "hdkey@npm:2.1.0" + dependencies: + bs58check: ^2.1.2 + ripemd160: ^2.0.2 + safe-buffer: ^5.1.1 + secp256k1: ^4.0.0 + checksum: 042f2d715dc4d106c868dc3791d584336845e4e53f3452e1df116d6af5d88d7084a0a73ddd8a07b4a7d9e6b29cd3b6b4174f03499f25d8ddd101642b34fabe5c + languageName: node + linkType: hard + "he@npm:1.2.0": version: 1.2.0 resolution: "he@npm:1.2.0" @@ -23180,6 +23542,13 @@ __metadata: languageName: node linkType: hard +"jsbi@npm:^3.1.5": + version: 3.2.5 + resolution: "jsbi@npm:3.2.5" + checksum: 642d1bb139ad1c1e96c4907eb159565e980a0d168487626b493d0d0b7b341da0e43001089d3b21703fe17b18a7a6c0f42c92026f71d54471ed0a0d1b3015ec0f + languageName: node + linkType: hard + "jsbn@npm:1.1.0": version: 1.1.0 resolution: "jsbn@npm:1.1.0" @@ -26192,6 +26561,13 @@ __metadata: languageName: node linkType: hard +"pako@npm:^2.1.0": + version: 2.1.0 + resolution: "pako@npm:2.1.0" + checksum: 71666548644c9a4d056bcaba849ca6fd7242c6cf1af0646d3346f3079a1c7f4a66ffec6f7369ee0dc88f61926c10d6ab05da3e1fca44b83551839e89edd75a3e + languageName: node + linkType: hard + "parent-module@npm:^1.0.0": version: 1.0.1 resolution: "parent-module@npm:1.0.1" @@ -26939,7 +27315,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:*, prop-types@npm:15.8.1, prop-types@npm:^15.5.10, prop-types@npm:^15.7.2, prop-types@npm:^15.8.0, prop-types@npm:^15.8.1": +"prop-types@npm:*, prop-types@npm:15.8.1, prop-types@npm:^15.5.10, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.0, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -27161,6 +27537,15 @@ __metadata: languageName: node linkType: hard +"qrcode.react@npm:^3.1.0": + version: 3.2.0 + resolution: "qrcode.react@npm:3.2.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 55d020ca482d57e8d73ee9e2e18f152184fd3d7d2d0742ae54ec58c5a3bab08b242a648585178d7fc91877fc75d6fbad7a35fb51bc4bddd4374e1de450ca78e7 + languageName: node + linkType: hard + "qrcode@npm:^1.5.1": version: 1.5.4 resolution: "qrcode@npm:1.5.4" @@ -27514,6 +27899,15 @@ __metadata: languageName: node linkType: hard +"react-native-camera@npm:4.2.1": + version: 4.2.1 + resolution: "react-native-camera@npm:4.2.1" + dependencies: + prop-types: ^15.6.2 + checksum: 0e84ce657774694d1cc49395c43a8f2caabc03df36aa77aacfb5c797ad8cfe0368f4807deccc54e82ff2b193e8c2d1ce7ad504eedf7a9fc4719b38e39958a804 + languageName: node + linkType: hard + "react-native-chart-kit@npm:6.12.0": version: 6.12.0 resolution: "react-native-chart-kit@npm:6.12.0" @@ -27922,6 +28316,16 @@ __metadata: languageName: node linkType: hard +"react-native-permissions@npm:^2.0.2": + version: 2.2.2 + resolution: "react-native-permissions@npm:2.2.2" + peerDependencies: + react: ">=16.8.6" + react-native: ">=0.60.0" + checksum: cfc2b9d9c1e70a965faea108f546b34909cff36bc453e854ea6f129d3fa41c67d0db2fedd13d6041417276f9fd30c03b1aa44e0e20ffb883be3135a28fc94993 + languageName: node + linkType: hard + "react-native-popable@npm:0.4.3": version: 0.4.3 resolution: "react-native-popable@npm:0.4.3" @@ -27942,6 +28346,30 @@ __metadata: languageName: node linkType: hard +"react-native-progress@npm:5.0.1": + version: 5.0.1 + resolution: "react-native-progress@npm:5.0.1" + dependencies: + prop-types: ^15.7.2 + peerDependencies: + react-native-svg: "*" + checksum: fc9b68f1ca381b011859f8900c89595d62461cfa5b4faf65527639e8d8247d494cc75d5eb86e6dd393bca8dec18996b451775670d7ef2ae70247fa4079c9a8cf + languageName: node + linkType: hard + +"react-native-qrcode-scanner@npm:1.5.5": + version: 1.5.5 + resolution: "react-native-qrcode-scanner@npm:1.5.5" + dependencies: + "@react-native-async-storage/async-storage": ^1.13.4 + prop-types: ^15.5.10 + react-native-permissions: ^2.0.2 + peerDependencies: + react-native-camera: ">=1.0.2" + checksum: 135a46a3ecc424b7b3be2f0637baba0e108fda10435299a15bad44dedff100fddaae8e31ddaf7dbd86296cc363e20195e7268bf58d8d7604e6de3243311cf8c3 + languageName: node + linkType: hard + "react-native-qrcode-svg@npm:6.3.2": version: 6.3.2 resolution: "react-native-qrcode-svg@npm:6.3.2" @@ -28230,7 +28658,7 @@ react-native-webview@ava-labs/react-native-webview: peerDependencies: react: "*" react-native: "*" - checksum: 77324747a8b5df0a5558bb99a9a0804a5575d328e84f480e462c56417af97213f38a9930e4582fb749bec374dc4d1a8910a45b006e77af9b14a8e64057b932bf + checksum: 6f005151d0b9f4210ad58a55706334c950077e45bb9358a6e2d992386d4079c6f1eac04911a925ffbb839cb7ab847a0cff1177af0fc61cf3172e0a0bb018ba37 languageName: node linkType: hard @@ -29203,7 +29631,7 @@ react-native-webview@ava-labs/react-native-webview: languageName: node linkType: hard -"ripemd160@npm:2, ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1": +"ripemd160@npm:2, ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1, ripemd160@npm:^2.0.2": version: 2.0.2 resolution: "ripemd160@npm:2.0.2" dependencies: @@ -29213,6 +29641,30 @@ react-native-webview@ava-labs/react-native-webview: languageName: node linkType: hard +"ripple-address-codec@npm:^4.3.1": + version: 4.3.1 + resolution: "ripple-address-codec@npm:4.3.1" + dependencies: + base-x: ^3.0.9 + create-hash: ^1.1.2 + checksum: 2961fa9ffd508137a8fbf52cc75cd34e76245f515d0f0595f3abb3a29a8df0014518c816d2db45fd6dbab433595f345a048781753fedfddeeb4a47f2d5e9c39e + languageName: node + linkType: hard + +"ripple-binary-codec@npm:^1.4.3": + version: 1.11.0 + resolution: "ripple-binary-codec@npm:1.11.0" + dependencies: + assert: ^2.0.0 + big-integer: ^1.6.48 + buffer: 6.0.3 + create-hash: ^1.2.0 + decimal.js: ^10.2.0 + ripple-address-codec: ^4.3.1 + checksum: 901f6da22bb31860e8c149974c55c72ba5a7d50d635b7efa9be81ce35cea6576a3b0c59b480069141829d73c558721ab17f34df801d4d68af8f3ae4ed0bbd42c + languageName: node + linkType: hard + "rlp@npm:^2.2.4": version: 2.2.7 resolution: "rlp@npm:2.2.7" @@ -29722,7 +30174,7 @@ react-native-webview@ava-labs/react-native-webview: languageName: node linkType: hard -"sha.js@npm:2, sha.js@npm:^2.4.0, sha.js@npm:^2.4.8": +"sha.js@npm:2, sha.js@npm:^2.4.0, sha.js@npm:^2.4.11, sha.js@npm:^2.4.8": version: 2.4.11 resolution: "sha.js@npm:2.4.11" dependencies: @@ -31163,6 +31615,13 @@ react-native-webview@ava-labs/react-native-webview: languageName: node linkType: hard +"ts-custom-error@npm:^3.2.1": + version: 3.3.1 + resolution: "ts-custom-error@npm:3.3.1" + checksum: 50a1e825fced68d70049bd8d282379a635e43aa023a370fa8e736b12a6edba7f18a2d731fa194ac35303a8b625be56e121bdb31d8a0318250d1a8b277059fce3 + languageName: node + linkType: hard + "ts-dedent@npm:^2.0.0, ts-dedent@npm:^2.2.0": version: 2.2.0 resolution: "ts-dedent@npm:2.2.0" @@ -31313,7 +31772,7 @@ react-native-webview@ava-labs/react-native-webview: languageName: node linkType: hard -"tslib@npm:2.8.1": +"tslib@npm:2.8.1, tslib@npm:^2.3.0": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a From 0b01a84379ac8146e3e24515a9cf8da58716bc23 Mon Sep 17 00:00:00 2001 From: Charon-Fan Date: Mon, 7 Jul 2025 14:01:04 +0800 Subject: [PATCH 02/25] fix: update modal options to use formSheetScreensOptions for Keystone modals --- packages/core-mobile/app/new/routes/(signedIn)/_layout.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core-mobile/app/new/routes/(signedIn)/_layout.tsx b/packages/core-mobile/app/new/routes/(signedIn)/_layout.tsx index e5646a9c0b..8208d62acf 100644 --- a/packages/core-mobile/app/new/routes/(signedIn)/_layout.tsx +++ b/packages/core-mobile/app/new/routes/(signedIn)/_layout.tsx @@ -45,11 +45,11 @@ export default function WalletLayout(): JSX.Element { /> Date: Mon, 7 Jul 2025 17:22:07 +0800 Subject: [PATCH 03/25] fix: simplify QRCode rendering in QRRenderer component --- .../screens/KeystoneSignerScreen/KeystoneSignerScreen.tsx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/core-mobile/app/new/features/hardware/screens/KeystoneSignerScreen/KeystoneSignerScreen.tsx b/packages/core-mobile/app/new/features/hardware/screens/KeystoneSignerScreen/KeystoneSignerScreen.tsx index 5d138f71c9..b51309ff10 100644 --- a/packages/core-mobile/app/new/features/hardware/screens/KeystoneSignerScreen/KeystoneSignerScreen.tsx +++ b/packages/core-mobile/app/new/features/hardware/screens/KeystoneSignerScreen/KeystoneSignerScreen.tsx @@ -161,13 +161,7 @@ const QRRenderer: FC<{ borderRadius: 7, marginVertical: 36 }}> - + Click on the 'Get Signature' button after signing the transaction with From a816362327242673c12bd485361e212045205ce8 Mon Sep 17 00:00:00 2001 From: Charon-Fan Date: Mon, 7 Jul 2025 18:02:43 +0800 Subject: [PATCH 04/25] feat: add light and dark QR code icons for Keystone troubleshooting screen --- packages/core-mobile/app/assets/icons/qrcode_dark.svg | 3 +++ .../app/assets/icons/{qrcode.svg => qrcode_light.svg} | 0 .../hardware/screens/keystoneTroubleshooting/index.tsx | 8 +++++--- 3 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 packages/core-mobile/app/assets/icons/qrcode_dark.svg rename packages/core-mobile/app/assets/icons/{qrcode.svg => qrcode_light.svg} (100%) diff --git a/packages/core-mobile/app/assets/icons/qrcode_dark.svg b/packages/core-mobile/app/assets/icons/qrcode_dark.svg new file mode 100644 index 0000000000..5b0bfae405 --- /dev/null +++ b/packages/core-mobile/app/assets/icons/qrcode_dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/core-mobile/app/assets/icons/qrcode.svg b/packages/core-mobile/app/assets/icons/qrcode_light.svg similarity index 100% rename from packages/core-mobile/app/assets/icons/qrcode.svg rename to packages/core-mobile/app/assets/icons/qrcode_light.svg diff --git a/packages/core-mobile/app/new/features/hardware/screens/keystoneTroubleshooting/index.tsx b/packages/core-mobile/app/new/features/hardware/screens/keystoneTroubleshooting/index.tsx index 58f22b570b..ca2ebfe0f8 100644 --- a/packages/core-mobile/app/new/features/hardware/screens/keystoneTroubleshooting/index.tsx +++ b/packages/core-mobile/app/new/features/hardware/screens/keystoneTroubleshooting/index.tsx @@ -5,9 +5,10 @@ import { walletConnectCache } from 'services/walletconnectv2/walletConnectCache/ import { router, useNavigation, Link } from 'expo-router' import { ScrollScreen } from 'common/components/ScrollScreen' import { BackHandler } from 'react-native' -import { View, Text, SCREEN_WIDTH, Button } from '@avalabs/k2-alpine' +import { View, Text, SCREEN_WIDTH, Button, useTheme } from '@avalabs/k2-alpine' import { Space } from 'common/components/Space' -import QRCode from 'assets/icons/qrcode.svg' +import QRCodeLight from 'assets/icons/qrcode_light.svg' +import QRCodeDark from 'assets/icons/qrcode_dark.svg' export const showKeystoneTroubleshooting = ( params: KeystoneTroubleshootingParams @@ -25,6 +26,7 @@ const KeystoneTroubleshootingScreen = ({ }: { params: KeystoneTroubleshootingParams }): JSX.Element => { + const { theme } = useTheme() const navigation = useNavigation() const { retry } = params @@ -86,7 +88,7 @@ const KeystoneTroubleshootingScreen = ({ - + {theme.isDark ? : } + + + ) diff --git a/packages/core-mobile/app/new/features/onboarding/components/KeystoneTroubleshooting.tsx b/packages/core-mobile/app/new/features/onboarding/components/KeystoneTroubleshooting.tsx index 26a8d79673..653c579b6f 100644 --- a/packages/core-mobile/app/new/features/onboarding/components/KeystoneTroubleshooting.tsx +++ b/packages/core-mobile/app/new/features/onboarding/components/KeystoneTroubleshooting.tsx @@ -55,7 +55,7 @@ export const KeystoneTroubleshooting = ({ diff --git a/packages/core-mobile/app/new/routes/(signedIn)/(modals)/accountSettings/securityAndPrivacy.tsx b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/accountSettings/securityAndPrivacy.tsx index 7c7c83489b..73558b848a 100644 --- a/packages/core-mobile/app/new/routes/(signedIn)/(modals)/accountSettings/securityAndPrivacy.tsx +++ b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/accountSettings/securityAndPrivacy.tsx @@ -136,6 +136,11 @@ const SecurityAndPrivacyScreen = (): JSX.Element => { useBiometrics ]) + const shouldHideRecoveryData = useMemo( + () => [WalletType.KEYSTONE].includes(wallet.type), + [wallet.type] + ) + const recoveryData = useMemo(() => { const data = [ { @@ -220,16 +225,20 @@ const SecurityAndPrivacyScreen = (): JSX.Element => { }} separatorMarginRight={16} /> - - + {!shouldHideRecoveryData && ( + <> + + + + )} Date: Mon, 25 Aug 2025 10:30:09 +0800 Subject: [PATCH 18/25] fix: yarn lock --- package.json | 10 +- yarn.lock | 279 +++++++++++++++++++++++++++++---------------------- 2 files changed, 166 insertions(+), 123 deletions(-) diff --git a/package.json b/package.json index adb1b702c8..ab5123d3fe 100644 --- a/package.json +++ b/package.json @@ -56,5 +56,13 @@ "node": ">=20.18.0", "yarn": ">=3.6.4" }, - "packageManager": "yarn@3.6.4" + "packageManager": "yarn@3.6.4", + "dependencies": { + "@ethereumjs/util": "9.1.0", + "@keystonehq/animated-qr": "0.10.0", + "@keystonehq/keystone-sdk": "0.11.3", + "@ngraveio/bc-ur": "1.1.13", + "react-native-popover-view": "6.1.0", + "react-native-progress": "5.0.1" + } } diff --git a/yarn.lock b/yarn.lock index c61456386b..2e6ca99e35 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1029,16 +1029,16 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.28.0, @babel/generator@npm:^7.28.3": - version: 7.28.3 - resolution: "@babel/generator@npm:7.28.3" +"@babel/generator@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/generator@npm:7.28.0" dependencies: - "@babel/parser": ^7.28.3 - "@babel/types": ^7.28.2 + "@babel/parser": ^7.28.0 + "@babel/types": ^7.28.0 "@jridgewell/gen-mapping": ^0.3.12 "@jridgewell/trace-mapping": ^0.3.28 jsesc: ^3.0.2 - checksum: e2202bf2b9c8a94f7e7a0a049fda0ee037d055c46922e85afa3bbc53309113f859b8193894f991045d7865226028b8f4f06152ed315ab414451932016dba5e42 + checksum: 3fc9ecca7e7a617cf7b7357e11975ddfaba4261f374ab915f5d9f3b1ddc8fd58da9f39492396416eb08cf61972d1aa13c92d4cca206533c553d8651c2740f07f languageName: node linkType: hard @@ -1496,15 +1496,15 @@ __metadata: linkType: hard "@babel/helper-module-transforms@npm:^7.27.3": - version: 7.28.3 - resolution: "@babel/helper-module-transforms@npm:7.28.3" + version: 7.27.3 + resolution: "@babel/helper-module-transforms@npm:7.27.3" dependencies: "@babel/helper-module-imports": ^7.27.1 "@babel/helper-validator-identifier": ^7.27.1 - "@babel/traverse": ^7.28.3 + "@babel/traverse": ^7.27.3 peerDependencies: "@babel/core": ^7.0.0 - checksum: 7cf7b79da0fa626d6c84bfc7b35c079a2559caecaa2ff645b0f1db0d741507aa4df6b5b98a3283e8ac4e89094af271d805bf5701e5c4f916e622797b7c8cbb18 + checksum: c611d42d3cb7ba23b1a864fcf8d6cde0dc99e876ca1c9a67e4d7919a70706ded4aaa45420de2bf7f7ea171e078e59f0edcfa15a56d74b9485e151b95b93b946e languageName: node linkType: hard @@ -1915,12 +1915,12 @@ __metadata: linkType: hard "@babel/helpers@npm:^7.27.6": - version: 7.28.3 - resolution: "@babel/helpers@npm:7.28.3" + version: 7.28.2 + resolution: "@babel/helpers@npm:7.28.2" dependencies: "@babel/template": ^7.27.2 "@babel/types": ^7.28.2 - checksum: 16c7f259dbd23834740ebc1c7e5a32d9424615eacd324ee067b585ab40eaafab37e2e50f50c84183a7e7a31251dc5a65a2ec4f8395f049001bbe6e14d0d3e9d4 + checksum: 7ead856041f73496eeeb4f7f88a741067c8022fc764cbca7fc3e96ae73ce71969f75fd79b40b2c6a60ca4923f9d56f7798fb86ac2538f13b6d4acb54ebb563a7 languageName: node linkType: hard @@ -2033,14 +2033,14 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.0, @babel/parser@npm:^7.28.3": - version: 7.28.3 - resolution: "@babel/parser@npm:7.28.3" +"@babel/parser@npm:^7.27.2, @babel/parser@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/parser@npm:7.28.0" dependencies: - "@babel/types": ^7.28.2 + "@babel/types": ^7.28.0 bin: parser: ./bin/babel-parser.js - checksum: 5aa5ea0683a4056f98cd9cd61650870d5d44ec1654da14f72a8a06fabe7b2a35bf6cef9605f3740b5ded1e68f64ec45ce1aabf7691047a13a1ff2babe126acf9 + checksum: 718e4ce9b0914701d6f74af610d3e7d52b355ef1dcf34a7dedc5930e96579e387f04f96187e308e601828b900b8e4e66d2fe85023beba2ac46587023c45b01cf languageName: node linkType: hard @@ -4064,18 +4064,18 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.0, @babel/traverse@npm:^7.28.3": - version: 7.28.3 - resolution: "@babel/traverse@npm:7.28.3" +"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.27.3, @babel/traverse@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/traverse@npm:7.28.0" dependencies: "@babel/code-frame": ^7.27.1 - "@babel/generator": ^7.28.3 + "@babel/generator": ^7.28.0 "@babel/helper-globals": ^7.28.0 - "@babel/parser": ^7.28.3 + "@babel/parser": ^7.28.0 "@babel/template": ^7.27.2 - "@babel/types": ^7.28.2 + "@babel/types": ^7.28.0 debug: ^4.3.1 - checksum: 5f5ce477adc99ebdd6e8c9b7ba2e0a162bef39a1d3c5860c730c1674e57f9cb057c7e3dfdd652ce890bd79331a70f6cd310902414697787578e68167d52d96e7 + checksum: f1b6ed2a37f593ee02db82521f8d54c8540a7ec2735c6c127ba687de306d62ac5a7c6471819783128e0b825c4f7e374206ebbd1daf00d07f05a4528f5b1b4c07 languageName: node linkType: hard @@ -5155,16 +5155,6 @@ __metadata: languageName: node linkType: hard -"@expo/json-file@npm:^10.0.2": - version: 10.0.2 - resolution: "@expo/json-file@npm:10.0.2" - dependencies: - "@babel/code-frame": ~7.10.4 - json5: ^2.2.3 - checksum: 8b60a5cfe27c60a699964670fb3a9508d338772b0b301ba5977507f511a3846d45fddbc6aa0f8cf7179279fd0db437fea2b11c33f575da7dfcd22f42ba7c80f9 - languageName: node - linkType: hard - "@expo/json-file@npm:^9.1.5, @expo/json-file@npm:~9.1.5": version: 9.1.5 resolution: "@expo/json-file@npm:9.1.5" @@ -5212,26 +5202,26 @@ __metadata: linkType: hard "@expo/osascript@npm:^2.2.5": - version: 2.3.2 - resolution: "@expo/osascript@npm:2.3.2" + version: 2.2.5 + resolution: "@expo/osascript@npm:2.2.5" dependencies: "@expo/spawn-async": ^1.7.2 exec-async: ^2.2.0 - checksum: 0d430acabd7db5d3da8c95561ccab8ff95a8cf05a41db82ba5a6e9e5b995f4a6cdc805538fdf026d19988a890029b0781be8f6bd23579a76b8a00c2e77e76ad8 + checksum: 1025a18f02a934326f494fa84f64201a6887324fb4406099792c6434a75f3366f2ffcfe669ebd32451dfaa027c7ee83b5ba8ac53a0a8d31bbab1887a15c2e588 languageName: node linkType: hard "@expo/package-manager@npm:^1.8.6": - version: 1.9.2 - resolution: "@expo/package-manager@npm:1.9.2" + version: 1.8.6 + resolution: "@expo/package-manager@npm:1.8.6" dependencies: - "@expo/json-file": ^10.0.2 + "@expo/json-file": ^9.1.5 "@expo/spawn-async": ^1.7.2 chalk: ^4.0.0 npm-package-arg: ^11.0.0 ora: ^3.4.0 resolve-workspace-root: ^2.0.0 - checksum: 62064db0d7b9352455ab46d3a8c70307c0e19545c9cdb4154a156681ef6d71f85441a60c1e4372c44b0b4481f98ce9dc53a906d281837e9ec918e5971382b703 + checksum: b2311cd739d80d934415bd1e1389b89ce6363dbc29b4efa086efc5226de25093d42e5b6839426b4c9b182ab5939620ff481ca5f15bd0b7195cad47e971cc4448 languageName: node linkType: hard @@ -6768,12 +6758,12 @@ __metadata: linkType: hard "@jridgewell/gen-mapping@npm:^0.3.12": - version: 0.3.13 - resolution: "@jridgewell/gen-mapping@npm:0.3.13" + version: 0.3.12 + resolution: "@jridgewell/gen-mapping@npm:0.3.12" dependencies: "@jridgewell/sourcemap-codec": ^1.5.0 "@jridgewell/trace-mapping": ^0.3.24 - checksum: f2105acefc433337145caa3c84bba286de954f61c0bc46279bbd85a9e6a02871089717fa060413cfb6a9d44189fe8313b2d1cabf3a2eb3284d208fd5f75c54ff + checksum: 56ee1631945084897f274e65348afbaca7970ce92e3c23b3a23b2fe5d0d2f0c67614f0df0f2bb070e585e944bbaaf0c11cee3a36318ab8a36af46f2fd566bc40 languageName: node linkType: hard @@ -6827,9 +6817,9 @@ __metadata: linkType: hard "@jridgewell/sourcemap-codec@npm:^1.5.0": - version: 1.5.5 - resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" - checksum: c2e36e67971f719a8a3a85ef5a5f580622437cc723c35d03ebd0c9c0b06418700ef006f58af742791f71f6a4fc68fcfaf1f6a74ec2f9a3332860e9373459dae7 + version: 1.5.4 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.4" + checksum: 959093724bfbc7c1c9aadc08066154f5c1f2acc647b45bd59beec46922cbfc6a9eda4a2114656de5bc00bb3600e420ea9a4cb05e68dcf388619f573b77bd9f0c languageName: node linkType: hard @@ -6864,12 +6854,12 @@ __metadata: linkType: hard "@jridgewell/trace-mapping@npm:^0.3.28": - version: 0.3.30 - resolution: "@jridgewell/trace-mapping@npm:0.3.30" + version: 0.3.29 + resolution: "@jridgewell/trace-mapping@npm:0.3.29" dependencies: "@jridgewell/resolve-uri": ^3.1.0 "@jridgewell/sourcemap-codec": ^1.4.14 - checksum: 26edb94faf6f02df346e3657deff9df3f2f083195cbda62a6cf60204d548a0a6134454cbc3af8437392206a89dfb3e72782eaf78f49cbd8924400e55a6575e72 + checksum: 5e92eeafa5131a4f6b7122063833d657f885cb581c812da54f705d7a599ff36a75a4a093a83b0f6c7e95642f5772dd94753f696915e8afea082237abf7423ca3 languageName: node linkType: hard @@ -7912,34 +7902,20 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:1.4.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.4.0": +"@noble/hashes@npm:1.4.0": version: 1.4.0 resolution: "@noble/hashes@npm:1.4.0" checksum: 8ba816ae26c90764b8c42493eea383716396096c5f7ba6bea559993194f49d80a73c081f315f4c367e51bd2d5891700bcdfa816b421d24ab45b41cb03e4f3342 languageName: node linkType: hard -"@noble/hashes@npm:1.8.0": +"@noble/hashes@npm:1.8.0, @noble/hashes@npm:^1.1.5, @noble/hashes@npm:^1.2.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.4.0, @noble/hashes@npm:^1.5.0, @noble/hashes@npm:^1.7.0": version: 1.8.0 resolution: "@noble/hashes@npm:1.8.0" checksum: c94e98b941963676feaba62475b1ccfa8341e3f572adbb3b684ee38b658df44100187fa0ef4220da580b13f8d27e87d5492623c8a02ecc61f23fb9960c7918f5 languageName: node linkType: hard -"@noble/hashes@npm:^1.1.5, @noble/hashes@npm:^1.2.0": - version: 1.3.2 - resolution: "@noble/hashes@npm:1.3.2" - checksum: fe23536b436539d13f90e4b9be843cc63b1b17666a07634a2b1259dded6f490be3d050249e6af98076ea8f2ea0d56f578773c2197f2aa0eeaa5fba5bc18ba474 - languageName: node - linkType: hard - -"@noble/hashes@npm:^1.5.0, @noble/hashes@npm:^1.7.0": - version: 1.7.1 - resolution: "@noble/hashes@npm:1.7.1" - checksum: 4f1b56428a10323feef17e4f437c9093556cb18db06f94d254043fadb69c3da8475f96eb3f8322d41e8670117d7486475a8875e68265c2839f60fd03edd6a616 - languageName: node - linkType: hard - "@noble/secp256k1@npm:2.1.0": version: 2.1.0 resolution: "@noble/secp256k1@npm:2.1.0" @@ -10017,7 +9993,7 @@ __metadata: languageName: node linkType: hard -"@react-navigation/bottom-tabs@npm:7.4.6, @react-navigation/bottom-tabs@npm:^7.3.10": +"@react-navigation/bottom-tabs@npm:7.4.6": version: 7.4.6 resolution: "@react-navigation/bottom-tabs@npm:7.4.6" dependencies: @@ -10033,9 +10009,25 @@ __metadata: languageName: node linkType: hard -"@react-navigation/core@npm:^7.12.3, @react-navigation/core@npm:^7.12.4": - version: 7.12.4 - resolution: "@react-navigation/core@npm:7.12.4" +"@react-navigation/bottom-tabs@npm:^7.3.10": + version: 7.4.4 + resolution: "@react-navigation/bottom-tabs@npm:7.4.4" + dependencies: + "@react-navigation/elements": ^2.6.1 + color: ^4.2.3 + peerDependencies: + "@react-navigation/native": ^7.1.16 + react: ">= 18.2.0" + react-native: "*" + react-native-safe-area-context: ">= 4.0.0" + react-native-screens: ">= 4.0.0" + checksum: b686bb59aec72d6049c34607589a5c5f262da335aa59c46529612daee585c9720b0e4a6e943e49a0af0b0e2f3a0ba7b7e5c8a2ecdf17fc929fb7e1b4decfd886 + languageName: node + linkType: hard + +"@react-navigation/core@npm:^7.12.3": + version: 7.12.3 + resolution: "@react-navigation/core@npm:7.12.3" dependencies: "@react-navigation/routers": ^7.5.1 escape-string-regexp: ^4.0.0 @@ -10046,7 +10038,7 @@ __metadata: use-sync-external-store: ^1.5.0 peerDependencies: react: ">= 18.2.0" - checksum: 84eb6d003d09c271e9e5e8f34c4a440447a82d81df7bd2f87dc4d56f851a5c74b1ec6e488cc2702cf16fde7d33bb55a58fe1dbd14e6cbdd513583b33227c2471 + checksum: 739b500673c93a0a1eaab7e816f6cb215c06f51e39fa73376af88734c6d17bb599a8cbfc94786e19e651aa4a137b968bce080b27779f0858ea9efa112190d5ff languageName: node linkType: hard @@ -10070,7 +10062,7 @@ __metadata: languageName: node linkType: hard -"@react-navigation/elements@npm:2.6.3, @react-navigation/elements@npm:^2.6.1, @react-navigation/elements@npm:^2.6.3": +"@react-navigation/elements@npm:2.6.3, @react-navigation/elements@npm:^2.6.3": version: 2.6.3 resolution: "@react-navigation/elements@npm:2.6.3" dependencies: @@ -10108,7 +10100,27 @@ __metadata: languageName: node linkType: hard -"@react-navigation/native-stack@npm:7.3.25, @react-navigation/native-stack@npm:^7.3.10": +"@react-navigation/elements@npm:^2.6.1": + version: 2.6.1 + resolution: "@react-navigation/elements@npm:2.6.1" + dependencies: + color: ^4.2.3 + use-latest-callback: ^0.2.4 + use-sync-external-store: ^1.5.0 + peerDependencies: + "@react-native-masked-view/masked-view": ">= 0.2.0" + "@react-navigation/native": ^7.1.16 + react: ">= 18.2.0" + react-native: "*" + react-native-safe-area-context: ">= 4.0.0" + peerDependenciesMeta: + "@react-native-masked-view/masked-view": + optional: true + checksum: 4613f01b8fca9a23a97be9b4bb6176d8206f2ab1fff1686920b961b62a054f712b9c26ed119737c7c3be8536b24e8ca00e63b069818010b2b03303eea34f7fe4 + languageName: node + linkType: hard + +"@react-navigation/native-stack@npm:7.3.25": version: 7.3.25 resolution: "@react-navigation/native-stack@npm:7.3.25" dependencies: @@ -10124,27 +10136,27 @@ __metadata: languageName: node linkType: hard -"@react-navigation/native@npm:7.1.16": - version: 7.1.16 - resolution: "@react-navigation/native@npm:7.1.16" +"@react-navigation/native-stack@npm:^7.3.10": + version: 7.3.23 + resolution: "@react-navigation/native-stack@npm:7.3.23" dependencies: - "@react-navigation/core": ^7.12.3 - escape-string-regexp: ^4.0.0 - fast-deep-equal: ^3.1.3 - nanoid: ^3.3.11 - use-latest-callback: ^0.2.4 + "@react-navigation/elements": ^2.6.1 + warn-once: ^0.1.1 peerDependencies: + "@react-navigation/native": ^7.1.16 react: ">= 18.2.0" react-native: "*" - checksum: ed10ebbd7a62145eaa144fff04c00ade31d2f8da716dd7715f9fe14ce51f58c6097b29b7228a5fb04b4eabc4c5040e929c0cdba6e2b1ed3dcc9e1a372321ddb7 + react-native-safe-area-context: ">= 4.0.0" + react-native-screens: ">= 4.0.0" + checksum: bfbed36f60f43e85c95743afd8a86440c9ff40b4f48e3bcf485a1b80da5ae3ac6639ba6c07c8546b8b53290cd5045851f33ebc4234d6ab02304dfec437b2b4bb languageName: node linkType: hard -"@react-navigation/native@npm:^7.1.6": - version: 7.1.17 - resolution: "@react-navigation/native@npm:7.1.17" +"@react-navigation/native@npm:7.1.16, @react-navigation/native@npm:^7.1.6": + version: 7.1.16 + resolution: "@react-navigation/native@npm:7.1.16" dependencies: - "@react-navigation/core": ^7.12.4 + "@react-navigation/core": ^7.12.3 escape-string-regexp: ^4.0.0 fast-deep-equal: ^3.1.3 nanoid: ^3.3.11 @@ -10152,7 +10164,7 @@ __metadata: peerDependencies: react: ">= 18.2.0" react-native: "*" - checksum: f0caa70f777c32861ce23a834d3afe6891c7829016649bf1491ba6b540fd4443dd6c5e6d8b44f58b92efed6074ea986e04b88ff84e9e19c09d68d9302ebd977a + checksum: ed10ebbd7a62145eaa144fff04c00ade31d2f8da716dd7715f9fe14ce51f58c6097b29b7228a5fb04b4eabc4c5040e929c0cdba6e2b1ed3dcc9e1a372321ddb7 languageName: node linkType: hard @@ -13762,20 +13774,13 @@ __metadata: languageName: node linkType: hard -"@xmldom/xmldom@npm:^0.8.3": +"@xmldom/xmldom@npm:^0.8.3, @xmldom/xmldom@npm:^0.8.8": version: 0.8.10 resolution: "@xmldom/xmldom@npm:0.8.10" checksum: 4c136aec31fb3b49aaa53b6fcbfe524d02a1dc0d8e17ee35bd3bf35e9ce1344560481cd1efd086ad1a4821541482528672306d5e37cdbd187f33d7fadd3e2cf0 languageName: node linkType: hard -"@xmldom/xmldom@npm:^0.8.8": - version: 0.8.11 - resolution: "@xmldom/xmldom@npm:0.8.11" - checksum: 72020f3d5c74b54e25d19f2cd7b2d87484926cc7febdf02347dc3e06364186641d54e9e94baaaaba30e99528e6727adcd1baef6d0809e7460aee3a5be890b132 - languageName: node - linkType: hard - "@yarnpkg/lockfile@npm:^1.0.0, @yarnpkg/lockfile@npm:^1.1.0": version: 1.1.0 resolution: "@yarnpkg/lockfile@npm:1.1.0" @@ -15005,9 +15010,9 @@ __metadata: linkType: hard "bignumber.js@npm:^9.0.1": - version: 9.3.0 - resolution: "bignumber.js@npm:9.3.0" - checksum: 580d783d60246e758e527fa879ae0d282d8f250f555dd0fcee1227d680186ceba49ed7964c6d14e2e8d8eac7a2f4dd6ef1b7925dc52f5fc28a5a87639dd2dbd1 + version: 9.3.1 + resolution: "bignumber.js@npm:9.3.1" + checksum: 6ab100271a23a75bb8b99a4b1a34a1a94967ac0b9a52a198147607bd91064e72c6f356380d7a09cd687bf50d81ad2ed1a0a8edfaa90369c9003ed8bb2440d7f0 languageName: node linkType: hard @@ -17214,16 +17219,16 @@ __metadata: linkType: hard "decimal.js@npm:^10.2.0": - version: 10.5.0 - resolution: "decimal.js@npm:10.5.0" - checksum: 91c6b53b5dd2f39a05535349ced6840f591d1f914e3c025c6dcec6ffada6e3cfc8dc3f560d304b716be9a9aece3567a7f80f6aff8f38d11ab6f78541c3a91a01 + version: 10.6.0 + resolution: "decimal.js@npm:10.6.0" + checksum: 9302b990cd6f4da1c7602200002e40e15d15660374432963421d3cd6d81cc6e27e0a488356b030fee64650947e32e78bdbea245d596dadfeeeb02e146d485999 languageName: node linkType: hard "decimal.js@npm:^10.4.3": - version: 10.6.0 - resolution: "decimal.js@npm:10.6.0" - checksum: 9302b990cd6f4da1c7602200002e40e15d15660374432963421d3cd6d81cc6e27e0a488356b030fee64650947e32e78bdbea245d596dadfeeeb02e146d485999 + version: 10.5.0 + resolution: "decimal.js@npm:10.5.0" + checksum: 91c6b53b5dd2f39a05535349ced6840f591d1f914e3c025c6dcec6ffada6e3cfc8dc3f560d304b716be9a9aece3567a7f80f6aff8f38d11ab6f78541c3a91a01 languageName: node linkType: hard @@ -20288,13 +20293,13 @@ __metadata: linkType: hard "fs-extra@npm:^11.3.0": - version: 11.3.1 - resolution: "fs-extra@npm:11.3.1" + version: 11.3.0 + resolution: "fs-extra@npm:11.3.0" dependencies: graceful-fs: ^4.2.0 jsonfile: ^6.0.1 universalify: ^2.0.0 - checksum: 12968b8b426f298c9ddfa9c2163e828a3bdf295b222895073faaec9798286102d771f54374498b934520cab6ef900ee3d643ea53b98a82703d5c546e16975538 + checksum: f983c706e0c22b0c0747a8e9c76aed6f391ba2d76734cf2757cd84da13417b402ed68fe25bace65228856c61d36d3b41da198f1ffbf33d0b34283a2f7a62c6e9 languageName: node linkType: hard @@ -23426,12 +23431,12 @@ __metadata: linkType: hard "launch-editor@npm:^2.9.1": - version: 2.11.1 - resolution: "launch-editor@npm:2.11.1" + version: 2.11.0 + resolution: "launch-editor@npm:2.11.0" dependencies: picocolors: ^1.1.1 shell-quote: ^1.8.3 - checksum: 95a2e0a50ce15425a87fd035bdef2de37e13c2aee9cd62756783efb286a6e36a341cfcbaecb0d578131a5411c6a1c74c422f9c5b6cb6f4c8284d6078967e08b4 + checksum: 88c6b95582ca9e39dc8d98cc7b62090b3ea72441a94b44e3208a11ad8966f401ca5ba599bd1b907ac8a596855d4aac09a113abf3659532dad83f37a7636df30d languageName: node linkType: hard @@ -24949,8 +24954,14 @@ __metadata: version: 0.0.0-use.local resolution: "mobile-monorepo@workspace:." dependencies: + "@ethereumjs/util": 9.1.0 + "@keystonehq/animated-qr": 0.10.0 + "@keystonehq/keystone-sdk": 0.11.3 + "@ngraveio/bc-ur": 1.1.13 husky: 9.1.6 lint-staged: 15.2.10 + react-native-popover-view: 6.1.0 + react-native-progress: 5.0.1 languageName: unknown linkType: soft @@ -28129,15 +28140,15 @@ __metadata: linkType: hard react-native-webview@ava-labs/react-native-webview: - version: 13.12.2 - resolution: "react-native-webview@https://github.com/ava-labs/react-native-webview.git#commit=114379c625b5edda2433170022819801fe81638e" + version: 13.15.0 + resolution: "react-native-webview@https://github.com/ava-labs/react-native-webview.git#commit=15480b1312661eebd4d872f523f0f91d950a452f" dependencies: escape-string-regexp: ^4.0.0 invariant: 2.2.4 peerDependencies: react: "*" react-native: "*" - checksum: 6f005151d0b9f4210ad58a55706334c950077e45bb9358a6e2d992386d4079c6f1eac04911a925ffbb839cb7ab847a0cff1177af0fc61cf3172e0a0bb018ba37 + checksum: eed2ea660a2e7e93a4a9878d6329d21ee93c43c5443ceb724bcbbe7af6ed330e48e4d9954d294f54b6017c52759a795acfb294a789630a3649b9ff2f71684c30 languageName: node linkType: hard @@ -29270,7 +29281,7 @@ react-native-webview@ava-labs/react-native-webview: languageName: node linkType: hard -"safe-buffer@npm:5.2.1, safe-buffer@npm:>=5.1.0, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.0, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:5.2.1, safe-buffer@npm:>=5.1.0, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.1, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.0, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 @@ -29704,7 +29715,7 @@ react-native-webview@ava-labs/react-native-webview: languageName: node linkType: hard -"sha.js@npm:2, sha.js@npm:^2.4.0, sha.js@npm:^2.4.11, sha.js@npm:^2.4.8": +"sha.js@npm:2, sha.js@npm:^2.4.0, sha.js@npm:^2.4.8": version: 2.4.11 resolution: "sha.js@npm:2.4.11" dependencies: @@ -29716,6 +29727,19 @@ react-native-webview@ava-labs/react-native-webview: languageName: node linkType: hard +"sha.js@npm:^2.4.11": + version: 2.4.12 + resolution: "sha.js@npm:2.4.12" + dependencies: + inherits: ^2.0.4 + safe-buffer: ^5.2.1 + to-buffer: ^1.2.0 + bin: + sha.js: bin.js + checksum: 9ec0fe39cc402acb33ffb18d261b52013485a2a9569a1873ff1861510a67b9ea2b3ccc78ab8aa09c34e1e85a5f06e18ab83637715509c6153ba8d537bbd2c29d + languageName: node + linkType: hard + "sha3@npm:2.1.4": version: 2.1.4 resolution: "sha3@npm:2.1.4" @@ -31063,9 +31087,9 @@ react-native-webview@ava-labs/react-native-webview: linkType: hard "tmp@npm:^0.2.1": - version: 0.2.5 - resolution: "tmp@npm:0.2.5" - checksum: 9d18e58060114154939930457b9e198b34f9495bcc05a343bc0a0a29aa546d2c1c2b343dae05b87b17c8fde0af93ab7d8fe8574a8f6dc2cd8fd3f2ca1ad0d8e1 + version: 0.2.4 + resolution: "tmp@npm:0.2.4" + checksum: fde5fcdbd741c957458d6f7310750879172b399ac62b468c6707cef6fd0e77d0e632dd05471f607530a248c483abaa00187a6eee8561030268ac98bfb5e41720 languageName: node linkType: hard @@ -31076,6 +31100,17 @@ react-native-webview@ava-labs/react-native-webview: languageName: node linkType: hard +"to-buffer@npm:^1.2.0": + version: 1.2.1 + resolution: "to-buffer@npm:1.2.1" + dependencies: + isarray: ^2.0.5 + safe-buffer: ^5.2.1 + typed-array-buffer: ^1.0.3 + checksum: a683dcf19bea02ed6af477513248d514b7590641170c2d64dd2b235bd9896193b0aea5f46ab64f50b787562aafce421569db6e44230b95beb8fb675a9169464b + languageName: node + linkType: hard + "to-fast-properties@npm:^2.0.0": version: 2.0.0 resolution: "to-fast-properties@npm:2.0.0" @@ -31794,9 +31829,9 @@ react-native-webview@ava-labs/react-native-webview: linkType: hard "undici@npm:^6.18.2 || ^7.0.0": - version: 7.5.0 - resolution: "undici@npm:7.5.0" - checksum: 796498f9d134a14a513282915109ebcb96605069e8a2b0d58271fe05cb42a5cf76f5dfa416c21e0ebfaf9df57a17a09d5a778906e7e25581df66b28f97437158 + version: 7.12.0 + resolution: "undici@npm:7.12.0" + checksum: dec61384d1d2c610f381debfe6b61bb4720720f36b8a5669ffd216d4e956fa283cb1fd9717ea44bc16b9e8a576ed237a67c40f00b0eba9df46cad01c5945abd8 languageName: node linkType: hard From 0fc9f26e876546d4cce302a2f36b3cb899c42631 Mon Sep 17 00:00:00 2001 From: Charon-Fan Date: Wed, 3 Sep 2025 10:24:53 +0800 Subject: [PATCH 19/25] feat: enhance wallet handling and add KeystoneWallet support --- .../new/common/hooks/useCombinedPrimaryNetworks.ts | 12 +++++++++--- .../app/services/wallet/KeystoneWallet/index.ts | 4 ++++ .../app/services/wallet/WalletService.tsx | 10 +++++++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/core-mobile/app/new/common/hooks/useCombinedPrimaryNetworks.ts b/packages/core-mobile/app/new/common/hooks/useCombinedPrimaryNetworks.ts index 186dc9891a..bb9f606f1f 100644 --- a/packages/core-mobile/app/new/common/hooks/useCombinedPrimaryNetworks.ts +++ b/packages/core-mobile/app/new/common/hooks/useCombinedPrimaryNetworks.ts @@ -9,6 +9,8 @@ import { } from 'services/network/consts' import { selectIsSolanaSupportBlocked } from 'store/posthog/slice' import { selectIsDeveloperMode } from 'store/settings/advanced' +import { WalletType } from 'services/wallet/types' +import { useActiveWallet } from './useActiveWallet' /** * Hook to get the combined primary networks (networks are merged together with same address) @@ -21,20 +23,24 @@ export function useCombinedPrimaryNetworks(): { } { const isDeveloperMode = useSelector(selectIsDeveloperMode) const isSolanaSupportBlocked = useSelector(selectIsSolanaSupportBlocked) + const wallet = useActiveWallet() const networks = useMemo(() => { + const blockSolana = + isSolanaSupportBlocked || wallet.type === WalletType.KEYSTONE + // Test networks if (isDeveloperMode) { - return isSolanaSupportBlocked + return blockSolana ? (TEST_PRIMARY_NETWORKS as Network[]) : [...TEST_PRIMARY_NETWORKS, NETWORK_SOLANA_DEVNET] } // Main networks - return isSolanaSupportBlocked + return blockSolana ? (MAIN_PRIMARY_NETWORKS as Network[]) : [...MAIN_PRIMARY_NETWORKS, NETWORK_SOLANA] - }, [isDeveloperMode, isSolanaSupportBlocked]) + }, [isDeveloperMode, isSolanaSupportBlocked, wallet.type]) return { networks } } diff --git a/packages/core-mobile/app/services/wallet/KeystoneWallet/index.ts b/packages/core-mobile/app/services/wallet/KeystoneWallet/index.ts index 19c67a8cd1..4708542b03 100644 --- a/packages/core-mobile/app/services/wallet/KeystoneWallet/index.ts +++ b/packages/core-mobile/app/services/wallet/KeystoneWallet/index.ts @@ -96,6 +96,10 @@ export default class KeystoneWallet implements Wallet { return { r, s, v } } + public getRawXpubXP(): string { + return this.xpubXP + } + public async signMessage({ rpcMethod, data, diff --git a/packages/core-mobile/app/services/wallet/WalletService.tsx b/packages/core-mobile/app/services/wallet/WalletService.tsx index 83f9203c67..8d3fe8fcd1 100644 --- a/packages/core-mobile/app/services/wallet/WalletService.tsx +++ b/packages/core-mobile/app/services/wallet/WalletService.tsx @@ -50,6 +50,7 @@ import { } from './utils' import WalletFactory from './WalletFactory' import { MnemonicWallet } from './MnemonicWallet' +import KeystoneWallet from './KeystoneWallet' // Tolerate 50% buffer for burn amount for EVM transactions const EVM_FEE_TOLERANCE = 50 @@ -314,7 +315,7 @@ class WalletService { walletId: string walletType: WalletType }): Promise { - if (walletType !== WalletType.MNEMONIC) { + if (![WalletType.MNEMONIC, WalletType.KEYSTONE].includes(walletType)) { throw new Error('Unable to get raw xpub XP: unsupported wallet type') } @@ -323,9 +324,12 @@ class WalletService { walletType }) - if (!(wallet instanceof MnemonicWallet)) { + if ( + !(wallet instanceof MnemonicWallet) && + !(wallet instanceof KeystoneWallet) + ) { throw new Error( - 'Unable to get raw xpub XP: Expected MnemonicWallet instance' + 'Unable to get raw xpub XP: Expected MnemonicWallet or KeystoneWallet instance' ) } From 7acfb4e1a0724f4acc45ce42079778e155924c6f Mon Sep 17 00:00:00 2001 From: Charon-Fan Date: Wed, 3 Sep 2025 11:34:44 +0800 Subject: [PATCH 20/25] chore: update Podfile.lock to reflect dependency version changes --- packages/core-mobile/ios/Podfile.lock | 268 +++++++++++++------------- 1 file changed, 134 insertions(+), 134 deletions(-) diff --git a/packages/core-mobile/ios/Podfile.lock b/packages/core-mobile/ios/Podfile.lock index d8013d7b12..74198c43d4 100644 --- a/packages/core-mobile/ios/Podfile.lock +++ b/packages/core-mobile/ios/Podfile.lock @@ -3830,7 +3830,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73 AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f - boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90 + boost: 1dca942403ed9342f98334bf4c3621f011aa7946 CatCrypto: a477899b6be4954e75be4897e732da098cc0a5a8 ComputableLayout: c50faffac4ed9f8f05b0ce5e6f3a60df1f6042c8 ContextMenuAuxiliaryPreview: 20be0be795b783b68f8792732eed4bed9f202c1c @@ -3839,38 +3839,38 @@ SPEC CHECKSUMS: DatadogInternal: a514ba01c9eb99dbe1ddd4452e218706bb0ddc2b DatadogLogs: 9352c58e4ab4a88f0ed7c20f27dc8d24442acc5e DatadogRUM: ab979c800d3fb7d7b2ff364a11d137b6a4be6831 - DatadogSDKReactNative: dc0db8e0608412abaf4b0297637586a8cc0972e5 + DatadogSDKReactNative: ad2a27c00fe2fd3c9f406c78f13d9190ff8dab82 DatadogTrace: 23df8545911d219d4c15446a4c6c04862ff76175 DatadogWebViewTracking: e88b8057eb5ff06a68baf232ae37637b8bb7518b DGSwiftUtilities: 567f8d5ee618f0b7afb185b17aa45ff356315a0f - DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb - EXApplication: 50cc8ea58c138da6e3f25cd789634219c86b90d5 - EXConstants: 9d62a46a36eae6d28cb978efcbc68aef354d1704 + DoubleConversion: f16ae600a246532c4020132d54af21d0ddb2a385 + EXApplication: 1e06972201838375ca1ec1ba34d586a98a5dc718 + EXConstants: 98bcf0f22b820f9b28f9fee55ff2daededadd2f8 EXJSONUtils: 1d3e4590438c3ee593684186007028a14b3686cd - EXManifests: f4cc4a62ee4f1c8a9cf2bb79d325eac6cb9f5684 - Expo: 666a397fcb608d72b019e16ba139b74e93e0b7d7 - expo-dev-client: f1b99dfea0c9174d2e4ec96c2c5461587dda1e86 - expo-dev-launcher: 27e8eba58d52b2f471b0c4001b0535a1c0b5610d - expo-dev-menu: 2868212810f6651bc5c30e72c636ef64de31ec6b + EXManifests: 691a779b04e4f2c96da46fb9bef4f86174fefcb5 + Expo: a40d525c930dd1c8a158e082756ee071955baccb + expo-dev-client: 9b1e78baf0dd87b005f035d180bbb07c05917fad + expo-dev-launcher: 35dc0269b5fc1f628abc00e08e5a969e7809eff4 + expo-dev-menu: 0771fa9c5c405e07aa15e55a699b8a4a984ea77a expo-dev-menu-interface: 609c35ae8b97479cdd4c9e23c8cf6adc44beea0e - ExpoAdapterGoogleSignIn: da10ae7e7c1d73a10c2facebcdfe5ebea8e073ce - ExpoAsset: 7bdbbacf4e6752ae6e3cf70555cee076f6229e6e - ExpoBlur: 846780b2c90f59e964b9a50385d4deb67174ebfb - ExpoCamera: fc1ab0e1c665b543a307c577df107e37cc2edc8e - ExpoFileSystem: 9681caebda23fa1b38a12a9c68b2bade7072ce20 - ExpoFont: 091a47eeaa1b30b0b760aa1d0a2e7814e8bf6fe6 - ExpoHaptics: 68c215e070f660e0a29c45dcda4f60eeff08aefb - ExpoHead: 7c1893efc8dc79570bdcbdadce175723f4c037ec - ExpoImage: 3099001359e4414d60addd7c3e00a5d949df41e0 - ExpoKeepAwake: e8dedc115d9f6f24b153ccd2d1d8efcdfd68a527 - ExpoLinearGradient: ce334cff9859da4635c1d8eff6e291b11b04ccbb - ExpoLinking: 343a89ea864a851831fd4495e8aea01cf0f6a36f - ExpoLocalAuthentication: 78f74d187ee51126e1a789d73fee32d6d7e60f1f - ExpoLocalization: 677e45c2536bf918119962f78d7ffeeea317e07d - ExpoModulesCore: 16f74d8df26d7e4b6bf7eb3d0effaf0f15df7b80 - ExpoSMS: de195632beeb7ef00556750da10da667596d8967 - ExpoVideo: 84edf8e48b71317fb1d7f17c3d49a310476dc0f4 - EXUpdatesInterface: 64f35449b8ef89ce08cdd8952a4d119b5de6821d + ExpoAdapterGoogleSignIn: 6393c1ad521f880f6e467bca40baf1e5dcaea4a3 + ExpoAsset: ef06e880126c375f580d4923fdd1cdf4ee6ee7d6 + ExpoBlur: 3c8885b9bf9eef4309041ec87adec48b5f1986a9 + ExpoCamera: e1879906d41184e84b57d7643119f8509414e318 + ExpoFileSystem: 7f92f7be2f5c5ed40a7c9efc8fa30821181d9d63 + ExpoFont: cf508bc2e6b70871e05386d71cab927c8524cc8e + ExpoHaptics: 0ff6e0d83cd891178a306e548da1450249d54500 + ExpoHead: a7b66cbaeeb51f4a85338d335a0f5467e29a2c90 + ExpoImage: f2c9cfd2a4cb918bba7ddbb40da851858f7aece4 + ExpoKeepAwake: bf0811570c8da182bfb879169437d4de298376e7 + ExpoLinearGradient: 7734c8059972fcf691fb4330bcdf3390960a152d + ExpoLinking: d5c183998ca6ada66ff45e407e0f965b398a8902 + ExpoLocalAuthentication: c35f18692dcb35775a1be0f37b2131096951a6bd + ExpoLocalization: 999a1ff61a7f5917d65c2bd9234883009019ca9f + ExpoModulesCore: 00a1b5c73248465bd0b93f59f8538c4573dac579 + ExpoSMS: 770f0b60a777f5d3f65fd7fc369ff62ff97e09a9 + ExpoVideo: ada534976cfd4a6bf082cc61aa1b17920a251e32 + EXUpdatesInterface: 7ff005b7af94ee63fa452ea7bb95d7a8ff40277a fast_float: 06eeec4fe712a76acc9376682e4808b05ce978b6 FBLazyVector: d2a9cd223302b6c9aa4aa34c1a775e9db609eb52 Firebase: 7a56fe4f56b5ab81b86a6822f5b8f909ae6fc7e2 @@ -3881,139 +3881,139 @@ SPEC CHECKSUMS: FirebaseCoreInternal: f47dd28ae7782e6a4738aad3106071a8fe0af604 FirebaseInstallations: d8063d302a426d114ac531cd82b1e335a0565745 FirebaseMessaging: 9f4e42053241bd45ce8565c881bfdd9c1df2f7da - fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd - glog: 5683914934d5b6e4240e497e0f4a3b42d1854183 + fmt: 01b82d4ca6470831d1cc0852a1af644be019e8f6 + glog: 08b301085f15bcbb6ff8632a8ebaf239aae04e6a GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleSignIn: d4281ab6cf21542b1cfaff85c191f230b399d2db GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 hermes-engine: f03b0e06d3882d71e67e45b073bb827da1a21aae - jail-monkey: a71b35d482a70ecba844a90f002994012cf12a5d + jail-monkey: 1846061ac12e861ac5a8ec7197b0daa775b83733 libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7 libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f lottie-ios: a881093fab623c467d3bce374367755c272bdd59 - lottie-react-native: 2ed3839d12e44b5946a901687e9ab00ee9bc3232 + lottie-react-native: 8bc11e10576d1a3f77f4e0ae5b70503c5c890a09 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c OpenTelemetrySwiftApi: aaee576ed961e0c348af78df58b61300e95bd104 PLCrashReporter: db59ef96fa3d25f3650040d02ec2798cffee75f2 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 - RCT-Folly: 36fe2295e44b10d831836cc0d1daec5f8abcf809 + RCT-Folly: e78785aa9ba2ed998ea4151e314036f6c49e6d82 RCTDeprecation: 5f638f65935e273753b1f31a365db6a8d6dc53b5 RCTRequired: 8b46a520ea9071e2bc47d474aa9ca31b4a935bd8 RCTTypeSafety: cc4740278c2a52cbf740592b0a0a40df1587c9ab React: 6393ae1807614f017a84805bf2417e3497f518a6 React-callinvoker: c34f666f551f05a325b87e7e3e6df0e082fa3d99 React-Codegen: 4b8b4817cea7a54b83851d4c1f91f79aa73de30a - React-Core: fc07a4b69a963880b25142c51178f4cb75628c7d - React-CoreModules: 94d39315cfa791f6c477712fea47c34f8ecb26c6 - React-cxxreact: 628c28cdb3fdef93ee3bfc2bec8e2d776e81ae49 + React-Core: 1ba9acdf7accbd46ccaae99999443ae2722c82b7 + React-CoreModules: 3c3cf4a91257f138e3feb47169a2d7fe341b5495 + React-cxxreact: 444d518a5d3a933e029b5e5ca6d8127c2e43255c React-debug: a951cdb698321d78ebd955fc8788ebbe51af3519 - React-defaultsnativemodule: 08779733c4541be5da1f1d3ec8492300dbc3c00a - React-domnativemodule: fdd4821b9a0c44e87ed9263231225aa65fe982e0 - React-Fabric: 8d905d8c41d666bf283a5b09db56bdaccfa07c8d - React-FabricComponents: 43aab5c94c7b5bbcabc3a9821b8536a0711a0f01 - React-FabricImage: 10708fa449d3f1b4a8d6eedb97f0c6476b098bb4 + React-defaultsnativemodule: 35816c7cb315962495d815446b2c8f1f3d2396ad + React-domnativemodule: 94efa04e53aa12a6dc02d420f1564ee18f3059bd + React-Fabric: bb8ccdb10256fa8acfd98a189590e2e44878abd7 + React-FabricComponents: 60703b954ca7e3d09cdb8d6fff6a4118f3c1478f + React-FabricImage: 0a8cc153d20af111f966e14b3814faa692a6805d React-featureflags: 32d776f9bef34bdab6218ad99db535e75e5c1f4e - React-featureflagsnativemodule: 413da7bc0d21aa86315dbea0fb2b2c27cb8b4bab - React-graphics: 83c676b633acc5044b5c5dfdb7f95aa3aaf7b7a5 - React-hermes: af1b3d79491295abc9d1b11f84e77d5dc00095b6 - React-idlecallbacksnativemodule: b039a595f29d9a87bbad12e731de45879a054b33 - React-ImageManager: 81dc38602ff1e7a8fd5fe3bf54772cf1a30d49c1 - React-jserrorhandler: b230f573b63a6a2a5540054d46cfb6087d26c86c - React-jsi: e9c3019e00db5d144e0a660616a52a605e12c39a - React-jsiexecutor: 3ed70a394b76f33e6c4ec4b382a457df7309d96c - React-jsinspector: 977527f0224edb5ae0970e946411f36dd1d70f43 - React-jsinspectortracing: 64ec4bde979134830c8f937758416f8d50daa8fb - React-jsitooling: 9dd45534fd158b508f785b547bf1350933bf465a - React-jsitracing: a645b2b3c4f6aa79051d5485c67b188ef49045a0 - React-logger: e6e6164f1753e46d1b7e2c8f0949cd7937eaf31b - React-Mapbuffer: 5b4959cbd91e7e8fae42ab0f4b7c25b86fd139a1 - React-microtasksnativemodule: 1695ab137281dd03de967b7bbeb4e392601f6432 - react-native-aes: 8e4348c6e75fcb32f5a960e987df877e1062714e - react-native-bottom-tabs: 5f3293a58aa9810ccdbf76d04c87bf52ab661200 - react-native-compat: 8fd509839fcf4e5646b4ff2281912d95bbd66334 - react-native-config: 8f7283449bbb048902f4e764affbbf24504454af - react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06 - react-native-ios-context-menu: f5c2bc565a9a8599bb4513c43835a38e00d73b3a - react-native-ios-utilities: 73c3e0a51544c059f80eecc226a3530609e10c42 - react-native-keyboard-controller: afd3252995bc3727ebe4b4f4997937323c2845c8 - react-native-menu: 8cc212c18ae939db6932e3c3feae9a99a80f0ecb - react-native-mmkv: 2421db62a08da22d1b97ea4d55adfee9ea0f88a1 - react-native-netinfo: f0a9899081c185db1de5bb2fdc1c88c202a059ac - react-native-pager-view: 794f015a4e3b7cfb9ede97c73eae15c0d11a3fbc - react-native-passkey: e0b0f58fa9b33c424bafaa0a93d66fb0e21dc092 - react-native-quick-base64: 2f2d797c2a3a7d49d77bdef41045f9391f3f4c09 - react-native-quick-crypto: e0b1003058f1706acd425c156f494a485d18509e - react-native-restart: 7595693413fe3ca15893702f2c8306c62a708162 - react-native-safe-area-context: 638038e064cdf9747580a2e47717b09be309a321 - react-native-skia: d4b71ff628f69fd8e1b2d0dbd436d6ab6ee8d669 - react-native-slider: c4c1a975352113af59b59dc783abc111618ec37a - react-native-theme-control: ad1dbaa6ac374bccf0100024269cadd44c73aa33 - react-native-view-shot: 41c5c50c809f1fd61f91c99400b2222c9b80d13f - react-native-webview: f23e694e18f05a5340a3432c57b4145d520333db - React-NativeModulesApple: 3ecc647742d33ad617bd2805902e3f91f2b3008f + React-featureflagsnativemodule: dd5e1e8579d7c3e10b31969c4ca2f56ba3743ec2 + React-graphics: bce95f01799245fa58ca35bdc06a98677b67352e + React-hermes: 9ec11ce5f88c0778e027aa06a6e3e6eb19ddae09 + React-idlecallbacksnativemodule: 9d125d1b9bb3e0bb4de334fea94228e6eeac1852 + React-ImageManager: c40cb4a131371ddecbabc618ef354c57c864c550 + React-jserrorhandler: c00e040f76b32a1846d7eb43602a78ad1e1f60d1 + React-jsi: 8f065aa1ae1d35bef3c394cb1663d114c4952fd8 + React-jsiexecutor: fc8e69fb870cb6e69920fd482a76d4ae54a1c40a + React-jsinspector: 42760714871594f021b3bf223f2f9ac350183ed3 + React-jsinspectortracing: 237f149a09bab785ec6b3a15cc92fc51c0d15cc4 + React-jsitooling: ef1fca866f14d8d4bd80a9570118c19e62775f96 + React-jsitracing: cfa927f650c6f7da613da9fe2a6eeaebc6b2ad1b + React-logger: 85fa3509931497c72ccd2547fcc91e7299d8591e + React-Mapbuffer: 96a2f2a176268581733be182fa6eebab1c0193be + React-microtasksnativemodule: bda561d2648e1e52bd9e5a87f8889836bdbde2e2 + react-native-aes: e2868d9f7203f573a2c1d797d95f4e88a54fa8cd + react-native-bottom-tabs: 05d040c837f04e57e6973d553db5e69c8e279113 + react-native-compat: 4594cac40c688f5ac4984e93f8c8e31496f4e614 + react-native-config: ea75335a7cca1d3326de1da384227e580a7c082e + react-native-get-random-values: d16467cf726c618e9c7a8c3c39c31faa2244bbba + react-native-ios-context-menu: 58804cdc253f80878284abe55ac5a050d4cde96a + react-native-ios-utilities: b3cf760d44fcc8220fdc0fe832beec7453483962 + react-native-keyboard-controller: 6639909c537996e456f3cc8dcfdda3a0cbcd6fc8 + react-native-menu: be9bce4eb201a4d13734744763d36d56e6df8b4a + react-native-mmkv: d3cc73d2554fafa20dc5b86386359034d1faf8ff + react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187 + react-native-pager-view: f238ed7fb53458bd03366944a33686f067c83e9a + react-native-passkey: 3aac247c18127443ef4a002b59d8e12dc7e99f2e + react-native-quick-base64: 651d972291fd5d9902869636a1b3c46820324490 + react-native-quick-crypto: 71b622aa0a231ac068759f5eef37982ad5eae58c + react-native-restart: 0bc732f4461709022a742bb29bcccf6bbc5b4863 + react-native-safe-area-context: 7e926a200d4bc9c56562275743705c6b56176455 + react-native-skia: 5c086469906cf854e26126b5b88dcbb6c93eb90f + react-native-slider: 78ccabe016aef7418b1a846b31115b4165c4dde6 + react-native-theme-control: d5836bcec2a9f3c3d3fd4e38874524b19a1da359 + react-native-view-shot: 57c7b8158751f19f32cb885109574712955ea016 + react-native-webview: 85c8fc8ca09f4e67b68afbc86207a1442af5dc80 + React-NativeModulesApple: 1ecb83880dd11baf2228f8dd89d8419c387e03ad React-oscompat: 0592889a9fcf0eacb205532028e4a364e22907dd - React-perflogger: 634408a9a0f5753faa577dfa81bc009edca01062 - React-performancetimeline: faa22f963845ae2298c28ef6b84bd8b58d3d8a90 + React-perflogger: c584fa50e422a46f37404d083fad12eb289d5de4 + React-performancetimeline: 8deae06fc819e6f7d1f834818e72ab5581540e45 React-RCTActionSheet: ce67bdc050cc1d9ef673c7a93e9799288a183f24 - React-RCTAnimation: 12193c2092a78012c7f77457806dcc822cc40d2c - React-RCTAppDelegate: 7225b51d5b6d3ddd3702165d717a1ffd4a90fb71 - React-RCTBlob: 923cf9b0098b9a641cb1e454c30a444d9d3cda70 - React-RCTFabric: a280fd9f2697c144b0d835200080a09ab15b2e07 - React-RCTFBReactNativeSpec: 50eabdca1efbf6ce1d774b816a68e6cc4b2a5598 - React-RCTImage: 580a5d0a6fdf9b69629d0582e5fb5a173e152099 - React-RCTLinking: 4ed7c5667709099bfd6b2b6246b1dfd79c89f7cb - React-RCTNetwork: 06a22dd0088392694df4fd098634811aa0b3e166 - React-RCTRuntime: 17c77bab5d39bc354c9983f8f11c7d3597fa8344 - React-RCTSettings: 9dbf433f302c8ebe43b280453e74624098fbc706 - React-RCTText: 92fcd78d6c44dbe64d147bb63f53698bcba7c971 - React-RCTVibration: 513659394c92491e6c749e981424f6e1e0abdb3c + React-RCTAnimation: 8bb813eb29c6de85be99c62640f3a999df76ba02 + React-RCTAppDelegate: 0200dcd70e996a7061965cfa7f8c443013cc11a1 + React-RCTBlob: a1dd15758420b6a8154019c5c188cf90648bc487 + React-RCTFabric: c7825ff7180893c4213eae8d249b279fc6bf5253 + React-RCTFBReactNativeSpec: b42afeff81dfd0618a4d37c6c6cb99a66b93a363 + React-RCTImage: 8a4f6ce18e73a7e894b886dfb7625e9e9fbc90ef + React-RCTLinking: fa49c624cd63979e7a6295ae9b1351d23ac4395a + React-RCTNetwork: f236fd2897d18522bba24453e2995a4c83e01024 + React-RCTRuntime: 6b9e893b1d375b7a733fe26c8781e8f062f52951 + React-RCTSettings: 69e2f25a5a1bf6cb37eef2e5c3bd4bb7e848296b + React-RCTText: 515ce74ed79c31dbf509e6f12770420ebbf23755 + React-RCTVibration: ef30ada606dfed859b2c71577f6f041d47f2cfbb React-rendererconsistency: aedf87f8509bc0936ae5475d4ea1e26cb5e8def6 - React-renderercss: 71727bedda678e0918506749f94f745e1050a080 - React-rendererdebug: 81a6b97bd089b49a8e7f4f5c7fd1de588c0e8a11 + React-renderercss: 636c2fffff5334897fc7745442c5e450a90eb549 + React-rendererdebug: 9c95cda4ebc6afb3b474924bb185b42ae317c02d React-rncore: 3eb6f7bdfd181bc26f9f3edc87f70eb1a68a2f3c - React-RuntimeApple: 368e8e7b0018f9e9ca4294a6a8167e6aebc6eb87 - React-RuntimeCore: 0f9a8bb41e043f3adaea111e5128801af0dfbc34 + React-RuntimeApple: 2cf5c8e38bfccd0e6aa47e3f87a1a3e85ae7fb87 + React-RuntimeCore: 2f87f504ca55b4a2a6bda1ee50c144b33cce0a15 React-runtimeexecutor: ebfd71307b3166c73ac0c441c1ea42e0f17f821d - React-RuntimeHermes: 7f55a7285794023ccb3cfe3e89c66c632ed566b1 - React-runtimescheduler: 316243b204bb6a5fd80cea7a97df9b1614ee1b0e + React-RuntimeHermes: a8391605396019d1f72079d3c72e80fcdc79c6a2 + React-runtimescheduler: 158b956675f624b3d3158ffab8f711ebf54fb3a6 React-timing: acc3fa92c72dcc1de6300d752ebb84a1d55dc809 - React-utils: 4efa98c1c602f5eacac3cece396c0b7c7d70c1d3 - ReactAppDependencyProvider: c42e7abdd2228ae583bdabc3dcd8e5cda6bef944 - ReactCodegen: 4d001cd4fa72b876bbff500bbb3811e458bb3c72 - ReactCommon: 41137f7e87cf7fd1c041a7124dfa3d0d48aa43f3 - ReactNativePerformance: ab7dee4c4862623d72c1530a9fc71b55458edf71 - RNAppleAuthentication: e00c76acb03351f5544373c78fa7f359bef6d5d3 - RNArgon2: 1481820722fd4af1575c09f7fc9ad67c00ee8a42 - RNBootSplash: f82b177a12ac2fde212e29c13480d9a08924f624 - RNCAsyncStorage: c1bbcf629d7206d1e19310827848b98d68a4cbaf - RNCClipboard: e63f1470286d683f2ade736feb352f4f18745247 - RNCMaskedView: 3e8d6bf9764b519d077986413882959eafceffbc - RNDateTimePicker: 792e57dd210f8af940812636708d43777f1f922b - RNDeviceInfo: 55264dd7cc939dad6e9c231a7621311f5277f1dc - RNDominantColor: 7c17c31201566a592ba4b2fbe2bb7e00df468753 - RNFBApp: 5c187f161ac2b1c258c9c099d56bf5cfdb1f0bcb - RNFBAppCheck: 94c8ce0a972880b3dd1563a01e0ba3245126a9a9 - RNFBMessaging: cb53c6f68f35949983ecb768589bb1c4771bea04 - RNFlashList: 30b68f572400383347ce7df3777985af0d089624 - RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 - RNGestureHandler: ccf4105b125002bd88e39d2a1f2b7e6001bcdf34 - RNGoogleSignin: 63192b9a15ec94c1fc4b0f55fba984a1d7af4ee7 - RNInAppBrowser: e36d6935517101ccba0e875bac8ad7b0cb655364 - RNKeychain: 16921786da69b6001ad2e65781b76f7af372bb10 - RNLocalize: 87712a038fae12e3ac03035ab5f0e35670a17cc3 - RNNotifee: 4a6ee5c7deaf00e005050052d73ee6315dff7ec9 - RNOS: 6f2f9a70895bbbfbdad7196abd952e7b01d45027 - RNPermissions: 5e9311c8050e355546083e45cd0b265ccbdc2a74 - RNReanimated: 6a437c90e263e4a2202a282f9d6dea0ad28d018d - RNScreens: c2e3cc506212228c607b4785b315205e28acbf0f - RNSensors: 117ba71c7eeeea0407ea0c0bb79e3495d602049b - RNSentry: a1c2583797dd0e7d154e34a47021ebc8bf9d5a06 - RNShare: c57877c95b51671130e531065ed8e9396dd2669f - RNSound: 99655e437691f6357ffdd8a45f7a3b7aae27624f - RNSVG: ee32efbed652c5151fd3f98bed13c68af285bc38 + React-utils: 525f1fe996874cff32a0ef8e523e31ebde23664d + ReactAppDependencyProvider: f3e842e6cb5a825b6918a74a38402ba1409411f8 + ReactCodegen: 6cb6e0d0b52471abc883541c76589d1c367c64c7 + ReactCommon: 1ab5451fc5da87c4cc4c3046e19a8054624ca763 + ReactNativePerformance: fa4952a58739e1a1f6b90a4e9777657d463499a3 + RNAppleAuthentication: 8d313d93fe2238d6b7ff0a39c67ebcf298d96653 + RNArgon2: 708e188b7a4d4ec8baf62463927c47abef453a94 + RNBootSplash: 295996a51f49baf0dff9f65e49b32ff93fbc7357 + RNCAsyncStorage: 39c42c1e478e1f5166d1db52b5055e090e85ad66 + RNCClipboard: b80e7bdccb8d432ab1c40189920e7af3116e074c + RNCMaskedView: ae521efb1c6c2b183ae0f8479487db03c826184c + RNDateTimePicker: a4ad049fdd568755003c479beac3bdea742ac4d0 + RNDeviceInfo: ae4e1a9b955b2a65314588cc7251795631925668 + RNDominantColor: 911de09d58e331bc8f84f22bf393e47d3cf8ca79 + RNFBApp: 33938c8ee95629bda8a14eda579e555a101212dd + RNFBAppCheck: 9135ee6833548d2dbd2cbda7e15d0d61bcedbe3c + RNFBMessaging: 1ea695eb9644bbb7aef5c459784f244af2b01cce + RNFlashList: 7ad51f0d0d51a3b7b1d1bb07947b927cb352afc4 + RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8 + RNGestureHandler: 7d0931a61d7ba0259f32db0ba7d0963c3ed15d2b + RNGoogleSignin: 2183722f55abd5b206d02e2edc146bec91fe5610 + RNInAppBrowser: 6d3eb68d471b9834335c664704719b8be1bfdb20 + RNKeychain: 943b4dbceef4b3a310c9122c99d1e5b0bd66b9f3 + RNLocalize: 83eda9ba7fd1cd23310dfd14e61ce5f091f888fb + RNNotifee: 5e3b271e8ea7456a36eec994085543c9adca9168 + RNOS: d07e5090b5060c6f2b83116d740a32cfdb33afe3 + RNPermissions: 4891cd00483fc6902cb92f61bd850e43badde94a + RNReanimated: 722d67dfde539bfe29b572878f4bc805f727726b + RNScreens: 482e9707f9826230810c92e765751af53826d509 + RNSensors: 111159597ac51505df10413c61b28bcd28e88983 + RNSentry: 3bc708566b3390947b6ecd785645398cd1a0049e + RNShare: 43faaefd287ef344e8379caeaca12d112f713295 + RNSound: 72c4886fb80b8a0e8c40131099223e09422aa8b4 + RNSVG: 794f269526df9ddc1f79b3d1a202b619df0368e3 SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3 SDWebImageAVIFCoder: 00310d246aab3232ce77f1d8f0076f8c4b021d90 SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c @@ -4025,4 +4025,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: ed1745b5dff04eddc5b671b6717bc6f6257e9f58 -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 From b35a364c73c37fb88c8ae5c581dcdaef07bc089c Mon Sep 17 00:00:00 2001 From: Charon-Fan Date: Wed, 3 Sep 2025 14:16:17 +0800 Subject: [PATCH 21/25] feat: update wallet removal logic to include Keystone wallets --- .../core-mobile/app/new/common/hooks/useManageWallet.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/core-mobile/app/new/common/hooks/useManageWallet.ts b/packages/core-mobile/app/new/common/hooks/useManageWallet.ts index 14ad2b115a..3499991689 100644 --- a/packages/core-mobile/app/new/common/hooks/useManageWallet.ts +++ b/packages/core-mobile/app/new/common/hooks/useManageWallet.ts @@ -125,9 +125,12 @@ export const useManageWallet = (): { // 1. Seedless wallets cannot be removed if (wallet.type === WalletType.SEEDLESS) return false - // 2. Mnemonic wallets can be removed if there are multiple mnemonic or seedless wallets + // 2. Mnemonic wallets can be removed if there are multiple mnemonic/seedless/keystone wallets const walletCount = Object.values(wallets).filter( - w => w.type === WalletType.MNEMONIC || w.type === WalletType.SEEDLESS + w => + w.type === WalletType.MNEMONIC || + w.type === WalletType.SEEDLESS || + w.type === WalletType.KEYSTONE ).length const isLastRemovableMnemonic = From 6f4724b395a9edfe0e9a5592fd05c5e755d10d76 Mon Sep 17 00:00:00 2001 From: Charon-Fan Date: Wed, 3 Sep 2025 14:17:49 +0800 Subject: [PATCH 22/25] feat: allow removal of Keystone wallets in wallet management --- packages/core-mobile/app/new/common/hooks/useManageWallet.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core-mobile/app/new/common/hooks/useManageWallet.ts b/packages/core-mobile/app/new/common/hooks/useManageWallet.ts index 3499991689..438027300c 100644 --- a/packages/core-mobile/app/new/common/hooks/useManageWallet.ts +++ b/packages/core-mobile/app/new/common/hooks/useManageWallet.ts @@ -134,7 +134,9 @@ export const useManageWallet = (): { ).length const isLastRemovableMnemonic = - walletCount === 1 && wallet.type === WalletType.MNEMONIC + walletCount === 1 && + (wallet.type === WalletType.MNEMONIC || + wallet.type === WalletType.KEYSTONE) return !isLastRemovableMnemonic }, From 2419efdbe47984430e21eaf931d14b403d9ed44c Mon Sep 17 00:00:00 2001 From: Charon-Fan Date: Tue, 16 Sep 2025 22:24:27 +0800 Subject: [PATCH 23/25] fix: fix lock file --- packages/core-mobile/ios/Podfile.lock | 16 +- yarn.lock | 229 +++++++++----------------- 2 files changed, 89 insertions(+), 156 deletions(-) diff --git a/packages/core-mobile/ios/Podfile.lock b/packages/core-mobile/ios/Podfile.lock index 74198c43d4..4bdcd6e82d 100644 --- a/packages/core-mobile/ios/Podfile.lock +++ b/packages/core-mobile/ios/Podfile.lock @@ -1974,7 +1974,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-keyboard-controller (1.18.2): + - react-native-keyboard-controller (1.18.6): - DoubleConversion - glog - hermes-engine @@ -1989,7 +1989,7 @@ PODS: - React-hermes - React-ImageManager - React-jsi - - react-native-keyboard-controller/common (= 1.18.2) + - react-native-keyboard-controller/common (= 1.18.6) - React-NativeModulesApple - React-RCTFabric - React-renderercss @@ -1999,7 +1999,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-keyboard-controller/common (1.18.2): + - react-native-keyboard-controller/common (1.18.6): - DoubleConversion - glog - hermes-engine @@ -3123,7 +3123,7 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - RNScreens (4.11.1): + - RNScreens (4.15.4): - DoubleConversion - glog - hermes-engine @@ -3147,9 +3147,9 @@ PODS: - ReactCodegen - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - - RNScreens/common (= 4.11.1) + - RNScreens/common (= 4.15.4) - Yoga - - RNScreens/common (4.11.1): + - RNScreens/common (4.15.4): - DoubleConversion - glog - hermes-engine @@ -3938,7 +3938,7 @@ SPEC CHECKSUMS: react-native-get-random-values: d16467cf726c618e9c7a8c3c39c31faa2244bbba react-native-ios-context-menu: 58804cdc253f80878284abe55ac5a050d4cde96a react-native-ios-utilities: b3cf760d44fcc8220fdc0fe832beec7453483962 - react-native-keyboard-controller: 6639909c537996e456f3cc8dcfdda3a0cbcd6fc8 + react-native-keyboard-controller: 16d80dc94f13d201ae48530023940260fc63eb0a react-native-menu: be9bce4eb201a4d13734744763d36d56e6df8b4a react-native-mmkv: d3cc73d2554fafa20dc5b86386359034d1faf8ff react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187 @@ -4008,7 +4008,7 @@ SPEC CHECKSUMS: RNOS: d07e5090b5060c6f2b83116d740a32cfdb33afe3 RNPermissions: 4891cd00483fc6902cb92f61bd850e43badde94a RNReanimated: 722d67dfde539bfe29b572878f4bc805f727726b - RNScreens: 482e9707f9826230810c92e765751af53826d509 + RNScreens: f0678748c5310b49a3f920f1485f5ec477afd345 RNSensors: 111159597ac51505df10413c61b28bcd28e88983 RNSentry: 3bc708566b3390947b6ecd785645398cd1a0049e RNShare: 43faaefd287ef344e8379caeaca12d112f713295 diff --git a/yarn.lock b/yarn.lock index 7f31cd2a6c..0d66fda39a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -60,9 +60,9 @@ __metadata: languageName: node linkType: hard -"@avalabs/avalanche-module@npm:1.9.10": - version: 1.9.10 - resolution: "@avalabs/avalanche-module@npm:1.9.10" +"@avalabs/avalanche-module@npm:1.9.12": + version: 1.9.12 + resolution: "@avalabs/avalanche-module@npm:1.9.12" dependencies: "@avalabs/avalanchejs": 5.1.0-alpha.2 "@avalabs/core-chains-sdk": 3.1.0-alpha.58 @@ -72,12 +72,12 @@ __metadata: "@avalabs/core-wallets-sdk": 3.1.0-alpha.58 "@avalabs/glacier-sdk": 3.1.0-alpha.58 "@avalabs/types": 3.1.0-alpha.58 - "@avalabs/vm-module-types": 1.9.10 + "@avalabs/vm-module-types": 1.9.12 "@metamask/rpc-errors": 6.3.0 big.js: 6.2.1 bn.js: 5.2.1 zod: 3.23.8 - checksum: b6d7dc10c9f2dbd2b3f33712e414409693aef450fc635b23695cef6abcb60d7d198289e9c06054d7eb2ecd12cf9947a97cc14076092167637fdb273a061a1089 + checksum: c67117bf5bef5e559ba7a2369c59bfbc4b95a49e07c5893dbe5e939550e520675b5d92c18150a04c97d253f86da03b3e4b9a7bb721cf6eb1b05e34688a71b043 languageName: node linkType: hard @@ -94,20 +94,20 @@ __metadata: languageName: node linkType: hard -"@avalabs/bitcoin-module@npm:1.9.10": - version: 1.9.10 - resolution: "@avalabs/bitcoin-module@npm:1.9.10" +"@avalabs/bitcoin-module@npm:1.9.12": + version: 1.9.12 + resolution: "@avalabs/bitcoin-module@npm:1.9.12" dependencies: "@avalabs/core-coingecko-sdk": 3.1.0-alpha.58 "@avalabs/core-utils-sdk": 3.1.0-alpha.58 "@avalabs/core-wallets-sdk": 3.1.0-alpha.58 - "@avalabs/vm-module-types": 1.9.10 + "@avalabs/vm-module-types": 1.9.12 "@metamask/rpc-errors": 6.3.0 big.js: 6.2.1 bitcoinjs-lib: 5.2.0 bn.js: 5.2.1 zod: 3.23.8 - checksum: e1ebda5542a7b90f5e61156c911ee055116bf595b24385e8031dad5221c9f7905d9730cec11c3c9a09be4b6096ac3cfbb92f0f3fd25305ed064a8bf432fee67b + checksum: b0707fe530c335a229f0c0ee412789d0b75559fa67cb9995b23445ce8b23f148a46f2cdd260468d68fdb5dcd4bc255879eeafeffdc0640b666b3f7cf6bad518d languageName: node linkType: hard @@ -185,9 +185,9 @@ __metadata: version: 0.0.0-use.local resolution: "@avalabs/core-mobile@workspace:packages/core-mobile" dependencies: - "@avalabs/avalanche-module": 1.9.10 + "@avalabs/avalanche-module": 1.9.12 "@avalabs/avalanchejs": 5.1.0-alpha.2 - "@avalabs/bitcoin-module": 1.9.10 + "@avalabs/bitcoin-module": 1.9.12 "@avalabs/bridge-unified": 4.0.3 "@avalabs/core-bridge-sdk": 3.1.0-alpha.58 "@avalabs/core-chains-sdk": 3.1.0-alpha.58 @@ -195,13 +195,13 @@ __metadata: "@avalabs/core-gasless-sdk": 3.1.0-alpha.58 "@avalabs/core-utils-sdk": 3.1.0-alpha.58 "@avalabs/core-wallets-sdk": 3.1.0-alpha.58 - "@avalabs/evm-module": 1.9.10 + "@avalabs/evm-module": 1.9.12 "@avalabs/glacier-sdk": 3.1.0-alpha.58 "@avalabs/k2-alpine": "workspace:*" - "@avalabs/svm-module": 1.9.10 + "@avalabs/svm-module": 1.9.12 "@avalabs/tsconfig-mobile": "workspace:*" "@avalabs/types": 3.1.0-alpha.58 - "@avalabs/vm-module-types": 1.9.10 + "@avalabs/vm-module-types": 1.9.12 "@babel/core": 7.28.0 "@babel/plugin-proposal-nullish-coalescing-operator": 7.18.6 "@babel/plugin-syntax-object-rest-spread": 7.8.3 @@ -212,7 +212,7 @@ __metadata: "@babel/preset-typescript": 7.25.7 "@babel/runtime": 7.25.7 "@bitcoinerlab/secp256k1": 1.2.0 - "@blockaid/client": 0.27.4 + "@blockaid/client": 0.48.0 "@bottom-tabs/react-navigation": 0.10.1 "@coinbase/cbpay-js": 2.2.1 "@config-plugins/detox": 9.0.0 @@ -264,12 +264,10 @@ __metadata: "@react-native/eslint-config": 0.79.5 "@react-native/metro-config": 0.79.5 "@react-native/typescript-config": 0.79.5 - "@react-navigation/bottom-tabs": 7.4.6 - "@react-navigation/drawer": 7.5.5 + "@react-navigation/bottom-tabs": 7.4.7 "@react-navigation/elements": 2.6.3 "@react-navigation/native": 7.1.16 "@react-navigation/native-stack": 7.3.25 - "@react-navigation/stack": 7.1.2 "@reduxjs/toolkit": 1.8.1 "@reown/walletkit": 1.0.0 "@rushstack/eslint-patch": 1.10.4 @@ -309,7 +307,7 @@ __metadata: "@welldone-software/why-did-you-render": 8.0.3 "@zodios/core": 10.9.6 assert: 2.1.0 - axios: 1.7.7 + axios: 1.12.0 babel-jest: 29.7.0 babel-loader: 9.2.1 babel-plugin-inline-dotenv: 1.7.0 @@ -398,7 +396,7 @@ __metadata: react-native-inappbrowser-reborn: 3.7.0 react-native-ios-context-menu: 3.1.0 react-native-ios-utilities: 5.1.2 - react-native-keyboard-controller: 1.18.2 + react-native-keyboard-controller: 1.18.6 react-native-keychain: 10.0.0 react-native-level-fs: 3.0.1 react-native-localize: 3.2.1 @@ -420,7 +418,7 @@ __metadata: react-native-restart: 0.0.27 react-native-root-siblings: 5.0.1 react-native-safe-area-context: 5.5.2 - react-native-screens: 4.11.1 + react-native-screens: 4.15.4 react-native-sensors: 7.3.6 react-native-share: 12.0.9 react-native-sound: 0.12.0 @@ -515,9 +513,9 @@ __metadata: languageName: node linkType: hard -"@avalabs/evm-module@npm:1.9.10": - version: 1.9.10 - resolution: "@avalabs/evm-module@npm:1.9.10" +"@avalabs/evm-module@npm:1.9.12": + version: 1.9.12 + resolution: "@avalabs/evm-module@npm:1.9.12" dependencies: "@avalabs/core-chains-sdk": 3.1.0-alpha.58 "@avalabs/core-coingecko-sdk": 3.1.0-alpha.58 @@ -526,8 +524,8 @@ __metadata: "@avalabs/core-wallets-sdk": 3.1.0-alpha.58 "@avalabs/glacier-sdk": 3.1.0-alpha.58 "@avalabs/types": 3.1.0-alpha.58 - "@avalabs/vm-module-types": 1.9.10 - "@blockaid/client": 0.36.0 + "@avalabs/vm-module-types": 1.9.12 + "@blockaid/client": 0.48.0 "@metamask/rpc-errors": 6.3.0 "@openzeppelin/contracts": 4.9.6 bn.js: 5.2.1 @@ -536,7 +534,7 @@ __metadata: zod: 3.23.8 peerDependencies: ethers: 6.13.5 - checksum: ffcdb2884661948ee77fb5763e5063fa03582be00d31001bc2ca4e3cd100d57f7f9eb7d9d3081dd719e0e195c701c872aa802f7f745a66e4e2c665645b26a2d3 + checksum: c8eee1fe90daa051845eb946a351eecd716b6adbd1b189e04bff7c5ce84a832d65669caea5721d2e0d5b91639e8840abb14a796bedeca9ee600a9cf6dcea57a6 languageName: node linkType: hard @@ -685,15 +683,15 @@ __metadata: languageName: unknown linkType: soft -"@avalabs/svm-module@npm:1.9.10": - version: 1.9.10 - resolution: "@avalabs/svm-module@npm:1.9.10" +"@avalabs/svm-module@npm:1.9.12": + version: 1.9.12 + resolution: "@avalabs/svm-module@npm:1.9.12" dependencies: "@avalabs/core-chains-sdk": 3.1.0-alpha.58 "@avalabs/core-coingecko-sdk": 3.1.0-alpha.58 "@avalabs/core-utils-sdk": 3.1.0-alpha.58 "@avalabs/core-wallets-sdk": 3.1.0-alpha.58 - "@avalabs/vm-module-types": 1.9.10 + "@avalabs/vm-module-types": 1.9.12 "@blockaid/client": 0.48.0 "@metamask/rpc-errors": 6.3.0 "@scure/base": 1.2.4 @@ -704,7 +702,7 @@ __metadata: "@wallet-standard/base": 1.1.0 "@wallet-standard/features": 1.1.0 zod: 3.23.8 - checksum: e972b05aa72ae184b20c4320af895a7b0509bea125a5a06b0aece8f85f98c65af7ae6a13adcdf5e01eb29fef3bf2901ed5cabe12c0e15c9100edcd9345a25e97 + checksum: 4653668282ea673d41b928af02cdc9c0c260eeaaea7478c19ba17b1aedd553ebaba653261cfabd3c62a15eb00f26fe0db5471e644ad43afd898ac842e2397596 languageName: node linkType: hard @@ -721,19 +719,20 @@ __metadata: languageName: node linkType: hard -"@avalabs/vm-module-types@npm:1.9.10": - version: 1.9.10 - resolution: "@avalabs/vm-module-types@npm:1.9.10" +"@avalabs/vm-module-types@npm:1.9.12": + version: 1.9.12 + resolution: "@avalabs/vm-module-types@npm:1.9.12" dependencies: "@avalabs/core-wallets-sdk": 3.1.0-alpha.58 "@avalabs/glacier-sdk": 3.1.0-alpha.58 + "@blockaid/client": 0.48.0 "@metamask/rpc-errors": 6.3.0 bitcoinjs-lib: 5.2.0 hypersdk-client: 0.4.16 zod: 3.23.8 peerDependencies: ethers: 6.13.5 - checksum: 7b3d9525bb135ec0380696795b96fa4016c827f403b025ceaba8c76b6350ff1fd2940e8a256b1b9ab8ab0b2b395b69d6942a8b9d6715141ee975c8ee6763ba28 + checksum: a247c83f9501897c9a83551e5a8142ef82158775f2c93849ecdb27d09263255716c3d120516662460db891a90c739a79131a709f2df4a52f8c8fc391a044153e languageName: node linkType: hard @@ -4205,36 +4204,6 @@ __metadata: languageName: node linkType: hard -"@blockaid/client@npm:0.27.4": - version: 0.27.4 - resolution: "@blockaid/client@npm:0.27.4" - dependencies: - "@types/node": ^18.11.18 - "@types/node-fetch": ^2.6.4 - abort-controller: ^3.0.0 - agentkeepalive: ^4.2.1 - form-data-encoder: 1.7.2 - formdata-node: ^4.3.2 - node-fetch: ^2.6.7 - checksum: c89fe4467fe77e9bcac401f7ddb30c646e86000d5e4913ba6e11560c349fde71ad200551c4ec277fd6e3aad0d9f11cf137194e9568472eb78a2c0617d6011136 - languageName: node - linkType: hard - -"@blockaid/client@npm:0.36.0": - version: 0.36.0 - resolution: "@blockaid/client@npm:0.36.0" - dependencies: - "@types/node": ^18.11.18 - "@types/node-fetch": ^2.6.4 - abort-controller: ^3.0.0 - agentkeepalive: ^4.2.1 - form-data-encoder: 1.7.2 - formdata-node: ^4.3.2 - node-fetch: ^2.6.7 - checksum: 7d3468822bc7248fdddf1d98e1b30f478b031589896fd9dade0d4e00a54d664a5314c25355687d0cdbae47be01ec2746e55300f7b4db8fcbfc69cb04d2d424c3 - languageName: node - linkType: hard - "@blockaid/client@npm:0.48.0": version: 0.48.0 resolution: "@blockaid/client@npm:0.48.0" @@ -9995,11 +9964,11 @@ __metadata: languageName: node linkType: hard -"@react-navigation/bottom-tabs@npm:7.4.6": - version: 7.4.6 - resolution: "@react-navigation/bottom-tabs@npm:7.4.6" +"@react-navigation/bottom-tabs@npm:7.4.7": + version: 7.4.7 + resolution: "@react-navigation/bottom-tabs@npm:7.4.7" dependencies: - "@react-navigation/elements": ^2.6.3 + "@react-navigation/elements": ^2.6.4 color: ^4.2.3 peerDependencies: "@react-navigation/native": ^7.1.17 @@ -10007,7 +9976,7 @@ __metadata: react-native: "*" react-native-safe-area-context: ">= 4.0.0" react-native-screens: ">= 4.0.0" - checksum: 42f6bf8d043a227c2c5cca8e68fd7b6d3870bef269d415a09003fae210b8e53eab1f80fe013c401e2ccb48d360e3afb8cff72642e8c5f952f1aea433300a783c + checksum: 9ff291b086b00d4f656d67fd29b084c7d801c68e8db41c3b18192076d9593e6d4c9d4d28d1bde12be71c0499b6af83331cbe348549c15ff5fa5f8daf42c6bae3 languageName: node linkType: hard @@ -10044,26 +10013,6 @@ __metadata: languageName: node linkType: hard -"@react-navigation/drawer@npm:7.5.5": - version: 7.5.5 - resolution: "@react-navigation/drawer@npm:7.5.5" - dependencies: - "@react-navigation/elements": ^2.6.1 - color: ^4.2.3 - react-native-drawer-layout: ^4.1.12 - use-latest-callback: ^0.2.4 - peerDependencies: - "@react-navigation/native": ^7.1.16 - react: ">= 18.2.0" - react-native: "*" - react-native-gesture-handler: ">= 2.0.0" - react-native-reanimated: ">= 2.0.0" - react-native-safe-area-context: ">= 4.0.0" - react-native-screens: ">= 4.0.0" - checksum: 3acbf6e44edeabf51425c84c75d07620c802b5cdf816abe5cbafae849be82d6e481accec88374dc2c05b369f3c831d9a7094b7921c5533026422342497d5e730 - languageName: node - linkType: hard - "@react-navigation/elements@npm:2.6.3, @react-navigation/elements@npm:^2.6.3": version: 2.6.3 resolution: "@react-navigation/elements@npm:2.6.3" @@ -10084,41 +10033,43 @@ __metadata: languageName: node linkType: hard -"@react-navigation/elements@npm:^2.2.6": - version: 2.2.6 - resolution: "@react-navigation/elements@npm:2.2.6" +"@react-navigation/elements@npm:^2.6.1": + version: 2.6.1 + resolution: "@react-navigation/elements@npm:2.6.1" dependencies: color: ^4.2.3 + use-latest-callback: ^0.2.4 + use-sync-external-store: ^1.5.0 peerDependencies: "@react-native-masked-view/masked-view": ">= 0.2.0" - "@react-navigation/native": ^7.0.15 + "@react-navigation/native": ^7.1.16 react: ">= 18.2.0" react-native: "*" react-native-safe-area-context: ">= 4.0.0" peerDependenciesMeta: "@react-native-masked-view/masked-view": optional: true - checksum: 4979be0fb72ae667f34c7f6a665ac366f29d8bebf50a4e0919b9f0aa74c1ac13a913ca1fd474f5fa829109c041bea2befaf682adf5a91ca09474dbd7b0b9edc1 + checksum: 4613f01b8fca9a23a97be9b4bb6176d8206f2ab1fff1686920b961b62a054f712b9c26ed119737c7c3be8536b24e8ca00e63b069818010b2b03303eea34f7fe4 languageName: node linkType: hard -"@react-navigation/elements@npm:^2.6.1": - version: 2.6.1 - resolution: "@react-navigation/elements@npm:2.6.1" +"@react-navigation/elements@npm:^2.6.4": + version: 2.6.4 + resolution: "@react-navigation/elements@npm:2.6.4" dependencies: color: ^4.2.3 use-latest-callback: ^0.2.4 use-sync-external-store: ^1.5.0 peerDependencies: "@react-native-masked-view/masked-view": ">= 0.2.0" - "@react-navigation/native": ^7.1.16 + "@react-navigation/native": ^7.1.17 react: ">= 18.2.0" react-native: "*" react-native-safe-area-context: ">= 4.0.0" peerDependenciesMeta: "@react-native-masked-view/masked-view": optional: true - checksum: 4613f01b8fca9a23a97be9b4bb6176d8206f2ab1fff1686920b961b62a054f712b9c26ed119737c7c3be8536b24e8ca00e63b069818010b2b03303eea34f7fe4 + checksum: 5ebcf77ca85755efbc35983a32caf6f82371bd8ca7ba705deb4317c250a9a9c1898765d02fe2373adfb2aae852666ac54f07b9185bf1a91fbfe185920ac9c46d languageName: node linkType: hard @@ -10179,23 +10130,6 @@ __metadata: languageName: node linkType: hard -"@react-navigation/stack@npm:7.1.2": - version: 7.1.2 - resolution: "@react-navigation/stack@npm:7.1.2" - dependencies: - "@react-navigation/elements": ^2.2.6 - color: ^4.2.3 - peerDependencies: - "@react-navigation/native": ^7.0.15 - react: ">= 18.2.0" - react-native: "*" - react-native-gesture-handler: ">= 2.0.0" - react-native-safe-area-context: ">= 4.0.0" - react-native-screens: ">= 4.0.0" - checksum: 8ee3e52c22b393a162815df623ba4ea0b50d0ceac2f121473df472c843834ef5699eff851d44140c9fcdbab79525f33b4eaa5137c4cc38d2d5bdff4802706162 - languageName: node - linkType: hard - "@reduxjs/toolkit@npm:1.8.1": version: 1.8.1 resolution: "@reduxjs/toolkit@npm:1.8.1" @@ -14615,14 +14549,14 @@ __metadata: languageName: node linkType: hard -"axios@npm:1.7.7": - version: 1.7.7 - resolution: "axios@npm:1.7.7" +"axios@npm:1.12.0": + version: 1.12.0 + resolution: "axios@npm:1.12.0" dependencies: follow-redirects: ^1.15.6 - form-data: ^4.0.0 + form-data: ^4.0.4 proxy-from-env: ^1.1.0 - checksum: 882d4fe0ec694a07c7f5c1f68205eb6dc5a62aecdb632cc7a4a3d0985188ce3030e0b277e1a8260ac3f194d314ae342117660a151fabffdc5081ca0b5a8b47fe + checksum: f2a109efea16711907ae86acc46434d52da28e889bf1d2fc2b66844e82c9908f6d96d988ad9043b37d4146abc182e67d61abd87367152bbbc1cd73afa3c5de71 languageName: node linkType: hard @@ -20226,6 +20160,19 @@ __metadata: languageName: node linkType: hard +"form-data@npm:^4.0.4": + version: 4.0.4 + resolution: "form-data@npm:4.0.4" + dependencies: + asynckit: ^0.4.0 + combined-stream: ^1.0.8 + es-set-tostringtag: ^2.1.0 + hasown: ^2.0.2 + mime-types: ^2.1.12 + checksum: 9b7788836df9fa5a6999e0c02515b001946b2a868cfe53f026c69e2c537a2ff9fbfb8e9d2b678744628f3dc7a2d6e14e4e45dfaf68aa6239727f0bdb8ce0abf2 + languageName: node + linkType: hard + "formdata-node@npm:^4.3.2": version: 4.4.1 resolution: "formdata-node@npm:4.4.1" @@ -27566,20 +27513,6 @@ __metadata: languageName: node linkType: hard -"react-native-drawer-layout@npm:^4.1.12": - version: 4.1.12 - resolution: "react-native-drawer-layout@npm:4.1.12" - dependencies: - use-latest-callback: ^0.2.4 - peerDependencies: - react: ">= 18.2.0" - react-native: "*" - react-native-gesture-handler: ">= 2.0.0" - react-native-reanimated: ">= 2.0.0" - checksum: fd61fec9663e03caf3ac2a7a4cf031c6944f3841fb8af9dcd8c0a4dbe29c50cc869625b0648c85c36c76685b527a78f85efb37b2ddc0d1307bd56d6eddc8eec4 - languageName: node - linkType: hard - "react-native-edge-to-edge@npm:1.6.0": version: 1.6.0 resolution: "react-native-edge-to-edge@npm:1.6.0" @@ -27711,7 +27644,7 @@ __metadata: languageName: node linkType: hard -"react-native-is-edge-to-edge@npm:^1.1.7, react-native-is-edge-to-edge@npm:^1.2.1": +"react-native-is-edge-to-edge@npm:^1.2.1": version: 1.2.1 resolution: "react-native-is-edge-to-edge@npm:1.2.1" peerDependencies: @@ -27721,16 +27654,16 @@ __metadata: languageName: node linkType: hard -"react-native-keyboard-controller@npm:1.18.2": - version: 1.18.2 - resolution: "react-native-keyboard-controller@npm:1.18.2" +"react-native-keyboard-controller@npm:1.18.6": + version: 1.18.6 + resolution: "react-native-keyboard-controller@npm:1.18.6" dependencies: react-native-is-edge-to-edge: ^1.2.1 peerDependencies: react: "*" react-native: "*" react-native-reanimated: ">=3.0.0" - checksum: 2d1fb8a43d70d172196d77acc7481d063592691fb26168bda4b75138055db7cf58872f7dafd631bb00b6311edbf9d424a69c4b401257c9f9f549646711a34a03 + checksum: 3de794b78c115a2c3ce2b7dac5971c04a3cde6be43dd38065522ce0e987eff8a76bda226bad6c0bfa19ace9b64e19a9001f3c7a4e7cf8fa57906573d9ab19674 languageName: node linkType: hard @@ -28034,17 +27967,17 @@ __metadata: languageName: node linkType: hard -"react-native-screens@npm:4.11.1": - version: 4.11.1 - resolution: "react-native-screens@npm:4.11.1" +"react-native-screens@npm:4.15.4": + version: 4.15.4 + resolution: "react-native-screens@npm:4.15.4" dependencies: react-freeze: ^1.0.0 - react-native-is-edge-to-edge: ^1.1.7 + react-native-is-edge-to-edge: ^1.2.1 warn-once: ^0.1.0 peerDependencies: react: "*" react-native: "*" - checksum: 22d3c302ef90a1cb20eed8c130b32e53d49288a19eba844f506a5e38342ef2add0d4f7a2ff5501cc05052aef6bf7f180db26a067b01f70f3cc12d3e1497329d6 + checksum: e0e5fbfcb77f0cd1b5358faa09b46661ef26fbcfa191ac49019967f2068feccf7cd3fa83e8dd7d52207443cd5f6263831440c365ba276fbb97def596a77626bb languageName: node linkType: hard From 0b428f68201fe2e3c13435eb341e3ed87f113dde Mon Sep 17 00:00:00 2001 From: Charon-Fan Date: Wed, 17 Sep 2025 17:04:32 +0800 Subject: [PATCH 24/25] fix: bug fix --- package.json | 10 +- .../(modals)/keystoneSigner/_layout.tsx | 8 +- .../keystoneTroubleshooting/_layout.tsx | 8 +- .../app/new/routes/(signedIn)/_layout.tsx | 4 +- .../core-mobile/app/store/posthog/slice.ts | 13 + packages/core-mobile/ios/Podfile.lock | 256 +++++++++--------- yarn.lock | 6 - 7 files changed, 154 insertions(+), 151 deletions(-) diff --git a/package.json b/package.json index ba7f060835..c782e791f0 100644 --- a/package.json +++ b/package.json @@ -57,13 +57,5 @@ "node": ">=20.18.0", "yarn": ">=3.6.4" }, - "packageManager": "yarn@3.6.4", - "dependencies": { - "@ethereumjs/util": "9.1.0", - "@keystonehq/animated-qr": "0.10.0", - "@keystonehq/keystone-sdk": "0.11.3", - "@ngraveio/bc-ur": "1.1.13", - "react-native-popover-view": "6.1.0", - "react-native-progress": "5.0.1" - } + "packageManager": "yarn@3.6.4" } diff --git a/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneSigner/_layout.tsx b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneSigner/_layout.tsx index 4a96eda371..9c6eeae247 100644 --- a/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneSigner/_layout.tsx +++ b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneSigner/_layout.tsx @@ -1,9 +1,11 @@ import React from 'react' import { Stack } from 'common/components/Stack' -import { useModalScreenOptions } from 'common/hooks/useModalScreenOptions' +import { + modalFirstScreenOptions, + modalStackNavigatorScreenOptions +} from 'common/consts/screenOptions' + export default function KeystoneSignerLayout(): JSX.Element { - const { modalStackNavigatorScreenOptions, modalFirstScreenOptions } = - useModalScreenOptions() return ( diff --git a/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneTroubleshooting/_layout.tsx b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneTroubleshooting/_layout.tsx index 4a96eda371..9c6eeae247 100644 --- a/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneTroubleshooting/_layout.tsx +++ b/packages/core-mobile/app/new/routes/(signedIn)/(modals)/keystoneTroubleshooting/_layout.tsx @@ -1,9 +1,11 @@ import React from 'react' import { Stack } from 'common/components/Stack' -import { useModalScreenOptions } from 'common/hooks/useModalScreenOptions' +import { + modalFirstScreenOptions, + modalStackNavigatorScreenOptions +} from 'common/consts/screenOptions' + export default function KeystoneSignerLayout(): JSX.Element { - const { modalStackNavigatorScreenOptions, modalFirstScreenOptions } = - useModalScreenOptions() return ( diff --git a/packages/core-mobile/app/new/routes/(signedIn)/_layout.tsx b/packages/core-mobile/app/new/routes/(signedIn)/_layout.tsx index 3da23f335e..cf5884e699 100644 --- a/packages/core-mobile/app/new/routes/(signedIn)/_layout.tsx +++ b/packages/core-mobile/app/new/routes/(signedIn)/_layout.tsx @@ -58,11 +58,11 @@ export default function WalletLayout(): JSX.Element { /> { export const selectIsSolanaSupportBlocked = (state: RootState): boolean => { const { featureFlags } = state.posthog + + const activeWallet = selectActiveWallet(state) + if (activeWallet?.type === WalletType.KEYSTONE) { + return true + } + return ( !featureFlags[FeatureGates.SOLANA_SUPPORT] || !featureFlags[FeatureGates.EVERYTHING] @@ -404,6 +411,12 @@ export const selectIsSwapFeesJupiterBlocked = (state: RootState): boolean => { export const selectIsSolanaSwapBlocked = (state: RootState): boolean => { const { featureFlags } = state.posthog + + const activeWallet = selectActiveWallet(state) + if (activeWallet?.type === WalletType.KEYSTONE) { + return true + } + return ( !featureFlags[FeatureGates.SWAP_SOLANA] || !featureFlags[FeatureGates.EVERYTHING] diff --git a/packages/core-mobile/ios/Podfile.lock b/packages/core-mobile/ios/Podfile.lock index 4bdcd6e82d..b999a29147 100644 --- a/packages/core-mobile/ios/Podfile.lock +++ b/packages/core-mobile/ios/Podfile.lock @@ -3839,38 +3839,38 @@ SPEC CHECKSUMS: DatadogInternal: a514ba01c9eb99dbe1ddd4452e218706bb0ddc2b DatadogLogs: 9352c58e4ab4a88f0ed7c20f27dc8d24442acc5e DatadogRUM: ab979c800d3fb7d7b2ff364a11d137b6a4be6831 - DatadogSDKReactNative: ad2a27c00fe2fd3c9f406c78f13d9190ff8dab82 + DatadogSDKReactNative: dc0db8e0608412abaf4b0297637586a8cc0972e5 DatadogTrace: 23df8545911d219d4c15446a4c6c04862ff76175 DatadogWebViewTracking: e88b8057eb5ff06a68baf232ae37637b8bb7518b DGSwiftUtilities: 567f8d5ee618f0b7afb185b17aa45ff356315a0f DoubleConversion: f16ae600a246532c4020132d54af21d0ddb2a385 - EXApplication: 1e06972201838375ca1ec1ba34d586a98a5dc718 - EXConstants: 98bcf0f22b820f9b28f9fee55ff2daededadd2f8 + EXApplication: 50cc8ea58c138da6e3f25cd789634219c86b90d5 + EXConstants: 9d62a46a36eae6d28cb978efcbc68aef354d1704 EXJSONUtils: 1d3e4590438c3ee593684186007028a14b3686cd - EXManifests: 691a779b04e4f2c96da46fb9bef4f86174fefcb5 - Expo: a40d525c930dd1c8a158e082756ee071955baccb - expo-dev-client: 9b1e78baf0dd87b005f035d180bbb07c05917fad - expo-dev-launcher: 35dc0269b5fc1f628abc00e08e5a969e7809eff4 - expo-dev-menu: 0771fa9c5c405e07aa15e55a699b8a4a984ea77a + EXManifests: f4cc4a62ee4f1c8a9cf2bb79d325eac6cb9f5684 + Expo: 666a397fcb608d72b019e16ba139b74e93e0b7d7 + expo-dev-client: f1b99dfea0c9174d2e4ec96c2c5461587dda1e86 + expo-dev-launcher: 27e8eba58d52b2f471b0c4001b0535a1c0b5610d + expo-dev-menu: 2868212810f6651bc5c30e72c636ef64de31ec6b expo-dev-menu-interface: 609c35ae8b97479cdd4c9e23c8cf6adc44beea0e - ExpoAdapterGoogleSignIn: 6393c1ad521f880f6e467bca40baf1e5dcaea4a3 - ExpoAsset: ef06e880126c375f580d4923fdd1cdf4ee6ee7d6 - ExpoBlur: 3c8885b9bf9eef4309041ec87adec48b5f1986a9 - ExpoCamera: e1879906d41184e84b57d7643119f8509414e318 - ExpoFileSystem: 7f92f7be2f5c5ed40a7c9efc8fa30821181d9d63 - ExpoFont: cf508bc2e6b70871e05386d71cab927c8524cc8e - ExpoHaptics: 0ff6e0d83cd891178a306e548da1450249d54500 - ExpoHead: a7b66cbaeeb51f4a85338d335a0f5467e29a2c90 - ExpoImage: f2c9cfd2a4cb918bba7ddbb40da851858f7aece4 - ExpoKeepAwake: bf0811570c8da182bfb879169437d4de298376e7 - ExpoLinearGradient: 7734c8059972fcf691fb4330bcdf3390960a152d - ExpoLinking: d5c183998ca6ada66ff45e407e0f965b398a8902 - ExpoLocalAuthentication: c35f18692dcb35775a1be0f37b2131096951a6bd - ExpoLocalization: 999a1ff61a7f5917d65c2bd9234883009019ca9f - ExpoModulesCore: 00a1b5c73248465bd0b93f59f8538c4573dac579 - ExpoSMS: 770f0b60a777f5d3f65fd7fc369ff62ff97e09a9 - ExpoVideo: ada534976cfd4a6bf082cc61aa1b17920a251e32 - EXUpdatesInterface: 7ff005b7af94ee63fa452ea7bb95d7a8ff40277a + ExpoAdapterGoogleSignIn: da10ae7e7c1d73a10c2facebcdfe5ebea8e073ce + ExpoAsset: 7bdbbacf4e6752ae6e3cf70555cee076f6229e6e + ExpoBlur: 846780b2c90f59e964b9a50385d4deb67174ebfb + ExpoCamera: fc1ab0e1c665b543a307c577df107e37cc2edc8e + ExpoFileSystem: 9681caebda23fa1b38a12a9c68b2bade7072ce20 + ExpoFont: 091a47eeaa1b30b0b760aa1d0a2e7814e8bf6fe6 + ExpoHaptics: 68c215e070f660e0a29c45dcda4f60eeff08aefb + ExpoHead: 7c1893efc8dc79570bdcbdadce175723f4c037ec + ExpoImage: 3099001359e4414d60addd7c3e00a5d949df41e0 + ExpoKeepAwake: e8dedc115d9f6f24b153ccd2d1d8efcdfd68a527 + ExpoLinearGradient: ce334cff9859da4635c1d8eff6e291b11b04ccbb + ExpoLinking: 343a89ea864a851831fd4495e8aea01cf0f6a36f + ExpoLocalAuthentication: 78f74d187ee51126e1a789d73fee32d6d7e60f1f + ExpoLocalization: 677e45c2536bf918119962f78d7ffeeea317e07d + ExpoModulesCore: 16f74d8df26d7e4b6bf7eb3d0effaf0f15df7b80 + ExpoSMS: de195632beeb7ef00556750da10da667596d8967 + ExpoVideo: 84edf8e48b71317fb1d7f17c3d49a310476dc0f4 + EXUpdatesInterface: 64f35449b8ef89ce08cdd8952a4d119b5de6821d fast_float: 06eeec4fe712a76acc9376682e4808b05ce978b6 FBLazyVector: d2a9cd223302b6c9aa4aa34c1a775e9db609eb52 Firebase: 7a56fe4f56b5ab81b86a6822f5b8f909ae6fc7e2 @@ -3889,11 +3889,11 @@ SPEC CHECKSUMS: GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 hermes-engine: f03b0e06d3882d71e67e45b073bb827da1a21aae - jail-monkey: 1846061ac12e861ac5a8ec7197b0daa775b83733 + jail-monkey: a71b35d482a70ecba844a90f002994012cf12a5d libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7 libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f lottie-ios: a881093fab623c467d3bce374367755c272bdd59 - lottie-react-native: 8bc11e10576d1a3f77f4e0ae5b70503c5c890a09 + lottie-react-native: 2ed3839d12e44b5946a901687e9ab00ee9bc3232 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c OpenTelemetrySwiftApi: aaee576ed961e0c348af78df58b61300e95bd104 @@ -3906,114 +3906,114 @@ SPEC CHECKSUMS: React: 6393ae1807614f017a84805bf2417e3497f518a6 React-callinvoker: c34f666f551f05a325b87e7e3e6df0e082fa3d99 React-Codegen: 4b8b4817cea7a54b83851d4c1f91f79aa73de30a - React-Core: 1ba9acdf7accbd46ccaae99999443ae2722c82b7 - React-CoreModules: 3c3cf4a91257f138e3feb47169a2d7fe341b5495 - React-cxxreact: 444d518a5d3a933e029b5e5ca6d8127c2e43255c + React-Core: fc07a4b69a963880b25142c51178f4cb75628c7d + React-CoreModules: 94d39315cfa791f6c477712fea47c34f8ecb26c6 + React-cxxreact: 628c28cdb3fdef93ee3bfc2bec8e2d776e81ae49 React-debug: a951cdb698321d78ebd955fc8788ebbe51af3519 - React-defaultsnativemodule: 35816c7cb315962495d815446b2c8f1f3d2396ad - React-domnativemodule: 94efa04e53aa12a6dc02d420f1564ee18f3059bd - React-Fabric: bb8ccdb10256fa8acfd98a189590e2e44878abd7 - React-FabricComponents: 60703b954ca7e3d09cdb8d6fff6a4118f3c1478f - React-FabricImage: 0a8cc153d20af111f966e14b3814faa692a6805d + React-defaultsnativemodule: 08779733c4541be5da1f1d3ec8492300dbc3c00a + React-domnativemodule: fdd4821b9a0c44e87ed9263231225aa65fe982e0 + React-Fabric: 8d905d8c41d666bf283a5b09db56bdaccfa07c8d + React-FabricComponents: 43aab5c94c7b5bbcabc3a9821b8536a0711a0f01 + React-FabricImage: 10708fa449d3f1b4a8d6eedb97f0c6476b098bb4 React-featureflags: 32d776f9bef34bdab6218ad99db535e75e5c1f4e - React-featureflagsnativemodule: dd5e1e8579d7c3e10b31969c4ca2f56ba3743ec2 - React-graphics: bce95f01799245fa58ca35bdc06a98677b67352e - React-hermes: 9ec11ce5f88c0778e027aa06a6e3e6eb19ddae09 - React-idlecallbacksnativemodule: 9d125d1b9bb3e0bb4de334fea94228e6eeac1852 - React-ImageManager: c40cb4a131371ddecbabc618ef354c57c864c550 - React-jserrorhandler: c00e040f76b32a1846d7eb43602a78ad1e1f60d1 - React-jsi: 8f065aa1ae1d35bef3c394cb1663d114c4952fd8 - React-jsiexecutor: fc8e69fb870cb6e69920fd482a76d4ae54a1c40a - React-jsinspector: 42760714871594f021b3bf223f2f9ac350183ed3 - React-jsinspectortracing: 237f149a09bab785ec6b3a15cc92fc51c0d15cc4 - React-jsitooling: ef1fca866f14d8d4bd80a9570118c19e62775f96 - React-jsitracing: cfa927f650c6f7da613da9fe2a6eeaebc6b2ad1b - React-logger: 85fa3509931497c72ccd2547fcc91e7299d8591e - React-Mapbuffer: 96a2f2a176268581733be182fa6eebab1c0193be - React-microtasksnativemodule: bda561d2648e1e52bd9e5a87f8889836bdbde2e2 - react-native-aes: e2868d9f7203f573a2c1d797d95f4e88a54fa8cd - react-native-bottom-tabs: 05d040c837f04e57e6973d553db5e69c8e279113 - react-native-compat: 4594cac40c688f5ac4984e93f8c8e31496f4e614 - react-native-config: ea75335a7cca1d3326de1da384227e580a7c082e - react-native-get-random-values: d16467cf726c618e9c7a8c3c39c31faa2244bbba - react-native-ios-context-menu: 58804cdc253f80878284abe55ac5a050d4cde96a - react-native-ios-utilities: b3cf760d44fcc8220fdc0fe832beec7453483962 - react-native-keyboard-controller: 16d80dc94f13d201ae48530023940260fc63eb0a - react-native-menu: be9bce4eb201a4d13734744763d36d56e6df8b4a - react-native-mmkv: d3cc73d2554fafa20dc5b86386359034d1faf8ff - react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187 - react-native-pager-view: f238ed7fb53458bd03366944a33686f067c83e9a - react-native-passkey: 3aac247c18127443ef4a002b59d8e12dc7e99f2e - react-native-quick-base64: 651d972291fd5d9902869636a1b3c46820324490 - react-native-quick-crypto: 71b622aa0a231ac068759f5eef37982ad5eae58c - react-native-restart: 0bc732f4461709022a742bb29bcccf6bbc5b4863 - react-native-safe-area-context: 7e926a200d4bc9c56562275743705c6b56176455 - react-native-skia: 5c086469906cf854e26126b5b88dcbb6c93eb90f - react-native-slider: 78ccabe016aef7418b1a846b31115b4165c4dde6 - react-native-theme-control: d5836bcec2a9f3c3d3fd4e38874524b19a1da359 - react-native-view-shot: 57c7b8158751f19f32cb885109574712955ea016 - react-native-webview: 85c8fc8ca09f4e67b68afbc86207a1442af5dc80 - React-NativeModulesApple: 1ecb83880dd11baf2228f8dd89d8419c387e03ad + React-featureflagsnativemodule: 413da7bc0d21aa86315dbea0fb2b2c27cb8b4bab + React-graphics: 83c676b633acc5044b5c5dfdb7f95aa3aaf7b7a5 + React-hermes: af1b3d79491295abc9d1b11f84e77d5dc00095b6 + React-idlecallbacksnativemodule: b039a595f29d9a87bbad12e731de45879a054b33 + React-ImageManager: 81dc38602ff1e7a8fd5fe3bf54772cf1a30d49c1 + React-jserrorhandler: b230f573b63a6a2a5540054d46cfb6087d26c86c + React-jsi: e9c3019e00db5d144e0a660616a52a605e12c39a + React-jsiexecutor: 3ed70a394b76f33e6c4ec4b382a457df7309d96c + React-jsinspector: 977527f0224edb5ae0970e946411f36dd1d70f43 + React-jsinspectortracing: 64ec4bde979134830c8f937758416f8d50daa8fb + React-jsitooling: 9dd45534fd158b508f785b547bf1350933bf465a + React-jsitracing: a645b2b3c4f6aa79051d5485c67b188ef49045a0 + React-logger: e6e6164f1753e46d1b7e2c8f0949cd7937eaf31b + React-Mapbuffer: 5b4959cbd91e7e8fae42ab0f4b7c25b86fd139a1 + React-microtasksnativemodule: 1695ab137281dd03de967b7bbeb4e392601f6432 + react-native-aes: 8e4348c6e75fcb32f5a960e987df877e1062714e + react-native-bottom-tabs: 5f3293a58aa9810ccdbf76d04c87bf52ab661200 + react-native-compat: 8fd509839fcf4e5646b4ff2281912d95bbd66334 + react-native-config: 8f7283449bbb048902f4e764affbbf24504454af + react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06 + react-native-ios-context-menu: f5c2bc565a9a8599bb4513c43835a38e00d73b3a + react-native-ios-utilities: 73c3e0a51544c059f80eecc226a3530609e10c42 + react-native-keyboard-controller: 140bd6036203cf520c811ec7ea67950a6332ff68 + react-native-menu: 8cc212c18ae939db6932e3c3feae9a99a80f0ecb + react-native-mmkv: 2421db62a08da22d1b97ea4d55adfee9ea0f88a1 + react-native-netinfo: f0a9899081c185db1de5bb2fdc1c88c202a059ac + react-native-pager-view: 794f015a4e3b7cfb9ede97c73eae15c0d11a3fbc + react-native-passkey: e0b0f58fa9b33c424bafaa0a93d66fb0e21dc092 + react-native-quick-base64: 2f2d797c2a3a7d49d77bdef41045f9391f3f4c09 + react-native-quick-crypto: e0b1003058f1706acd425c156f494a485d18509e + react-native-restart: 7595693413fe3ca15893702f2c8306c62a708162 + react-native-safe-area-context: 638038e064cdf9747580a2e47717b09be309a321 + react-native-skia: d4b71ff628f69fd8e1b2d0dbd436d6ab6ee8d669 + react-native-slider: c4c1a975352113af59b59dc783abc111618ec37a + react-native-theme-control: ad1dbaa6ac374bccf0100024269cadd44c73aa33 + react-native-view-shot: 41c5c50c809f1fd61f91c99400b2222c9b80d13f + react-native-webview: f23e694e18f05a5340a3432c57b4145d520333db + React-NativeModulesApple: 3ecc647742d33ad617bd2805902e3f91f2b3008f React-oscompat: 0592889a9fcf0eacb205532028e4a364e22907dd - React-perflogger: c584fa50e422a46f37404d083fad12eb289d5de4 - React-performancetimeline: 8deae06fc819e6f7d1f834818e72ab5581540e45 + React-perflogger: 634408a9a0f5753faa577dfa81bc009edca01062 + React-performancetimeline: faa22f963845ae2298c28ef6b84bd8b58d3d8a90 React-RCTActionSheet: ce67bdc050cc1d9ef673c7a93e9799288a183f24 - React-RCTAnimation: 8bb813eb29c6de85be99c62640f3a999df76ba02 - React-RCTAppDelegate: 0200dcd70e996a7061965cfa7f8c443013cc11a1 - React-RCTBlob: a1dd15758420b6a8154019c5c188cf90648bc487 - React-RCTFabric: c7825ff7180893c4213eae8d249b279fc6bf5253 - React-RCTFBReactNativeSpec: b42afeff81dfd0618a4d37c6c6cb99a66b93a363 - React-RCTImage: 8a4f6ce18e73a7e894b886dfb7625e9e9fbc90ef - React-RCTLinking: fa49c624cd63979e7a6295ae9b1351d23ac4395a - React-RCTNetwork: f236fd2897d18522bba24453e2995a4c83e01024 - React-RCTRuntime: 6b9e893b1d375b7a733fe26c8781e8f062f52951 - React-RCTSettings: 69e2f25a5a1bf6cb37eef2e5c3bd4bb7e848296b - React-RCTText: 515ce74ed79c31dbf509e6f12770420ebbf23755 - React-RCTVibration: ef30ada606dfed859b2c71577f6f041d47f2cfbb + React-RCTAnimation: 12193c2092a78012c7f77457806dcc822cc40d2c + React-RCTAppDelegate: 7225b51d5b6d3ddd3702165d717a1ffd4a90fb71 + React-RCTBlob: 923cf9b0098b9a641cb1e454c30a444d9d3cda70 + React-RCTFabric: a280fd9f2697c144b0d835200080a09ab15b2e07 + React-RCTFBReactNativeSpec: 50eabdca1efbf6ce1d774b816a68e6cc4b2a5598 + React-RCTImage: 580a5d0a6fdf9b69629d0582e5fb5a173e152099 + React-RCTLinking: 4ed7c5667709099bfd6b2b6246b1dfd79c89f7cb + React-RCTNetwork: 06a22dd0088392694df4fd098634811aa0b3e166 + React-RCTRuntime: 17c77bab5d39bc354c9983f8f11c7d3597fa8344 + React-RCTSettings: 9dbf433f302c8ebe43b280453e74624098fbc706 + React-RCTText: 92fcd78d6c44dbe64d147bb63f53698bcba7c971 + React-RCTVibration: 513659394c92491e6c749e981424f6e1e0abdb3c React-rendererconsistency: aedf87f8509bc0936ae5475d4ea1e26cb5e8def6 - React-renderercss: 636c2fffff5334897fc7745442c5e450a90eb549 - React-rendererdebug: 9c95cda4ebc6afb3b474924bb185b42ae317c02d + React-renderercss: 71727bedda678e0918506749f94f745e1050a080 + React-rendererdebug: 81a6b97bd089b49a8e7f4f5c7fd1de588c0e8a11 React-rncore: 3eb6f7bdfd181bc26f9f3edc87f70eb1a68a2f3c - React-RuntimeApple: 2cf5c8e38bfccd0e6aa47e3f87a1a3e85ae7fb87 - React-RuntimeCore: 2f87f504ca55b4a2a6bda1ee50c144b33cce0a15 + React-RuntimeApple: 368e8e7b0018f9e9ca4294a6a8167e6aebc6eb87 + React-RuntimeCore: 0f9a8bb41e043f3adaea111e5128801af0dfbc34 React-runtimeexecutor: ebfd71307b3166c73ac0c441c1ea42e0f17f821d - React-RuntimeHermes: a8391605396019d1f72079d3c72e80fcdc79c6a2 - React-runtimescheduler: 158b956675f624b3d3158ffab8f711ebf54fb3a6 + React-RuntimeHermes: 7f55a7285794023ccb3cfe3e89c66c632ed566b1 + React-runtimescheduler: 316243b204bb6a5fd80cea7a97df9b1614ee1b0e React-timing: acc3fa92c72dcc1de6300d752ebb84a1d55dc809 - React-utils: 525f1fe996874cff32a0ef8e523e31ebde23664d - ReactAppDependencyProvider: f3e842e6cb5a825b6918a74a38402ba1409411f8 - ReactCodegen: 6cb6e0d0b52471abc883541c76589d1c367c64c7 - ReactCommon: 1ab5451fc5da87c4cc4c3046e19a8054624ca763 - ReactNativePerformance: fa4952a58739e1a1f6b90a4e9777657d463499a3 - RNAppleAuthentication: 8d313d93fe2238d6b7ff0a39c67ebcf298d96653 - RNArgon2: 708e188b7a4d4ec8baf62463927c47abef453a94 - RNBootSplash: 295996a51f49baf0dff9f65e49b32ff93fbc7357 - RNCAsyncStorage: 39c42c1e478e1f5166d1db52b5055e090e85ad66 - RNCClipboard: b80e7bdccb8d432ab1c40189920e7af3116e074c - RNCMaskedView: ae521efb1c6c2b183ae0f8479487db03c826184c - RNDateTimePicker: a4ad049fdd568755003c479beac3bdea742ac4d0 - RNDeviceInfo: ae4e1a9b955b2a65314588cc7251795631925668 - RNDominantColor: 911de09d58e331bc8f84f22bf393e47d3cf8ca79 - RNFBApp: 33938c8ee95629bda8a14eda579e555a101212dd - RNFBAppCheck: 9135ee6833548d2dbd2cbda7e15d0d61bcedbe3c - RNFBMessaging: 1ea695eb9644bbb7aef5c459784f244af2b01cce - RNFlashList: 7ad51f0d0d51a3b7b1d1bb07947b927cb352afc4 - RNFS: 89de7d7f4c0f6bafa05343c578f61118c8282ed8 - RNGestureHandler: 7d0931a61d7ba0259f32db0ba7d0963c3ed15d2b - RNGoogleSignin: 2183722f55abd5b206d02e2edc146bec91fe5610 - RNInAppBrowser: 6d3eb68d471b9834335c664704719b8be1bfdb20 - RNKeychain: 943b4dbceef4b3a310c9122c99d1e5b0bd66b9f3 - RNLocalize: 83eda9ba7fd1cd23310dfd14e61ce5f091f888fb - RNNotifee: 5e3b271e8ea7456a36eec994085543c9adca9168 - RNOS: d07e5090b5060c6f2b83116d740a32cfdb33afe3 - RNPermissions: 4891cd00483fc6902cb92f61bd850e43badde94a - RNReanimated: 722d67dfde539bfe29b572878f4bc805f727726b - RNScreens: f0678748c5310b49a3f920f1485f5ec477afd345 - RNSensors: 111159597ac51505df10413c61b28bcd28e88983 - RNSentry: 3bc708566b3390947b6ecd785645398cd1a0049e - RNShare: 43faaefd287ef344e8379caeaca12d112f713295 - RNSound: 72c4886fb80b8a0e8c40131099223e09422aa8b4 - RNSVG: 794f269526df9ddc1f79b3d1a202b619df0368e3 + React-utils: 4efa98c1c602f5eacac3cece396c0b7c7d70c1d3 + ReactAppDependencyProvider: c42e7abdd2228ae583bdabc3dcd8e5cda6bef944 + ReactCodegen: 4d001cd4fa72b876bbff500bbb3811e458bb3c72 + ReactCommon: 41137f7e87cf7fd1c041a7124dfa3d0d48aa43f3 + ReactNativePerformance: ab7dee4c4862623d72c1530a9fc71b55458edf71 + RNAppleAuthentication: e00c76acb03351f5544373c78fa7f359bef6d5d3 + RNArgon2: 1481820722fd4af1575c09f7fc9ad67c00ee8a42 + RNBootSplash: f82b177a12ac2fde212e29c13480d9a08924f624 + RNCAsyncStorage: c1bbcf629d7206d1e19310827848b98d68a4cbaf + RNCClipboard: e63f1470286d683f2ade736feb352f4f18745247 + RNCMaskedView: 3e8d6bf9764b519d077986413882959eafceffbc + RNDateTimePicker: 792e57dd210f8af940812636708d43777f1f922b + RNDeviceInfo: 55264dd7cc939dad6e9c231a7621311f5277f1dc + RNDominantColor: 7c17c31201566a592ba4b2fbe2bb7e00df468753 + RNFBApp: 5c187f161ac2b1c258c9c099d56bf5cfdb1f0bcb + RNFBAppCheck: 94c8ce0a972880b3dd1563a01e0ba3245126a9a9 + RNFBMessaging: cb53c6f68f35949983ecb768589bb1c4771bea04 + RNFlashList: 30b68f572400383347ce7df3777985af0d089624 + RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 + RNGestureHandler: ccf4105b125002bd88e39d2a1f2b7e6001bcdf34 + RNGoogleSignin: 63192b9a15ec94c1fc4b0f55fba984a1d7af4ee7 + RNInAppBrowser: e36d6935517101ccba0e875bac8ad7b0cb655364 + RNKeychain: 16921786da69b6001ad2e65781b76f7af372bb10 + RNLocalize: 87712a038fae12e3ac03035ab5f0e35670a17cc3 + RNNotifee: 4a6ee5c7deaf00e005050052d73ee6315dff7ec9 + RNOS: 6f2f9a70895bbbfbdad7196abd952e7b01d45027 + RNPermissions: 5e9311c8050e355546083e45cd0b265ccbdc2a74 + RNReanimated: 6a437c90e263e4a2202a282f9d6dea0ad28d018d + RNScreens: 5fc633a16a513f598d9aaf515c380a82812a8bfc + RNSensors: 117ba71c7eeeea0407ea0c0bb79e3495d602049b + RNSentry: a1c2583797dd0e7d154e34a47021ebc8bf9d5a06 + RNShare: c57877c95b51671130e531065ed8e9396dd2669f + RNSound: 99655e437691f6357ffdd8a45f7a3b7aae27624f + RNSVG: ee32efbed652c5151fd3f98bed13c68af285bc38 SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3 SDWebImageAVIFCoder: 00310d246aab3232ce77f1d8f0076f8c4b021d90 SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c diff --git a/yarn.lock b/yarn.lock index 0d66fda39a..f64addc373 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24912,14 +24912,8 @@ __metadata: version: 0.0.0-use.local resolution: "mobile-monorepo@workspace:." dependencies: - "@ethereumjs/util": 9.1.0 - "@keystonehq/animated-qr": 0.10.0 - "@keystonehq/keystone-sdk": 0.11.3 - "@ngraveio/bc-ur": 1.1.13 husky: 9.1.6 lint-staged: 15.2.10 - react-native-popover-view: 6.1.0 - react-native-progress: 5.0.1 languageName: unknown linkType: soft From d0fc82391f1892d56322de07b874cee7066c8fc3 Mon Sep 17 00:00:00 2001 From: Charon-Fan Date: Wed, 17 Sep 2025 17:58:11 +0800 Subject: [PATCH 25/25] fix: clean up the UI when camera is disabled --- .../new/common/components/KeystoneQrScanner.tsx | 14 ++++++++++++-- .../app/new/common/components/QrCodeScanner.tsx | 8 ++++++++ .../components/RecoveryUsingKeystone.tsx | 7 +++++-- .../new/routes/onboarding/keystone/_layout.tsx | 16 ++++++++++++++-- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/packages/core-mobile/app/new/common/components/KeystoneQrScanner.tsx b/packages/core-mobile/app/new/common/components/KeystoneQrScanner.tsx index c7eb75b06f..9a49dd992c 100644 --- a/packages/core-mobile/app/new/common/components/KeystoneQrScanner.tsx +++ b/packages/core-mobile/app/new/common/components/KeystoneQrScanner.tsx @@ -12,6 +12,7 @@ interface Props { urTypes: string[] onSuccess: (ur: UR) => void onError?: () => void + onCameraPermissionGranted?: (granted: boolean) => void info?: string } @@ -19,11 +20,13 @@ export const KeystoneQrScanner: (props: Props) => JSX.Element = ({ info, urTypes, onSuccess, - onError + onError, + onCameraPermissionGranted }) => { const [urDecoder, setUrDecoder] = useState(new URDecoder()) const [progress, setProgress] = useState(0) const [showTroubleshooting, setShowTroubleshooting] = useState(false) + const [cameraPermissionGranted, setCameraPermissionGranted] = useState(false) const { theme } = useTheme() const progressColor = theme.isDark ? theme.colors.$white : theme.colors.$black @@ -51,6 +54,12 @@ export const KeystoneQrScanner: (props: Props) => JSX.Element = ({ } }, [showTroubleshooting, showErrorSheet, onError]) + useEffect(() => { + if (onCameraPermissionGranted) { + onCameraPermissionGranted(cameraPermissionGranted) + } + }, [cameraPermissionGranted, onCameraPermissionGranted]) + const handleScan = useCallback( (code: string) => { if (showTroubleshooting) { @@ -107,13 +116,14 @@ export const KeystoneQrScanner: (props: Props) => JSX.Element = ({ width: SCANNER_WIDTH, height: SCANNER_WIDTH }} + onCameraPermissionGranted={setCameraPermissionGranted} /> - + void vibrate?: boolean sx?: SxProp + onCameraPermissionGranted?: (granted: boolean) => void paused?: boolean } @@ -31,6 +32,7 @@ export const QrCodeScanner = ({ onSuccess, vibrate = false, sx, + onCameraPermissionGranted, paused = false }: Props): React.JSX.Element | undefined => { const { @@ -201,6 +203,12 @@ export const QrCodeScanner = ({ ) }, [colors.$textDanger]) + useEffect(() => { + if (onCameraPermissionGranted) { + onCameraPermissionGranted(cameraPermissionGranted) + } + }, [cameraPermissionGranted, onCameraPermissionGranted]) + if (cameraPermissionPending) return if (!cameraPermissionGranted) return renderCameraInstruction() diff --git a/packages/core-mobile/app/new/features/onboarding/components/RecoveryUsingKeystone.tsx b/packages/core-mobile/app/new/features/onboarding/components/RecoveryUsingKeystone.tsx index eb555affd0..cb8b6ebb91 100644 --- a/packages/core-mobile/app/new/features/onboarding/components/RecoveryUsingKeystone.tsx +++ b/packages/core-mobile/app/new/features/onboarding/components/RecoveryUsingKeystone.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useState } from 'react' import { View } from '@avalabs/k2-alpine' import { ScrollScreen } from 'common/components/ScrollScreen' import { UR, URType } from '@keystonehq/keystone-sdk' @@ -11,6 +11,8 @@ export const RecoveryUsingKeystone = ({ onSuccess: (ur: UR) => void onError: () => void }): JSX.Element => { + const [cameraPermissionGranted, setCameraPermissionGranted] = useState(false) + return ( - + diff --git a/packages/core-mobile/app/new/routes/onboarding/keystone/_layout.tsx b/packages/core-mobile/app/new/routes/onboarding/keystone/_layout.tsx index c8d1a6095c..790852ff84 100644 --- a/packages/core-mobile/app/new/routes/onboarding/keystone/_layout.tsx +++ b/packages/core-mobile/app/new/routes/onboarding/keystone/_layout.tsx @@ -2,10 +2,13 @@ import React, { useEffect, useMemo, useState } from 'react' import { Stack } from 'common/components/Stack' import { PageControl } from '@avalabs/k2-alpine' import { stackNavigatorScreenOptions } from 'common/consts/screenOptions' -import { useRootNavigationState } from 'expo-router' +import { useNavigation, useRootNavigationState } from 'expo-router' import { NavigationState } from '@react-navigation/native' +import { Platform } from 'react-native' +import { NativeStackNavigationOptions } from '@react-navigation/native-stack' export default function KeystoneOnboardingLayout(): JSX.Element { + const navigation = useNavigation() const [currentPage, setCurrentPage] = useState(0) const rootState: NavigationState = useRootNavigationState() @@ -24,11 +27,20 @@ export default function KeystoneOnboardingLayout(): JSX.Element { ) + useEffect(() => { + if (Platform.OS === 'ios') { + const navigationOptions: NativeStackNavigationOptions = { + headerTitle: renderPageControl + } + navigation.getParent()?.setOptions(navigationOptions) + } + }, [navigation, renderPageControl]) + return ( {screens.map(screen => { return