diff --git a/app/components/set-default-account-modal/set-default-account-modal.tsx b/app/components/set-default-account-modal/set-default-account-modal.tsx index ca3acfc31..bda4f3e36 100644 --- a/app/components/set-default-account-modal/set-default-account-modal.tsx +++ b/app/components/set-default-account-modal/set-default-account-modal.tsx @@ -10,7 +10,10 @@ import { useBreez } from "@app/hooks" import { useApolloClient } from "@apollo/client" import { useI18nContext } from "@app/i18n/i18n-react" import { useNavigation } from "@react-navigation/native" -import { useSetDefaultAccountModalQuery } from "@app/graphql/generated" +import { + useAccountUpdateDefaultWalletIdMutation, + useSetDefaultAccountModalQuery, +} from "@app/graphql/generated" import { usePersistentStateContext } from "@app/store/persistent-state" // utils @@ -34,17 +37,23 @@ export const SetDefaultAccountModal = ({ isVisible, toggleModal }: Props) => { const { LL } = useI18nContext() const { btcWallet } = useBreez() const { updateState } = usePersistentStateContext() + const [updateDefaultWalletId] = useAccountUpdateDefaultWalletIdMutation() const { data } = useSetDefaultAccountModalQuery({ fetchPolicy: "cache-only", }) const usdWallet = getUsdWallet(data?.me?.defaultAccount?.wallets) - const onPressHandler = (currency: string) => { + const onPressHandler = async (currency: string) => { let defaultWallet = usdWallet if (currency === "BTC") { defaultWallet = btcWallet } + if (defaultWallet?.id) { + await updateDefaultWalletId({ + variables: { input: { walletId: defaultWallet.id } }, + }) + } updateState((state: any) => { if (state) return { diff --git a/app/contexts/BreezContext.tsx b/app/contexts/BreezContext.tsx index a7b2e34e6..c440bbd98 100644 --- a/app/contexts/BreezContext.tsx +++ b/app/contexts/BreezContext.tsx @@ -1,15 +1,26 @@ import React, { createContext, useEffect, useRef, useState } from "react" -import { WalletCurrency } from "@app/graphql/generated" +import { useUpdateExternalWalletMutation, WalletCurrency } from "@app/graphql/generated" import { usePersistentStateContext } from "@app/store/persistent-state" import { Alert, Platform } from "react-native" import { v4 as uuidv4 } from "uuid" -import { initializeBreezSDK, getInfo, handleSparkMigration } from "@app/utils/breez-sdk" +import { + initializeBreezSDK, + getInfo, + handleSparkMigration, + registerLightningAddress, + getLightningAddress, + checkLightningAddressAvailable, +} from "@app/utils/breez-sdk" +import { useAppConfig } from "@app/hooks/use-app-config" +import { useAddressScreenQuery } from "@app/graphql/generated" +import { useIsAuthed } from "@app/graphql/is-authed-context" import SparkMigrationModal from "@app/components/spark-migration-modal" type BtcWallet = { id: string walletCurrency: WalletCurrency balance: number + isExternal: boolean } interface BreezInterface { @@ -25,6 +36,7 @@ export const BreezContext = createContext({ id: "", walletCurrency: "BTC", balance: 0, + isExternal: true, }, }) @@ -34,11 +46,20 @@ type Props = { export const BreezProvider = ({ children }: Props) => { const { persistentState, updateState } = usePersistentStateContext() + const { appConfig } = useAppConfig() + const isAuthed = useIsAuthed() + const { data: meData } = useAddressScreenQuery({ + fetchPolicy: "cache-first", + skip: !isAuthed, + }) + const [updateExternalWallet] = useUpdateExternalWalletMutation() + const [loading, setLoading] = useState(false) const [btcWallet, setBtcWallet] = useState({ id: "", walletCurrency: "BTC", balance: persistentState.breezBalance || 0, + isExternal: true, }) const initializingRef = useRef(false) const updatingBalanceRef = useRef(false) @@ -85,6 +106,7 @@ export const BreezProvider = ({ children }: Props) => { id: "", walletCurrency: "BTC", balance: 0, + isExternal: true, }) } } @@ -94,17 +116,16 @@ export const BreezProvider = ({ children }: Props) => { if (updatingBalanceRef.current) return updatingBalanceRef.current = true try { - const balanceSats = await getInfo() - setBtcWallet({ - id: uuidv4(), - walletCurrency: WalletCurrency.Btc, - balance: balanceSats, - }) + const walletInfo = await getInfo() + setBtcWallet((prev) => ({ + ...prev, + balance: Number(walletInfo.balanceSats), + })) updateState((state: any) => { if (state) return { ...state, - breezBalance: balanceSats, + breezBalance: Number(walletInfo.balanceSats), } return undefined }) @@ -113,6 +134,49 @@ export const BreezProvider = ({ children }: Props) => { } } + const updateExternalWalletLnurlp = async (lnurlp: string) => { + const externalWalletRes = await updateExternalWallet({ + variables: { input: { lnurlp } }, + }) + console.log("Update External Wallet Response: ", externalWalletRes) + const walletId = externalWalletRes.data?.updateExternalWallet.walletId + if (walletId) { + setBtcWallet((prev) => ({ + ...prev, + id: walletId, + })) + } + } + + const ensureLightningAddress = async () => { + const username = meData?.me?.username + if (!username) return + + try { + const existing = await getLightningAddress() + console.log("BREEZ LIGHTNING ADDRESS: ", existing) + + if (existing) { + updateExternalWalletLnurlp(existing.lnurl.bech32) + return + } + + // Register with username as the Lightning address + const lightningAddress = username + uuidv4() + const res = await registerLightningAddress( + lightningAddress, + `Pay to ${username}@${appConfig.galoyInstance.lnAddressHostname}`, + ) + console.log("BREEZ LIGHTNING ADDRESS RES: ", res) + + if (res) { + updateExternalWalletLnurlp(res.lnurl.bech32) + } + } catch (err) { + console.warn("Failed to register Lightning address:", err) + } + } + const getBreezInfo = async () => { if (initializingRef.current) return initializingRef.current = true @@ -122,6 +186,9 @@ export const BreezProvider = ({ children }: Props) => { await updateBalance() setLoading(false) + // Register Lightning address + await ensureLightningAddress() + // Trigger migration after Spark SDK is ready if (!persistentState.sparkMigrationCompleted) { await onMigrate() diff --git a/app/graphql/cache.ts b/app/graphql/cache.ts index ab7d3923c..4d10e375b 100644 --- a/app/graphql/cache.ts +++ b/app/graphql/cache.ts @@ -9,6 +9,7 @@ gql` id balance walletCurrency + isExternal } } diff --git a/app/graphql/front-end-mutations.ts b/app/graphql/front-end-mutations.ts index b9de734ee..dcdeedcd6 100644 --- a/app/graphql/front-end-mutations.ts +++ b/app/graphql/front-end-mutations.ts @@ -212,4 +212,14 @@ gql` uploadUrl } } + + mutation UpdateExternalWallet($input: UpdateExternalWalletInput!) { + updateExternalWallet(input: $input) { + errors { + code + message + } + walletId + } + } ` diff --git a/app/graphql/front-end-queries.ts b/app/graphql/front-end-queries.ts index d0715234c..691aa07ad 100644 --- a/app/graphql/front-end-queries.ts +++ b/app/graphql/front-end-queries.ts @@ -37,6 +37,7 @@ gql` id balance walletCurrency + isExternal } } } @@ -83,6 +84,7 @@ gql` id balance walletCurrency + isExternal } } } @@ -97,6 +99,7 @@ gql` id balance walletCurrency + isExternal } } } @@ -111,6 +114,7 @@ gql` id balance walletCurrency + isExternal } } } @@ -135,6 +139,7 @@ gql` id balance walletCurrency + isExternal } } } @@ -150,6 +155,7 @@ gql` id wallets { id + isExternal } } contacts { @@ -178,6 +184,7 @@ gql` id walletCurrency balance + isExternal } } } @@ -224,6 +231,7 @@ gql` id balance walletCurrency + isExternal } } } @@ -245,6 +253,7 @@ gql` id wallets { id + isExternal } } contacts { diff --git a/app/graphql/generated.gql b/app/graphql/generated.gql index 311d81c91..5efe9189e 100644 --- a/app/graphql/generated.gql +++ b/app/graphql/generated.gql @@ -3,6 +3,7 @@ fragment MyWallets on ConsumerAccount { id balance walletCurrency + isExternal __typename } __typename @@ -119,6 +120,18 @@ mutation MerchantMapSuggest($input: MerchantMapSuggestInput!) { } } +mutation UpdateExternalWallet($input: UpdateExternalWalletInput!) { + updateExternalWallet(input: $input) { + errors { + code + message + __typename + } + walletId + __typename + } +} + mutation accountDelete { accountDelete { errors { @@ -943,6 +956,7 @@ query accountScreen { id balance walletCurrency + isExternal __typename } __typename @@ -1028,6 +1042,7 @@ query cashoutScreen { id balance walletCurrency + isExternal __typename } __typename @@ -1063,6 +1078,7 @@ query conversionScreen { id balance walletCurrency + isExternal __typename } __typename @@ -1134,6 +1150,7 @@ query homeAuthed { id balance walletCurrency + isExternal __typename } __typename @@ -1294,6 +1311,7 @@ query paymentRequest { id balance walletCurrency + isExternal __typename } defaultWalletId @@ -1367,6 +1385,7 @@ query scanningQRCodeScreen { id wallets { id + isExternal __typename } __typename @@ -1389,6 +1408,7 @@ query sendBitcoinConfirmationScreen { id balance walletCurrency + isExternal __typename } __typename @@ -1408,6 +1428,7 @@ query sendBitcoinDestination { id wallets { id + isExternal __typename } __typename @@ -1435,6 +1456,7 @@ query sendBitcoinDetailsScreen { id walletCurrency balance + isExternal __typename } __typename @@ -1493,6 +1515,7 @@ query setDefaultAccountModal { id balance walletCurrency + isExternal __typename } __typename @@ -1511,6 +1534,7 @@ query setDefaultWalletScreen { id balance walletCurrency + isExternal __typename } __typename @@ -1532,6 +1556,7 @@ query settingsScreen { id balance walletCurrency + isExternal __typename } __typename @@ -1644,6 +1669,7 @@ query walletOverviewScreen { id balance walletCurrency + isExternal __typename } __typename @@ -1661,6 +1687,7 @@ query wallets { walletCurrency id lnurlp + isExternal __typename } __typename @@ -1679,6 +1706,7 @@ query warningSecureAccount { id balance walletCurrency + isExternal __typename } __typename diff --git a/app/graphql/generated.ts b/app/graphql/generated.ts index a840b8000..b25ea581c 100644 --- a/app/graphql/generated.ts +++ b/app/graphql/generated.ts @@ -17,6 +17,8 @@ export type Scalars = { Boolean: { input: boolean; output: boolean; } Int: { input: number; output: number; } Float: { input: number; output: number; } + /** Bank account number. Accepts String or Int and coerces to String. */ + AccountNumber: { input: string; output: string; } /** An Opaque Bearer token */ AuthToken: { input: string; output: string; } /** (Positive) Cent amount (1/100 of a dollar) */ @@ -262,8 +264,9 @@ export type BtcWallet = Wallet & { readonly __typename: 'BTCWallet'; readonly accountId: Scalars['ID']['output']; /** A balance stored in BTC. */ - readonly balance: Scalars['FractionalCentAmount']['output']; + readonly balance?: Maybe; readonly id: Scalars['ID']['output']; + readonly isExternal: Scalars['Boolean']['output']; readonly lnurlp?: Maybe; /** An unconfirmed incoming onchain balance. */ readonly pendingIncomingBalance: Scalars['SignedAmount']['output']; @@ -299,15 +302,20 @@ export type Bank = { export type BankAccount = { readonly __typename: 'BankAccount'; - readonly accountNumber: Scalars['Int']['output']; + readonly accountName?: Maybe; + readonly accountNumber: Scalars['String']['output']; readonly accountType: Scalars['String']['output']; readonly bankBranch: Scalars['String']['output']; readonly bankName: Scalars['String']['output']; + /** Account currency (e.g. JMD, USD) */ readonly currency: Scalars['String']['output']; + /** ERPNext bank account identifier */ + readonly id?: Maybe; + readonly isDefault: Scalars['Boolean']['output']; }; export type BankAccountInput = { - readonly accountNumber: Scalars['Int']['input']; + readonly accountNumber: Scalars['AccountNumber']['input']; readonly accountType: Scalars['String']['input']; readonly bankBranch: Scalars['String']['input']; readonly bankName: Scalars['String']['input']; @@ -375,17 +383,17 @@ export type CaptchaRequestAuthCodeInput = { export type CashoutOffer = { readonly __typename: 'CashoutOffer'; /** The rate used when withdrawing to a JMD bank account */ - readonly exchangeRate: Scalars['JMDCents']['output']; + readonly exchangeRate?: Maybe; /** The time at which this offer is no longer accepted by Flash */ readonly expiresAt: Scalars['Timestamp']['output']; - /** The amount that Flash is charging for it's services */ + /** The amount that Flash is charging for its services */ readonly flashFee: Scalars['USDCents']['output']; /** ID of the offer */ readonly offerId: Scalars['ID']['output']; - /** The amount Flash owes to the user denominated in JMD as cents */ - readonly receiveJmd: Scalars['JMDCents']['output']; - /** The amount Flash owes to the user denominated in USD as cents */ - readonly receiveUsd: Scalars['USDCents']['output']; + /** The amount Flash owes to the user denominated in JMD cents (null for USD payouts) */ + readonly receiveJmd?: Maybe; + /** The amount Flash owes to the user denominated in USD cents (null for JMD payouts) */ + readonly receiveUsd?: Maybe; /** The amount the user is sending to flash */ readonly send: Scalars['USDCents']['output']; /** ID for the users USD wallet to send from */ @@ -552,7 +560,7 @@ export type InitiateCashoutInput = { export type InitiatedCashoutResponse = { readonly __typename: 'InitiatedCashoutResponse'; readonly errors: ReadonlyArray; - readonly journalId?: Maybe; + readonly id?: Maybe; }; export type InitiationVia = InitiationViaIntraLedger | InitiationViaLn | InitiationViaOnChain; @@ -935,6 +943,7 @@ export type Mutation = { * The user can review this offer and then execute the withdrawal by calling the initiateCashout mutation. */ readonly requestCashout: RequestCashoutResponse; + readonly updateExternalWallet: UpdateExternalWalletPayload; /** @deprecated will be moved to AccountContact */ readonly userContactUpdateAlias: UserContactUpdateAliasPayload; readonly userEmailDelete: UserEmailDeletePayload; @@ -1148,6 +1157,11 @@ export type MutationRequestCashoutArgs = { }; +export type MutationUpdateExternalWalletArgs = { + input: UpdateExternalWalletInput; +}; + + export type MutationUserContactUpdateAliasArgs = { input: UserContactUpdateAliasInput; }; @@ -1608,6 +1622,8 @@ export type RealtimePricePayload = { export type RequestCashoutInput = { /** Amount in USD cents. */ readonly amount: Scalars['USDCents']['input']; + /** ERPNext bank account identifier to receive the cashout. */ + readonly bankAccountId: Scalars['ID']['input']; /** ID for a USD wallet belonging to the current user. */ readonly walletId: Scalars['WalletId']['input']; }; @@ -1806,6 +1822,16 @@ export const TxStatus = { } as const; export type TxStatus = typeof TxStatus[keyof typeof TxStatus]; +export type UpdateExternalWalletInput = { + readonly lnurlp: Scalars['Lnurl']['input']; +}; + +export type UpdateExternalWalletPayload = { + readonly __typename: 'UpdateExternalWalletPayload'; + readonly errors: ReadonlyArray; + readonly walletId?: Maybe; +}; + export type UpgradePayload = { readonly __typename: 'UpgradePayload'; readonly authToken?: Maybe; @@ -1817,8 +1843,9 @@ export type UpgradePayload = { export type UsdWallet = Wallet & { readonly __typename: 'UsdWallet'; readonly accountId: Scalars['ID']['output']; - readonly balance: Scalars['FractionalCentAmount']['output']; + readonly balance?: Maybe; readonly id: Scalars['ID']['output']; + readonly isExternal: Scalars['Boolean']['output']; readonly lnurlp?: Maybe; /** An unconfirmed incoming onchain balance. */ readonly pendingIncomingBalance: Scalars['SignedAmount']['output']; @@ -1848,6 +1875,8 @@ export type UsdWalletTransactionsByAddressArgs = { export type User = { readonly __typename: 'User'; + /** Bank accounts available for cashout */ + readonly bankAccounts: ReadonlyArray; /** * Get single contact details. * Can include the transactions associated with the contact. @@ -2075,8 +2104,9 @@ export type UserUpdateUsernamePayload = { /** A generic wallet which stores value in one of our supported currencies. */ export type Wallet = { readonly accountId: Scalars['ID']['output']; - readonly balance: Scalars['FractionalCentAmount']['output']; + readonly balance?: Maybe; readonly id: Scalars['ID']['output']; + readonly isExternal: Scalars['Boolean']['output']; readonly lnurlp?: Maybe; readonly pendingIncomingBalance: Scalars['SignedAmount']['output']; /** @@ -2154,7 +2184,7 @@ export type AnalyticsQueryVariables = Exact<{ [key: string]: never; }>; export type AnalyticsQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly username?: string | null, readonly id: string } | null, readonly globals?: { readonly __typename: 'Globals', readonly network: Network } | null }; -export type MyWalletsFragment = { readonly __typename: 'ConsumerAccount', readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency }> }; +export type MyWalletsFragment = { readonly __typename: 'ConsumerAccount', readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean }> }; export type RealtimePriceQueryVariables = Exact<{ [key: string]: never; }>; @@ -2305,6 +2335,13 @@ export type IdDocumentUploadUrlGenerateMutationVariables = Exact<{ export type IdDocumentUploadUrlGenerateMutation = { readonly __typename: 'Mutation', readonly idDocumentUploadUrlGenerate: { readonly __typename: 'IdDocumentUploadUrlPayload', readonly fileKey?: string | null, readonly uploadUrl?: string | null, readonly errors: ReadonlyArray<{ readonly __typename: 'GraphQLApplicationError', readonly code?: string | null, readonly message: string }> } }; +export type UpdateExternalWalletMutationVariables = Exact<{ + input: UpdateExternalWalletInput; +}>; + + +export type UpdateExternalWalletMutation = { readonly __typename: 'Mutation', readonly updateExternalWallet: { readonly __typename: 'UpdateExternalWalletPayload', readonly walletId?: string | null, readonly errors: ReadonlyArray<{ readonly __typename: 'GraphQLApplicationError', readonly code?: string | null, readonly message: string }> } }; + export type AuthQueryVariables = Exact<{ [key: string]: never; }>; @@ -2313,7 +2350,7 @@ export type AuthQuery = { readonly __typename: 'Query', readonly me?: { readonly export type HomeAuthedQueryVariables = Exact<{ [key: string]: never; }>; -export type HomeAuthedQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly language: string, readonly username?: string | null, readonly phone?: string | null, readonly npub?: string | null, readonly email?: { readonly __typename: 'Email', readonly address?: string | null, readonly verified?: boolean | null } | null, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly level: AccountLevel, readonly defaultWalletId: string, readonly transactions?: { readonly __typename: 'TransactionConnection', readonly pageInfo: { readonly __typename: 'PageInfo', readonly hasNextPage: boolean, readonly hasPreviousPage: boolean, readonly startCursor?: string | null, readonly endCursor?: string | null }, readonly edges?: ReadonlyArray<{ readonly __typename: 'TransactionEdge', readonly cursor: string, readonly node: { readonly __typename: 'Transaction', readonly id: string, readonly status: TxStatus, readonly direction: TxDirection, readonly memo?: string | null, readonly createdAt: number, readonly settlementAmount: number, readonly settlementFee: number, readonly settlementDisplayFee: string, readonly settlementCurrency: WalletCurrency, readonly settlementDisplayAmount: string, readonly settlementDisplayCurrency: string, readonly settlementPrice: { readonly __typename: 'PriceOfOneSettlementMinorUnitInDisplayMinorUnit', readonly base: number, readonly offset: number, readonly currencyUnit: string, readonly formattedAmount: string }, readonly initiationVia: { readonly __typename: 'InitiationViaIntraLedger', readonly counterPartyWalletId?: string | null, readonly counterPartyUsername?: string | null } | { readonly __typename: 'InitiationViaLn', readonly paymentHash: string } | { readonly __typename: 'InitiationViaOnChain', readonly address: string }, readonly settlementVia: { readonly __typename: 'SettlementViaIntraLedger', readonly counterPartyWalletId?: string | null, readonly counterPartyUsername?: string | null } | { readonly __typename: 'SettlementViaLn', readonly paymentSecret?: string | null } | { readonly __typename: 'SettlementViaOnChain', readonly transactionHash?: string | null } } }> | null } | null, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency }> } } | null }; +export type HomeAuthedQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly language: string, readonly username?: string | null, readonly phone?: string | null, readonly npub?: string | null, readonly email?: { readonly __typename: 'Email', readonly address?: string | null, readonly verified?: boolean | null } | null, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly level: AccountLevel, readonly defaultWalletId: string, readonly transactions?: { readonly __typename: 'TransactionConnection', readonly pageInfo: { readonly __typename: 'PageInfo', readonly hasNextPage: boolean, readonly hasPreviousPage: boolean, readonly startCursor?: string | null, readonly endCursor?: string | null }, readonly edges?: ReadonlyArray<{ readonly __typename: 'TransactionEdge', readonly cursor: string, readonly node: { readonly __typename: 'Transaction', readonly id: string, readonly status: TxStatus, readonly direction: TxDirection, readonly memo?: string | null, readonly createdAt: number, readonly settlementAmount: number, readonly settlementFee: number, readonly settlementDisplayFee: string, readonly settlementCurrency: WalletCurrency, readonly settlementDisplayAmount: string, readonly settlementDisplayCurrency: string, readonly settlementPrice: { readonly __typename: 'PriceOfOneSettlementMinorUnitInDisplayMinorUnit', readonly base: number, readonly offset: number, readonly currencyUnit: string, readonly formattedAmount: string }, readonly initiationVia: { readonly __typename: 'InitiationViaIntraLedger', readonly counterPartyWalletId?: string | null, readonly counterPartyUsername?: string | null } | { readonly __typename: 'InitiationViaLn', readonly paymentHash: string } | { readonly __typename: 'InitiationViaOnChain', readonly address: string }, readonly settlementVia: { readonly __typename: 'SettlementViaIntraLedger', readonly counterPartyWalletId?: string | null, readonly counterPartyUsername?: string | null } | { readonly __typename: 'SettlementViaLn', readonly paymentSecret?: string | null } | { readonly __typename: 'SettlementViaOnChain', readonly transactionHash?: string | null } } }> | null } | null, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean }> } } | null }; export type HomeUnauthedQueryVariables = Exact<{ [key: string]: never; }>; @@ -2333,17 +2370,17 @@ export type TransactionListForDefaultAccountQuery = { readonly __typename: 'Quer export type SetDefaultAccountModalQueryVariables = Exact<{ [key: string]: never; }>; -export type SetDefaultAccountModalQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly defaultWalletId: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency }> } } | null }; +export type SetDefaultAccountModalQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly defaultWalletId: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean }> } } | null }; export type ConversionScreenQueryVariables = Exact<{ [key: string]: never; }>; -export type ConversionScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency }> } } | null }; +export type ConversionScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean }> } } | null }; export type CashoutScreenQueryVariables = Exact<{ [key: string]: never; }>; -export type CashoutScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency }> } } | null }; +export type CashoutScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean }> } } | null }; export type WalletCsvTransactionsQueryVariables = Exact<{ walletIds: ReadonlyArray | Scalars['WalletId']['input']; @@ -2355,12 +2392,12 @@ export type WalletCsvTransactionsQuery = { readonly __typename: 'Query', readonl export type WalletOverviewScreenQueryVariables = Exact<{ [key: string]: never; }>; -export type WalletOverviewScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency }> } } | null }; +export type WalletOverviewScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean }> } } | null }; export type SendBitcoinDestinationQueryVariables = Exact<{ [key: string]: never; }>; -export type SendBitcoinDestinationQuery = { readonly __typename: 'Query', readonly globals?: { readonly __typename: 'Globals', readonly network: Network } | null, readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string } | { readonly __typename: 'UsdWallet', readonly id: string }> }, readonly contacts: ReadonlyArray<{ readonly __typename: 'UserContact', readonly id: string, readonly username: string }> } | null }; +export type SendBitcoinDestinationQuery = { readonly __typename: 'Query', readonly globals?: { readonly __typename: 'Globals', readonly network: Network } | null, readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly isExternal: boolean }> }, readonly contacts: ReadonlyArray<{ readonly __typename: 'UserContact', readonly id: string, readonly username: string }> } | null }; export type AccountDefaultWalletQueryVariables = Exact<{ username: Scalars['Username']['input']; @@ -2372,7 +2409,7 @@ export type AccountDefaultWalletQuery = { readonly __typename: 'Query', readonly export type SendBitcoinDetailsScreenQueryVariables = Exact<{ [key: string]: never; }>; -export type SendBitcoinDetailsScreenQuery = { readonly __typename: 'Query', readonly globals?: { readonly __typename: 'Globals', readonly network: Network } | null, readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly defaultWalletId: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly walletCurrency: WalletCurrency, readonly balance: number } | { readonly __typename: 'UsdWallet', readonly id: string, readonly walletCurrency: WalletCurrency, readonly balance: number }> } } | null }; +export type SendBitcoinDetailsScreenQuery = { readonly __typename: 'Query', readonly globals?: { readonly __typename: 'Globals', readonly network: Network } | null, readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly defaultWalletId: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly walletCurrency: WalletCurrency, readonly balance?: number | null, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly walletCurrency: WalletCurrency, readonly balance?: number | null, readonly isExternal: boolean }> } } | null }; export type SendBitcoinWithdrawalLimitsQueryVariables = Exact<{ [key: string]: never; }>; @@ -2387,12 +2424,12 @@ export type SendBitcoinInternalLimitsQuery = { readonly __typename: 'Query', rea export type SendBitcoinConfirmationScreenQueryVariables = Exact<{ [key: string]: never; }>; -export type SendBitcoinConfirmationScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency }> } } | null }; +export type SendBitcoinConfirmationScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean }> } } | null }; export type ScanningQrCodeScreenQueryVariables = Exact<{ [key: string]: never; }>; -export type ScanningQrCodeScreenQuery = { readonly __typename: 'Query', readonly globals?: { readonly __typename: 'Globals', readonly network: Network } | null, readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string } | { readonly __typename: 'UsdWallet', readonly id: string }> }, readonly contacts: ReadonlyArray<{ readonly __typename: 'UserContact', readonly id: string, readonly username: string }> } | null }; +export type ScanningQrCodeScreenQuery = { readonly __typename: 'Query', readonly globals?: { readonly __typename: 'Globals', readonly network: Network } | null, readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly isExternal: boolean }> }, readonly contacts: ReadonlyArray<{ readonly __typename: 'UserContact', readonly id: string, readonly username: string }> } | null }; export type RealtimePriceUnauthedQueryVariables = Exact<{ currency: Scalars['DisplayCurrency']['input']; @@ -2411,7 +2448,7 @@ export type NpubByUsernameQuery = { readonly __typename: 'Query', readonly npubB export type LatestAccountUpgradeRequestQueryVariables = Exact<{ [key: string]: never; }>; -export type LatestAccountUpgradeRequestQuery = { readonly __typename: 'Query', readonly latestAccountUpgradeRequest: { readonly __typename: 'AccountUpgradeRequestPayload', readonly errors?: ReadonlyArray<{ readonly __typename: 'GraphQLApplicationError', readonly code?: string | null, readonly message: string } | null> | null, readonly upgradeRequest?: { readonly __typename: 'AccountUpgradeRequest', readonly currentLevel: AccountLevel, readonly fullName: string, readonly terminalsRequested: number, readonly status: string, readonly requestedLevel: AccountLevel, readonly phoneNumber: string, readonly email?: string | null, readonly idDocument: boolean, readonly address: { readonly __typename: 'Address', readonly city: string, readonly country: string, readonly line1: string, readonly line2?: string | null, readonly postalCode?: string | null, readonly state: string, readonly title: string }, readonly bankAccount?: { readonly __typename: 'BankAccount', readonly accountNumber: number, readonly accountType: string, readonly bankBranch: string, readonly bankName: string, readonly currency: string } | null } | null } }; +export type LatestAccountUpgradeRequestQuery = { readonly __typename: 'Query', readonly latestAccountUpgradeRequest: { readonly __typename: 'AccountUpgradeRequestPayload', readonly errors?: ReadonlyArray<{ readonly __typename: 'GraphQLApplicationError', readonly code?: string | null, readonly message: string } | null> | null, readonly upgradeRequest?: { readonly __typename: 'AccountUpgradeRequest', readonly currentLevel: AccountLevel, readonly fullName: string, readonly terminalsRequested: number, readonly status: string, readonly requestedLevel: AccountLevel, readonly phoneNumber: string, readonly email?: string | null, readonly idDocument: boolean, readonly address: { readonly __typename: 'Address', readonly city: string, readonly country: string, readonly line1: string, readonly line2?: string | null, readonly postalCode?: string | null, readonly state: string, readonly title: string }, readonly bankAccount?: { readonly __typename: 'BankAccount', readonly accountNumber: string, readonly accountType: string, readonly bankBranch: string, readonly bankName: string, readonly currency: string } | null } | null } }; export type SupportedBanksQueryVariables = Exact<{ [key: string]: never; }>; @@ -2624,7 +2661,7 @@ export type MyLnUpdatesSubscription = { readonly __typename: 'Subscription', rea export type PaymentRequestQueryVariables = Exact<{ [key: string]: never; }>; -export type PaymentRequestQuery = { readonly __typename: 'Query', readonly globals?: { readonly __typename: 'Globals', readonly network: Network, readonly feesInformation: { readonly __typename: 'FeesInformation', readonly deposit: { readonly __typename: 'DepositFeesInformation', readonly minBankFee: string, readonly minBankFeeThreshold: string } } } | null, readonly me?: { readonly __typename: 'User', readonly id: string, readonly username?: string | null, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly defaultWalletId: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency }> } } | null }; +export type PaymentRequestQuery = { readonly __typename: 'Query', readonly globals?: { readonly __typename: 'Globals', readonly network: Network, readonly feesInformation: { readonly __typename: 'FeesInformation', readonly deposit: { readonly __typename: 'DepositFeesInformation', readonly minBankFee: string, readonly minBankFeeThreshold: string } } } | null, readonly me?: { readonly __typename: 'User', readonly id: string, readonly username?: string | null, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly defaultWalletId: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean }> } } | null }; export type LnNoAmountInvoiceCreateMutationVariables = Exact<{ input: LnNoAmountInvoiceCreateInput; @@ -2664,7 +2701,7 @@ export type FeedbackSubmitMutation = { readonly __typename: 'Mutation', readonly export type AccountScreenQueryVariables = Exact<{ [key: string]: never; }>; -export type AccountScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly phone?: string | null, readonly totpEnabled: boolean, readonly email?: { readonly __typename: 'Email', readonly address?: string | null, readonly verified?: boolean | null } | null, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly level: AccountLevel, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency }> } } | null }; +export type AccountScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly phone?: string | null, readonly totpEnabled: boolean, readonly email?: { readonly __typename: 'Email', readonly address?: string | null, readonly verified?: boolean | null } | null, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly level: AccountLevel, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean }> } } | null }; export type UserEmailDeleteMutationVariables = Exact<{ [key: string]: never; }>; @@ -2686,7 +2723,7 @@ export type UserTotpDeleteMutation = { readonly __typename: 'Mutation', readonly export type WarningSecureAccountQueryVariables = Exact<{ [key: string]: never; }>; -export type WarningSecureAccountQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly level: AccountLevel, readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency }> } } | null }; +export type WarningSecureAccountQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly level: AccountLevel, readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean }> } } | null }; export type AccountUpdateDefaultWalletIdMutationVariables = Exact<{ input: AccountUpdateDefaultWalletIdInput; @@ -2698,7 +2735,7 @@ export type AccountUpdateDefaultWalletIdMutation = { readonly __typename: 'Mutat export type SetDefaultWalletScreenQueryVariables = Exact<{ [key: string]: never; }>; -export type SetDefaultWalletScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly defaultWalletId: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency }> } } | null }; +export type SetDefaultWalletScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly defaultWalletId: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean }> } } | null }; export type AccountUpdateDisplayCurrencyMutationVariables = Exact<{ input: AccountUpdateDisplayCurrencyInput; @@ -2755,7 +2792,7 @@ export type AccountDisableNotificationCategoryMutation = { readonly __typename: export type SettingsScreenQueryVariables = Exact<{ [key: string]: never; }>; -export type SettingsScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly phone?: string | null, readonly username?: string | null, readonly language: string, readonly totpEnabled: boolean, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly defaultWalletId: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance: number, readonly walletCurrency: WalletCurrency }> }, readonly email?: { readonly __typename: 'Email', readonly address?: string | null, readonly verified?: boolean | null } | null } | null }; +export type SettingsScreenQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly phone?: string | null, readonly username?: string | null, readonly language: string, readonly totpEnabled: boolean, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly defaultWalletId: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly id: string, readonly balance?: number | null, readonly walletCurrency: WalletCurrency, readonly isExternal: boolean }> }, readonly email?: { readonly __typename: 'Email', readonly address?: string | null, readonly verified?: boolean | null } | null } | null }; export type ExportCsvSettingQueryVariables = Exact<{ walletIds: ReadonlyArray | Scalars['WalletId']['input']; @@ -2805,7 +2842,7 @@ export type DeviceNotificationTokenCreateMutation = { readonly __typename: 'Muta export type WalletsQueryVariables = Exact<{ [key: string]: never; }>; -export type WalletsQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly walletCurrency: WalletCurrency, readonly id: string, readonly lnurlp?: string | null } | { readonly __typename: 'UsdWallet', readonly walletCurrency: WalletCurrency, readonly id: string, readonly lnurlp?: string | null }> } } | null }; +export type WalletsQuery = { readonly __typename: 'Query', readonly me?: { readonly __typename: 'User', readonly id: string, readonly defaultAccount: { readonly __typename: 'ConsumerAccount', readonly id: string, readonly wallets: ReadonlyArray<{ readonly __typename: 'BTCWallet', readonly walletCurrency: WalletCurrency, readonly id: string, readonly lnurlp?: string | null, readonly isExternal: boolean } | { readonly __typename: 'UsdWallet', readonly walletCurrency: WalletCurrency, readonly id: string, readonly lnurlp?: string | null, readonly isExternal: boolean }> } } | null }; export const MyWalletsFragmentDoc = gql` fragment MyWallets on ConsumerAccount { @@ -2813,6 +2850,7 @@ export const MyWalletsFragmentDoc = gql` id balance walletCurrency + isExternal } } `; @@ -3905,6 +3943,43 @@ export function useIdDocumentUploadUrlGenerateMutation(baseOptions?: Apollo.Muta export type IdDocumentUploadUrlGenerateMutationHookResult = ReturnType; export type IdDocumentUploadUrlGenerateMutationResult = Apollo.MutationResult; export type IdDocumentUploadUrlGenerateMutationOptions = Apollo.BaseMutationOptions; +export const UpdateExternalWalletDocument = gql` + mutation UpdateExternalWallet($input: UpdateExternalWalletInput!) { + updateExternalWallet(input: $input) { + errors { + code + message + } + walletId + } +} + `; +export type UpdateExternalWalletMutationFn = Apollo.MutationFunction; + +/** + * __useUpdateExternalWalletMutation__ + * + * To run a mutation, you first call `useUpdateExternalWalletMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdateExternalWalletMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [updateExternalWalletMutation, { data, loading, error }] = useUpdateExternalWalletMutation({ + * variables: { + * input: // value for 'input' + * }, + * }); + */ +export function useUpdateExternalWalletMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(UpdateExternalWalletDocument, options); + } +export type UpdateExternalWalletMutationHookResult = ReturnType; +export type UpdateExternalWalletMutationResult = Apollo.MutationResult; +export type UpdateExternalWalletMutationOptions = Apollo.BaseMutationOptions; export const AuthDocument = gql` query auth { me { @@ -3969,6 +4044,7 @@ export const HomeAuthedDocument = gql` id balance walletCurrency + isExternal } } } @@ -4097,6 +4173,7 @@ export const SetDefaultAccountModalDocument = gql` id balance walletCurrency + isExternal } } } @@ -4139,6 +4216,7 @@ export const ConversionScreenDocument = gql` id balance walletCurrency + isExternal } } } @@ -4181,6 +4259,7 @@ export const CashoutScreenDocument = gql` id balance walletCurrency + isExternal } } } @@ -4262,6 +4341,7 @@ export const WalletOverviewScreenDocument = gql` id balance walletCurrency + isExternal } } } @@ -4305,6 +4385,7 @@ export const SendBitcoinDestinationDocument = gql` id wallets { id + isExternal } } contacts { @@ -4390,6 +4471,7 @@ export const SendBitcoinDetailsScreenDocument = gql` id walletCurrency balance + isExternal } } } @@ -4520,6 +4602,7 @@ export const SendBitcoinConfirmationScreenDocument = gql` id balance walletCurrency + isExternal } } } @@ -4563,6 +4646,7 @@ export const ScanningQrCodeScreenDocument = gql` id wallets { id + isExternal } } contacts { @@ -6013,6 +6097,7 @@ export const PaymentRequestDocument = gql` id balance walletCurrency + isExternal } defaultWalletId } @@ -6259,6 +6344,7 @@ export const AccountScreenDocument = gql` id balance walletCurrency + isExternal } } } @@ -6432,6 +6518,7 @@ export const WarningSecureAccountDocument = gql` id balance walletCurrency + isExternal } } } @@ -6514,6 +6601,7 @@ export const SetDefaultWalletScreenDocument = gql` id balance walletCurrency + isExternal } } } @@ -6892,6 +6980,7 @@ export const SettingsScreenDocument = gql` id balance walletCurrency + isExternal } } totpEnabled @@ -7226,6 +7315,7 @@ export const WalletsDocument = gql` walletCurrency id lnurlp + isExternal } } } diff --git a/app/graphql/wallets-utils.ts b/app/graphql/wallets-utils.ts index e8e00299f..6dff22a5c 100644 --- a/app/graphql/wallets-utils.ts +++ b/app/graphql/wallets-utils.ts @@ -1,6 +1,6 @@ import { Wallet, WalletCurrency } from "@app/graphql/generated" -type WalletBalance = Pick +type WalletBalance = Pick export const getBtcWallet = (wallets: readonly WalletBalance[] | undefined) => { if (wallets === undefined || wallets.length === 0) { @@ -28,3 +28,11 @@ export const getDefaultWallet = ( return wallets.find((wallet) => wallet.id === defaultWalletId) } + +export const getInternalWallets = (wallets: readonly WalletBalance[] | undefined) => { + if (wallets === undefined || wallets.length === 0) { + return undefined + } + + return wallets.filter((wallet) => !wallet.isExternal) +} diff --git a/app/hooks/useBreez.ts b/app/hooks/useBreez.ts index f53720154..8c28a7935 100644 --- a/app/hooks/useBreez.ts +++ b/app/hooks/useBreez.ts @@ -6,6 +6,7 @@ type BtcWallet = { id: string walletCurrency: WalletCurrency balance: number + isExternal: boolean } interface ContextProps { diff --git a/app/screens/import-wallet-screen/ImportWallet.tsx b/app/screens/import-wallet-screen/ImportWallet.tsx index bad93e14c..1ae8e7d32 100644 --- a/app/screens/import-wallet-screen/ImportWallet.tsx +++ b/app/screens/import-wallet-screen/ImportWallet.tsx @@ -16,6 +16,7 @@ import { useI18nContext } from "@app/i18n/i18n-react" import { useCreateAccount } from "@app/hooks/useCreateAccount" import { Text, useTheme, useThemeMode } from "@rneui/themed" import { usePersistentStateContext } from "@app/store/persistent-state" +import { useAppConfig } from "@app/hooks/use-app-config" // utils import { disconnectToSDK, initializeBreezSDK } from "@app/utils/breez-sdk" @@ -31,6 +32,7 @@ const ImportWallet: React.FC = ({ navigation, route }) => { const { mode } = useThemeMode() const { LL } = useI18nContext() const { updateState } = usePersistentStateContext() + const { appConfig } = useAppConfig() const { createDeviceAccountAndLogin } = useCreateAccount() const inputRef = useRef([]) diff --git a/app/screens/receive-bitcoin-screen/use-receive-bitcoin.ts b/app/screens/receive-bitcoin-screen/use-receive-bitcoin.ts index fc7a29bee..356c4f4fc 100644 --- a/app/screens/receive-bitcoin-screen/use-receive-bitcoin.ts +++ b/app/screens/receive-bitcoin-screen/use-receive-bitcoin.ts @@ -61,6 +61,7 @@ gql` id balance walletCurrency + isExternal } defaultWalletId } diff --git a/app/screens/send-bitcoin-screen/send-bitcoin-details-screen.tsx b/app/screens/send-bitcoin-screen/send-bitcoin-details-screen.tsx index 6464361b0..174865e19 100644 --- a/app/screens/send-bitcoin-screen/send-bitcoin-details-screen.tsx +++ b/app/screens/send-bitcoin-screen/send-bitcoin-details-screen.tsx @@ -23,7 +23,7 @@ import { WalletCurrency, } from "@app/graphql/generated" import { decodeInvoiceString, Network as NetworkLibGaloy } from "@galoymoney/client" -import { getUsdWallet } from "@app/graphql/wallets-utils" +import { getInternalWallets, getUsdWallet } from "@app/graphql/wallets-utils" // hooks import { useIsAuthed } from "@app/graphql/is-authed-context" @@ -382,7 +382,7 @@ const SendBitcoinDetailsScreen: React.FC = ({ navigation, route }) => { > diff --git a/app/screens/settings-screen/account-screen.tsx b/app/screens/settings-screen/account-screen.tsx index 978915aa2..917604702 100644 --- a/app/screens/settings-screen/account-screen.tsx +++ b/app/screens/settings-screen/account-screen.tsx @@ -46,6 +46,7 @@ gql` id balance walletCurrency + isExternal } } } diff --git a/app/screens/settings-screen/account/settings/delete.tsx b/app/screens/settings-screen/account/settings/delete.tsx index 1a05f3e6c..005600f8d 100644 --- a/app/screens/settings-screen/account/settings/delete.tsx +++ b/app/screens/settings-screen/account/settings/delete.tsx @@ -104,7 +104,6 @@ export const Delete = () => { if (res.data?.accountDelete?.success) { await deleteNostrData() - if (data?.me?.phone) await deleteUser(data?.me?.phone) await cleanUp(true) setAccountIsBeingDeleted(false) navigation.reset({ diff --git a/app/screens/settings-screen/account/show-warning-secure-account-hook.ts b/app/screens/settings-screen/account/show-warning-secure-account-hook.ts index 81cce1d8f..8c738ff4e 100644 --- a/app/screens/settings-screen/account/show-warning-secure-account-hook.ts +++ b/app/screens/settings-screen/account/show-warning-secure-account-hook.ts @@ -22,6 +22,7 @@ gql` id balance walletCurrency + isExternal } } } diff --git a/app/screens/settings-screen/default-wallet.tsx b/app/screens/settings-screen/default-wallet.tsx index 279bdb0d8..c96f8142c 100644 --- a/app/screens/settings-screen/default-wallet.tsx +++ b/app/screens/settings-screen/default-wallet.tsx @@ -1,5 +1,8 @@ import { gql } from "@apollo/client" -import { useSetDefaultWalletScreenQuery } from "@app/graphql/generated" +import { + useAccountUpdateDefaultWalletIdMutation, + useSetDefaultWalletScreenQuery, +} from "@app/graphql/generated" import { useIsAuthed } from "@app/graphql/is-authed-context" import { useI18nContext } from "@app/i18n/i18n-react" import { Text, makeStyles } from "@rneui/themed" @@ -36,6 +39,7 @@ gql` id balance walletCurrency + isExternal } } } @@ -54,6 +58,7 @@ export const DefaultWalletScreen: React.FC = () => { fetchPolicy: "cache-first", skip: !isAuthed, }) + const [updateDefaultWalletId] = useAccountUpdateDefaultWalletIdMutation() const usdWallet = getUsdWallet(data?.me?.defaultAccount?.wallets) @@ -73,6 +78,12 @@ export const DefaultWalletScreen: React.FC = () => { defaultWallet = btcWallet } + if (defaultWallet.id) { + await updateDefaultWalletId({ + variables: { input: { walletId: defaultWallet.id } }, + }) + } + updateState((state: any) => { if (state) return { diff --git a/app/screens/settings-screen/settings-screen.tsx b/app/screens/settings-screen/settings-screen.tsx index ff569474f..2e25bcde2 100644 --- a/app/screens/settings-screen/settings-screen.tsx +++ b/app/screens/settings-screen/settings-screen.tsx @@ -48,6 +48,7 @@ gql` id balance walletCurrency + isExternal } } totpEnabled diff --git a/app/screens/settings-screen/show-warning-secure-account.tsx b/app/screens/settings-screen/show-warning-secure-account.tsx index 1812569bf..de8952dfd 100644 --- a/app/screens/settings-screen/show-warning-secure-account.tsx +++ b/app/screens/settings-screen/show-warning-secure-account.tsx @@ -22,6 +22,7 @@ gql` id balance walletCurrency + isExternal } } } diff --git a/app/types/amounts.ts b/app/types/amounts.ts index 8d3172c3d..867b75d8b 100644 --- a/app/types/amounts.ts +++ b/app/types/amounts.ts @@ -37,8 +37,8 @@ export const ZeroBtcMoneyAmount: BtcMoneyAmount = { currencyCode: "BTC", } -export const toBtcMoneyAmount = (amount: number | undefined): BtcMoneyAmount => { - if (amount === undefined) { +export const toBtcMoneyAmount = (amount: number | undefined | null): BtcMoneyAmount => { + if (amount === undefined || amount === null) { return { amount: NaN, currency: WalletCurrency.Btc, @@ -52,8 +52,8 @@ export const toBtcMoneyAmount = (amount: number | undefined): BtcMoneyAmount => } } -export const toUsdMoneyAmount = (amount: number | undefined): UsdMoneyAmount => { - if (amount === undefined) { +export const toUsdMoneyAmount = (amount: number | undefined | null): UsdMoneyAmount => { + if (amount === undefined || amount === null) { return { amount: NaN, currency: WalletCurrency.Usd, diff --git a/app/types/declaration.d.ts b/app/types/declaration.d.ts index 475131c04..457cd07b5 100644 --- a/app/types/declaration.d.ts +++ b/app/types/declaration.d.ts @@ -32,4 +32,5 @@ declare module "@env" { export const GREENLIGHT_PARTNER_KEY: string export const GOOGLE_PLACE_API_KEY: string export const MIGRATION_FEE_LNURL_W: string + export const BREEZ_LNURL_DOMAIN: string } diff --git a/app/types/transactions.ts b/app/types/transactions.ts index 9b88e49f4..50cde7643 100644 --- a/app/types/transactions.ts +++ b/app/types/transactions.ts @@ -103,7 +103,6 @@ export const getTransactionStatus = ( tx: UnifiedTransaction, ): "SUCCESS" | "PENDING" | "FAILURE" => { if (isBreezTransaction(tx)) { - // PaymentStatus: Completed = 0, Pending = 1, Failed = 2 switch (tx.payment.status) { case 0: case PaymentStatus.Completed: diff --git a/app/utils/breez-sdk/spark.ts b/app/utils/breez-sdk/spark.ts index 1561b2050..fb5a21403 100644 --- a/app/utils/breez-sdk/spark.ts +++ b/app/utils/breez-sdk/spark.ts @@ -28,11 +28,12 @@ import type { RecommendedFees, SendPaymentMethod, LnurlPayResponse, + LightningAddressInfo, Payment, Logger, LogEntry, } from "@breeztech/breez-sdk-spark-react-native" -import { API_KEY } from "@env" +import { API_KEY, BREEZ_LNURL_DOMAIN } from "@env" import { appendLog, initLogBuffer } from "./log-buffer" // Constants @@ -67,7 +68,7 @@ export const initializeBreezSDK = async (): Promise => { breezSDKInitializing = (async () => { try { - await retry(connectToSDK, 5000, 3) + await retry(() => connectToSDK(), 5000, 3) breezSDKInitialized = true return true } catch (error: unknown) { @@ -120,6 +121,7 @@ const connectToSDK = async (): Promise => { const config = defaultConfig(Network.Mainnet) config.apiKey = API_KEY + config.lnurlDomain = BREEZ_LNURL_DOMAIN config.maxDepositClaimFee = new MaxFee.NetworkRecommended({ leewaySatPerVbyte: BigInt(1), }) @@ -174,7 +176,7 @@ export const getInfo = async () => { const sdk = getSDKInstance() const info = await sdk.getInfo({ ensureSynced: true }) - return Number(info.balanceSats) + return info } // Fee Estimation @@ -624,3 +626,31 @@ export const refundDeposit = async ( return { success: false, error: message } } } + +// Lightning Address (LNURL-Pay) +export const checkLightningAddressAvailable = async ( + username: string, +): Promise => { + const sdk = getSDKInstance() + return sdk.checkLightningAddressAvailable({ username }) +} + +export const registerLightningAddress = async ( + username: string, + description?: string, +): Promise => { + const sdk = getSDKInstance() + return sdk.registerLightningAddress({ username, description }) +} + +export const getLightningAddress = async (): Promise< + LightningAddressInfo | undefined +> => { + const sdk = getSDKInstance() + return sdk.getLightningAddress() +} + +export const deleteLightningAddress = async (): Promise => { + const sdk = getSDKInstance() + await sdk.deleteLightningAddress() +} diff --git a/e2e/utils/graphql.ts b/e2e/utils/graphql.ts index aa45455f6..70bd3e9ef 100644 --- a/e2e/utils/graphql.ts +++ b/e2e/utils/graphql.ts @@ -90,6 +90,7 @@ gql` walletCurrency id lnurlp + isExternal } } } diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 0e39cb3a3..b8a000c0f 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -10,7 +10,7 @@ PODS: - breez_sdk_liquidFFI (0.11.13) - BreezSDKLiquid (0.11.13): - breez_sdk_liquidFFI (= 0.11.13) - - BreezSdkSparkReactNative (0.13.4): + - breeztech-breez-sdk-spark-react-native (0.7.14): - DoubleConversion - glog - hermes-engine @@ -3013,7 +3013,7 @@ SPEC CHECKSUMS: breez_sdk_liquid: 5c229f9ab3bcf6b648bbf2d512f6fe1eee96d121 breez_sdk_liquidFFI: f05fadc0611126ade76d1fe6761ed8b020aabefb BreezSDKLiquid: ee6bf5a57f1b2533dc3c14c24c9773496f17b756 - BreezSdkSparkReactNative: 22459556b92935587708d1e8f875a59fad16005f + breeztech-breez-sdk-spark-react-native: 0af390a27a5f95bc838cddbecead825b671f60b2 BVLinearGradient: 880f91a7854faff2df62518f0281afb1c60d49a3 DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb fast_float: 06eeec4fe712a76acc9376682e4808b05ce978b6 diff --git a/yarn.lock b/yarn.lock index a8ec0c412..c6182ea6b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1334,10 +1334,10 @@ dependencies: "@noble/curves" "^1.7.0" -"@breeztech/breez-sdk-spark-react-native@^0.13.4": - version "0.13.4" - resolved "https://registry.yarnpkg.com/@breeztech/breez-sdk-spark-react-native/-/breez-sdk-spark-react-native-0.13.4.tgz#7c5429a677547fcbe3aef4fcb299c159e0ff1641" - integrity sha512-wspP9tXY4GDJWVH42xI3dhe+MS5ROYX0a2mOqHKLWGcFqQc+Yuf77NaPBhZqM3FDKxVvZkDtAhCDuqDJ4vaclQ== +"@breeztech/breez-sdk-spark-react-native@^0.7.14": + version "0.7.14" + resolved "https://registry.yarnpkg.com/@breeztech/breez-sdk-spark-react-native/-/breez-sdk-spark-react-native-0.7.14.tgz#b8914719e67620aa6b85178d7a903d7efcaedbac" + integrity sha512-xHhcwD0/aDQAGg6mJM1K1Wepp3bmf3SnuK7tIC2jSX7VA308lB92u6ag3vIQMvAtz6mZptu+8Le+br9sr2u4/w== dependencies: uniffi-bindgen-react-native "^0.29.3-1"