Skip to content

Commit

Permalink
feat: add resetNetwork option to WalletManager (#260)
Browse files Browse the repository at this point in the history
- Introduce `options` object in `WalletManagerConfig`
- Add `resetNetwork` as the first option
- Implement `resetNetwork` functionality in `WalletManager` constructor
- Update tests to cover `resetNetwork` behavior

This change allows users to configure additional behaviors through the `options` object. The `resetNetwork` option, when true, resets the network to the configured value on each initialization, overriding any persisted network state. (This is the first of several planned configuration options.)
  • Loading branch information
drichar committed Sep 13, 2024
1 parent 9943725 commit 70b8454
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 11 deletions.
94 changes: 94 additions & 0 deletions packages/use-wallet/src/__tests__/manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -466,4 +466,98 @@ describe('WalletManager', () => {
expect(kibisisDisconnectMock).not.toHaveBeenCalled()
})
})

describe('options', () => {
describe('resetNetwork', () => {
let mockInitialState: State | null = null

beforeEach(() => {
vi.clearAllMocks()

vi.mocked(StorageAdapter.getItem).mockImplementation((key: string) => {
if (key === LOCAL_STORAGE_KEY && mockInitialState !== null) {
return JSON.stringify(mockInitialState)
}
return null
})

// Reset to null before each test
mockInitialState = null
})

it('uses the default network when resetNetwork is true, ignoring persisted state', () => {
mockInitialState = {
wallets: {},
activeWallet: null,
activeNetwork: NetworkId.MAINNET,
algodClient: new Algodv2('', 'https://mainnet-api.algonode.cloud')
}

const manager = new WalletManager({
wallets: [],
network: NetworkId.TESTNET,
options: { resetNetwork: true }
})

expect(manager.activeNetwork).toBe(NetworkId.TESTNET)
})

it('uses the persisted network when resetNetwork is false', () => {
mockInitialState = {
wallets: {},
activeWallet: null,
activeNetwork: NetworkId.MAINNET,
algodClient: new Algodv2('', 'https://mainnet-api.algonode.cloud')
}

const manager = new WalletManager({
wallets: [],
network: NetworkId.TESTNET,
options: { resetNetwork: false }
})

expect(manager.activeNetwork).toBe(NetworkId.MAINNET)
})

it('uses the default network when resetNetwork is false and no persisted state exists', () => {
const manager = new WalletManager({
wallets: [],
network: NetworkId.TESTNET,
options: { resetNetwork: false }
})

expect(manager.activeNetwork).toBe(NetworkId.TESTNET)
})

it('preserves wallet state when resetNetwork is true, only changing the network', () => {
mockInitialState = {
wallets: {
[WalletId.PERA]: {
accounts: [{ name: 'Account 1', address: 'address1' }],
activeAccount: { name: 'Account 1', address: 'address1' }
}
},
activeWallet: WalletId.PERA,
activeNetwork: NetworkId.MAINNET,
algodClient: new Algodv2('', 'https://mainnet-api.algonode.cloud')
}

const manager = new WalletManager({
wallets: [WalletId.PERA],
network: NetworkId.TESTNET,
options: { resetNetwork: true }
})

// Check that the network is forced to TESTNET
expect(manager.activeNetwork).toBe(NetworkId.TESTNET)

// Check that the wallet state is preserved
expect(manager.store.state.wallets[WalletId.PERA]).toEqual({
accounts: [{ name: 'Account 1', address: 'address1' }],
activeAccount: { name: 'Account 1', address: 'address1' }
})
expect(manager.store.state.activeWallet).toBe(WalletId.PERA)
})
})
})
})
47 changes: 36 additions & 11 deletions packages/use-wallet/src/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export interface WalletManagerConfig {
wallets?: SupportedWallet[]
network?: NetworkId
algod?: NetworkConfig
options?: {
resetNetwork?: boolean
}
}

export type PersistedState = Omit<State, 'algodClient'>
Expand All @@ -46,27 +49,48 @@ export class WalletManager {
public store: Store<State>
public subscribe: (callback: (state: State) => void) => () => void

constructor({ wallets = [], network = NetworkId.TESTNET, algod = {} }: WalletManagerConfig = {}) {
public options: { resetNetwork: boolean }

constructor({
wallets = [],
network = NetworkId.TESTNET,
algod = {},
options = {}
}: WalletManagerConfig = {}) {
// Initialize network config
this.networkConfig = this.initNetworkConfig(network, algod)

// Initialize options
this.options = { resetNetwork: options.resetNetwork || false }

// Load persisted state from local storage
const persistedState = this.loadPersistedState()
const initialState: State = persistedState
? {
...persistedState,
algodClient: this.createAlgodClient(this.networkConfig[persistedState.activeNetwork])
}
: {
...defaultState,
activeNetwork: network,
algodClient: this.createAlgodClient(this.networkConfig[network])
}

// Set active network
const activeNetwork = this.options.resetNetwork
? network
: persistedState?.activeNetwork || network

// Create Algod client for active network
const algodClient = this.createAlgodClient(this.networkConfig[activeNetwork])

// Create initial state
const initialState: State = {
...defaultState,
...persistedState,
activeNetwork,
algodClient
}

// Create store
this.store = new Store<State>(initialState, {
onUpdate: () => this.savePersistedState()
})

// Save persisted state immediately
this.savePersistedState()

// Subscribe to store updates
this.subscribe = (callback: (state: State) => void): (() => void) => {
const unsubscribe = this.store.subscribe(() => {
callback(this.store.state)
Expand All @@ -75,6 +99,7 @@ export class WalletManager {
return unsubscribe
}

// Initialize wallets
this.initializeWallets(wallets)
}

Expand Down

0 comments on commit 70b8454

Please sign in to comment.