Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
5890065
feat: add breez-sdk-spark-react-native and react-native-fs dependencies
esaugomez31 Apr 3, 2026
ee64475
feat: enable new architecture for Breez SDK turbo modules
esaugomez31 Apr 3, 2026
d4d1aaf
feat: add mnemonic secure storage methods to KeyStoreWrapper
esaugomez31 Apr 3, 2026
e61f568
feat: add toNumber helper for BigInt conversion
esaugomez31 Apr 3, 2026
fa5ab69
feat: add toWalletMoneyAmount shared helper
esaugomez31 Apr 3, 2026
7da30c0
refactor: use toWalletMoneyAmount in custodial transaction mapper
esaugomez31 Apr 3, 2026
7d1bdb2
feat: add Spark SDK configuration constants
esaugomez31 Apr 3, 2026
c55143e
feat: update SDK logging to createSdkLogListener
esaugomez31 Apr 3, 2026
52bc038
feat: add Breez SDK bridge with wallet create and restore
esaugomez31 Apr 3, 2026
c360eb4
feat: add self-custodial transaction mapper
esaugomez31 Apr 3, 2026
4c7a7cc
feat: add SelfCustodialWalletProvider with real SDK integration
esaugomez31 Apr 3, 2026
0192231
feat: wire SelfCustodialWalletProvider to useActiveWallet and app tree
esaugomez31 Apr 3, 2026
49e4f78
test: add mnemonic secure storage tests
esaugomez31 Apr 3, 2026
7a3fd76
test: add toNumber helper tests
esaugomez31 Apr 3, 2026
b87a66d
test: add toWalletMoneyAmount tests
esaugomez31 Apr 3, 2026
5288a0b
test: add Breez SDK bridge tests
esaugomez31 Apr 3, 2026
298fc7d
test: add self-custodial transaction mapper tests
esaugomez31 Apr 3, 2026
33e61ad
test: add SelfCustodialWalletProvider tests
esaugomez31 Apr 3, 2026
81d74ee
test: update SDK logging tests for createSdkLogListener
esaugomez31 Apr 3, 2026
7494bd4
feat: add cloud icon to galoy-icon component
esaugomez31 Apr 6, 2026
e386758
feat: add i18n keys for AccountTypeSelectionScreen and SparkWalletCre…
esaugomez31 Apr 6, 2026
ac05f44
feat: add account type selection screen with tests
esaugomez31 Apr 6, 2026
be80c66
feat: add spark wallet creation screen with tests
esaugomez31 Apr 6, 2026
2fc7e7d
feat: register new screens in navigation and fix initial route for se…
esaugomez31 Apr 6, 2026
6c5d897
feat: add DefaultAccountId constants to wallet types
esaugomez31 Apr 6, 2026
b132bfd
refactor: use DefaultAccountId from wallet types
esaugomez31 Apr 6, 2026
938ad05
refactor: clean up bridge with lazy logging and direct RNG injection
esaugomez31 Apr 6, 2026
af187f1
feat: route to account type selection when nonCustodialEnabled
esaugomez31 Apr 6, 2026
18cdee9
feat: handle selfCustodial flow in terms and conditions
esaugomez31 Apr 6, 2026
a6e14e7
feat: add self-custodial support to home screen
esaugomez31 Apr 6, 2026
5017b77
test: add global mock for breez-sdk-spark
esaugomez31 Apr 6, 2026
b16bbed
test: add global mock for react-native-fs
esaugomez31 Apr 6, 2026
0175d25
test: add global mock for react-native-config
esaugomez31 Apr 6, 2026
da1684f
test: update bridge tests for RNG injection
esaugomez31 Apr 6, 2026
37d04de
test: add self-custodial home screen test
esaugomez31 Apr 6, 2026
fc0e300
refactor: return null from getMnemonic and add network metadata to ke…
esaugomez31 Apr 9, 2026
2ebf535
feat: parametrize SDK network via BREEZ_NETWORK env var
esaugomez31 Apr 9, 2026
7c2e5c3
feat: add network guard and store network on wallet creation
esaugomez31 Apr 9, 2026
18e9182
refactor: extract wallet snapshot and add refresh coalescing
esaugomez31 Apr 9, 2026
ce79c68
refactor: extract useCreateWallet hook from wallet creation screen
esaugomez31 Apr 9, 2026
e41ce27
refactor: add derived fields to useActiveWallet and simplify home screen
esaugomez31 Apr 9, 2026
f0d5b50
chore: add noRetryOperations registration point for self-custodial
esaugomez31 Apr 9, 2026
361233d
fix: add crashlytics to wallet creation, cloud backup and checkpoint …
esaugomez31 Apr 9, 2026
78d54a1
fix: stop TransferringFundsScreen from faking success
esaugomez31 Apr 9, 2026
8ad4a85
refactor: change selfCustodialCreateWallet return to void
esaugomez31 Apr 9, 2026
4343332
refactor: extract useSdkLifecycle and simplify wallet provider
esaugomez31 Apr 9, 2026
85e279e
refactor: improve home screen readability and remove dead code
esaugomez31 Apr 9, 2026
c327918
refactor: use wallet abstraction in backup-confirm and fix wallet-sna…
esaugomez31 Apr 9, 2026
1f0e090
fix: hide move-to-noncustodial setting when already self-custodial
esaugomez31 Apr 10, 2026
422773b
fix: reinit SDK after wallet creation to prevent stale unavailable st…
esaugomez31 Apr 10, 2026
8d5b18e
test: fix card transactions test order dependency
esaugomez31 Apr 11, 2026
d6e7ff4
fix: patch react-native-modal for New Architecture (Fabric) compatibi…
esaugomez31 Apr 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions __mocks__/@breeztech/breez-sdk-spark-react-native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* eslint-disable camelcase */
const SdkEvent_Tags = {
Synced: "Synced",
PaymentSucceeded: "PaymentSucceeded",
PaymentPending: "PaymentPending",
PaymentFailed: "PaymentFailed",
ClaimedDeposits: "ClaimedDeposits",
UnclaimedDeposits: "UnclaimedDeposits",
Optimization: "Optimization",
LightningAddressChanged: "LightningAddressChanged",
}

const PaymentDetails_Tags = {
Spark: "Spark",
Token: "Token",
Lightning: "Lightning",
Withdraw: "Withdraw",
Deposit: "Deposit",
}

module.exports = {
connect: jest.fn(),
defaultConfig: jest.fn().mockReturnValue({}),
initLogging: jest.fn(),
Network: { Mainnet: 0, Regtest: 1 },
Seed: { Mnemonic: jest.fn().mockImplementation((args) => args) },
StableBalanceActiveLabel: {
Set: jest.fn().mockImplementation((args) => ({ tag: "Set", inner: args })),
Unset: jest.fn().mockReturnValue({ tag: "Unset" }),
},
SdkEvent_Tags,
PaymentMethod: {
Lightning: 0,
Spark: 1,
Token: 2,
Deposit: 3,
Withdraw: 4,
Unknown: 5,
},
PaymentStatus: { Completed: 0, Pending: 1, Failed: 2 },
PaymentType: { Send: 0, Receive: 1 },
PaymentDetails_Tags,
}
6 changes: 6 additions & 0 deletions __mocks__/react-native-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
BREEZ_API_KEY: "test-api-key",
SPARK_TOKEN_IDENTIFIER: "test-token-id",
BREEZ_NETWORK: "regtest",
IGNORE_LOGS: "",
}
5 changes: 5 additions & 0 deletions __mocks__/react-native-fs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
DocumentDirectoryPath: "/mock/documents",
CachesDirectoryPath: "/mock/caches",
TemporaryDirectoryPath: "/mock/temp",
}
13 changes: 4 additions & 9 deletions __tests__/hooks/use-account-registry.spec.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { renderHook, act } from "@testing-library/react-native"

import {
AccountStatus,
AccountType,
CUSTODIAL_DEFAULT_ID,
SELF_CUSTODIAL_DEFAULT_ID,
} from "@app/types/wallet.types"
import { AccountStatus, AccountType, DefaultAccountId } from "@app/types/wallet.types"

import {
createCustodialDescriptor,
Expand Down Expand Up @@ -157,7 +152,7 @@ describe("createCustodialDescriptor", () => {
it("creates a custodial descriptor with correct defaults", () => {
const desc = createCustodialDescriptor("Blink")

expect(desc.id).toBe(CUSTODIAL_DEFAULT_ID)
expect(desc.id).toBe(DefaultAccountId.Custodial)
expect(desc.type).toBe(AccountType.Custodial)
expect(desc.label).toBe("Blink")
expect(desc.selected).toBe(false)
Expand All @@ -169,7 +164,7 @@ describe("createSelfCustodialDescriptor", () => {
it("creates a self-custodial descriptor with correct defaults", () => {
const desc = createSelfCustodialDescriptor("Spark")

expect(desc.id).toBe(SELF_CUSTODIAL_DEFAULT_ID)
expect(desc.id).toBe(DefaultAccountId.SelfCustodial)
expect(desc.type).toBe(AccountType.SelfCustodial)
expect(desc.label).toBe("Spark")
expect(desc.selected).toBe(false)
Expand All @@ -184,7 +179,7 @@ describe("markSelected", () => {
]

it("marks account matching activeId as selected", () => {
const result = markSelected(accounts, SELF_CUSTODIAL_DEFAULT_ID)
const result = markSelected(accounts, DefaultAccountId.SelfCustodial)

expect(result[0].selected).toBe(false)
expect(result[1].selected).toBe(true)
Expand Down
46 changes: 42 additions & 4 deletions __tests__/hooks/use-active-wallet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const mockActiveAccount = jest.fn()
const mockAccounts = jest.fn()
const mockSetActiveAccountId = jest.fn()
const mockCustodialState = jest.fn()
const mockSelfCustodialState = jest.fn()

jest.mock("@app/hooks/use-account-registry", () => ({
useAccountRegistry: () => ({
Expand All @@ -25,16 +26,33 @@ jest.mock("@app/custodial/providers/wallet-provider", () => ({
useCustodialWallet: () => mockCustodialState(),
}))

jest.mock("@app/self-custodial/providers/wallet-provider", () => ({
useSelfCustodialWallet: () => mockSelfCustodialState(),
}))

const custodialReady = {
wallets: [],
status: ActiveWalletStatus.Ready,
accountType: AccountType.Custodial,
}

const selfCustodialReady = {
wallets: [],
status: ActiveWalletStatus.Ready,
accountType: AccountType.SelfCustodial,
}

const selfCustodialUnavailable = {
wallets: [],
status: ActiveWalletStatus.Unavailable,
accountType: AccountType.SelfCustodial,
}

describe("useActiveWallet", () => {
beforeEach(() => {
jest.clearAllMocks()
mockCustodialState.mockReturnValue(custodialReady)
mockSelfCustodialState.mockReturnValue(selfCustodialUnavailable)
mockAccounts.mockReturnValue([])
})

Expand All @@ -48,19 +66,37 @@ describe("useActiveWallet", () => {

expect(result.current.status).toBe(ActiveWalletStatus.Ready)
expect(result.current.accountType).toBe(AccountType.Custodial)
expect(result.current.isReady).toBe(true)
expect(result.current.isSelfCustodial).toBe(false)
expect(result.current.needsBackendAuth).toBe(true)
})

it("returns unavailable placeholder when active account is self-custodial", () => {
it("returns self-custodial state when active account is self-custodial", () => {
mockActiveAccount.mockReturnValue({
id: "self-custodial-default",
id: "sc-default",
type: AccountType.SelfCustodial,
})
mockSelfCustodialState.mockReturnValue(selfCustodialReady)

const { result } = renderHook(() => useActiveWallet())

expect(result.current.status).toBe(ActiveWalletStatus.Unavailable)
expect(result.current.status).toBe(ActiveWalletStatus.Ready)
expect(result.current.accountType).toBe(AccountType.SelfCustodial)
expect(result.current.wallets).toHaveLength(0)
expect(result.current.isReady).toBe(true)
expect(result.current.isSelfCustodial).toBe(true)
expect(result.current.needsBackendAuth).toBe(false)
})

it("isSelfCustodial is false when self-custodial but unavailable", () => {
mockActiveAccount.mockReturnValue({
id: "sc-default",
type: AccountType.SelfCustodial,
})
mockSelfCustodialState.mockReturnValue(selfCustodialUnavailable)

const { result } = renderHook(() => useActiveWallet())

expect(result.current.isSelfCustodial).toBe(false)
})

it("returns unavailable custodial placeholder when no active account", () => {
Expand All @@ -70,5 +106,7 @@ describe("useActiveWallet", () => {

expect(result.current.status).toBe(ActiveWalletStatus.Unavailable)
expect(result.current.accountType).toBe(AccountType.Custodial)
expect(result.current.isReady).toBe(false)
expect(result.current.needsBackendAuth).toBe(true)
})
})
31 changes: 0 additions & 31 deletions __tests__/hooks/use-has-custodial-account.spec.ts

This file was deleted.

4 changes: 2 additions & 2 deletions __tests__/hooks/use-payments.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ describe("usePayments", () => {
const { result } = renderHook(() => usePayments())

expect(result.current.claimDeposit).toBeDefined()
expect(result.current.claimDeposit.getClaimFee).toBeDefined()
expect(result.current.claimDeposit.claimDeposit).toBeDefined()
expect(result.current.claimDeposit!.getClaimFee).toBeDefined()
expect(result.current.claimDeposit!.claimDeposit).toBeDefined()
})

it("returns convert adapter", () => {
Expand Down
18 changes: 9 additions & 9 deletions __tests__/hooks/use-self-custodial-rollback.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const custodialAccount = {
selected: false,
status: AccountStatus.Available,
}
const scAccount = {
const selfCustodialAccount = {
id: "sc-default",
type: AccountType.SelfCustodial,
label: "Self-custodial",
Expand All @@ -40,8 +40,8 @@ describe("useSelfCustodialRollback", () => {

renderHook(() =>
useSelfCustodialRollback({
activeAccount: scAccount,
accounts: [custodialAccount, scAccount],
activeAccount: selfCustodialAccount,
accounts: [custodialAccount, selfCustodialAccount],
setActiveAccountId: mockSetActiveAccountId,
}),
)
Expand All @@ -54,8 +54,8 @@ describe("useSelfCustodialRollback", () => {

renderHook(() =>
useSelfCustodialRollback({
activeAccount: scAccount,
accounts: [custodialAccount, scAccount],
activeAccount: selfCustodialAccount,
accounts: [custodialAccount, selfCustodialAccount],
setActiveAccountId: mockSetActiveAccountId,
}),
)
Expand All @@ -82,8 +82,8 @@ describe("useSelfCustodialRollback", () => {

renderHook(() =>
useSelfCustodialRollback({
activeAccount: scAccount,
accounts: [scAccount],
activeAccount: selfCustodialAccount,
accounts: [selfCustodialAccount],
setActiveAccountId: mockSetActiveAccountId,
}),
)
Expand All @@ -96,8 +96,8 @@ describe("useSelfCustodialRollback", () => {

const { rerender } = renderHook(() =>
useSelfCustodialRollback({
activeAccount: scAccount,
accounts: [custodialAccount, scAccount],
activeAccount: selfCustodialAccount,
accounts: [custodialAccount, selfCustodialAccount],
setActiveAccountId: mockSetActiveAccountId,
}),
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import React from "react"
import { render, screen, act } from "@testing-library/react-native"
import { render, screen } from "@testing-library/react-native"
import { loadLocale } from "@app/i18n/i18n-util.sync"

import { TransferringFundsScreen } from "@app/screens/account-migration/to-non-custodial/transferring-funds-screen"
import { ContextForScreen } from "../../helper"

loadLocale("en")

const mockReplace = jest.fn()

jest.mock("@react-navigation/native", () => ({
...jest.requireActual("@react-navigation/native"),
useNavigation: () => ({
replace: mockReplace,
}),
}))

jest.mock("@app/components/status-screen-layout", () => ({
StatusScreenLayout: ({ children }: { children: React.ReactNode }) => {
const { View } = jest.requireActual("react-native")
Expand All @@ -26,14 +17,9 @@ jest.mock("@app/components/status-screen-layout", () => ({
describe("TransferringFundsScreen", () => {
beforeEach(() => {
jest.clearAllMocks()
jest.useFakeTimers()
loadLocale("en")
})

afterEach(() => {
jest.useRealTimers()
})

it("renders transferring funds message", () => {
render(
<ContextForScreen>
Expand All @@ -46,33 +32,13 @@ describe("TransferringFundsScreen", () => {
).toBeTruthy()
})

it("navigates to success screen after timeout", async () => {
render(
<ContextForScreen>
<TransferringFundsScreen />
</ContextForScreen>,
)

expect(mockReplace).not.toHaveBeenCalled()

await act(() => {
jest.advanceTimersByTime(2000)
})

expect(mockReplace).toHaveBeenCalledWith("sparkBackupSuccessScreen")
})

it("does not navigate before timeout", async () => {
it("renders status layout", () => {
render(
<ContextForScreen>
<TransferringFundsScreen />
</ContextForScreen>,
)

await act(() => {
jest.advanceTimersByTime(1000)
})

expect(mockReplace).not.toHaveBeenCalled()
expect(screen.getByTestId("status-layout")).toBeTruthy()
})
})
Loading
Loading