Skip to content
This repository has been archived by the owner on Oct 10, 2023. It is now read-only.

Commit

Permalink
Introduce CosmosClient (#2291)
Browse files Browse the repository at this point in the history
  • Loading branch information
veado authored Jun 14, 2022
1 parent 1eea9fb commit 66e9315
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
67 changes: 67 additions & 0 deletions src/renderer/services/cosmos/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import * as RD from '@devexperts/remote-data-ts'
import { Client } from '@xchainjs/xchain-cosmos'
import { CosmosChain } from '@xchainjs/xchain-util'
import * as FP from 'fp-ts/lib/function'
import * as O from 'fp-ts/lib/Option'
import * as Rx from 'rxjs'
import * as RxOp from 'rxjs/operators'

import { isError } from '../../../shared/utils/guard'
import { clientNetwork$ } from '../app/service'
import * as C from '../clients'
import { keystoreService } from '../wallet/keystore'
import { getPhrase } from '../wallet/util'
import type { Client$, ClientState, ClientState$ } from './types'

/**
* Stream to create an observable `CosmosClient` depending on existing phrase in keystore
*
* Whenever a phrase has been added to keystore, a new `CosmosClient` will be created.
* By the other hand: Whenever a phrase has been removed, `ClientState` is set to `initial`
* A `CosmosClient` will never be created as long as no phrase is available
*/
const clientState$: ClientState$ = FP.pipe(
Rx.combineLatest([keystoreService.keystore$, clientNetwork$]),
RxOp.switchMap(
([keystore, network]): ClientState$ =>
Rx.of(
FP.pipe(
getPhrase(keystore),
O.map<string, ClientState>((phrase) => {
try {
const client = new Client({
network,
phrase
})
return RD.success(client)
} catch (error) {
return RD.failure<Error>(isError(error) ? error : new Error('Failed to create Cosmos client'))
}
}),
// Set back to `initial` if no phrase is available (locked wallet)
O.getOrElse<ClientState>(() => RD.initial)
)
)
),
RxOp.startWith<ClientState>(RD.initial),
RxOp.shareReplay(1)
)

const client$: Client$ = clientState$.pipe(RxOp.map(RD.toOption), RxOp.shareReplay(1))

/**
* `Address`
*/
const address$: C.WalletAddress$ = C.address$(client$, CosmosChain)

/**
* `Address`
*/
const addressUI$: C.WalletAddress$ = C.addressUI$(client$, CosmosChain)

/**
* Explorer url depending on selected network
*/
const explorerUrl$: C.ExplorerUrl$ = C.explorerUrl$(client$)

export { client$, clientState$, address$, addressUI$, explorerUrl$ }
3 changes: 3 additions & 0 deletions src/renderer/services/cosmos/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { client$, clientState$, address$, addressUI$, explorerUrl$ } from './common'

export { client$, clientState$, address$, addressUI$, explorerUrl$ }
8 changes: 8 additions & 0 deletions src/renderer/services/cosmos/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Client } from '@xchainjs/xchain-cosmos'

import * as C from '../clients'

export type Client$ = C.Client$<Client>

export type ClientState = C.ClientState<Client>
export type ClientState$ = C.ClientState$<Client>

0 comments on commit 66e9315

Please sign in to comment.