import { KVStore , toGenerator } from "@keplr-wallet/common" ; import { flow , makeObservable , observable , runInAction } from "mobx" ; import { computedFn } from "mobx-utils" ; import { Channel } from "./types" ; import { HasMapStore } from "../common" ; import { ChainIdHelper } from "@keplr-wallet/cosmos" ; export class IBCChannelStoreInner { @ observable . shallow protected channelMap : Map < string , Map < string , Channel > > = new Map ( ) ; constructor ( protected readonly kvStore , protected readonly chainId ) { makeObservable ( this ) ; this . loadChannels ( ) ; } getTransferChannels ( ) { return this . getChannelsToPort ( "transfer" ) ; } readonly getChannelsToPort = computedFn ( ( portId ) => { if ( ! this . channelMap . has ( portId ) ) { runInAction ( ( ) => { this . channelMap . set ( portId , observable . map ( { } , { deep : false , } ) ) ; } ) ; } const channelMapOfPort = this . channelMap . get ( portId ) ! ; const channels = [ ] ; for ( const channel of channelMapOfPort . values ( ) ) { channels . push ( channel ) ; } return channels ; } ) ; readonly getChannel = computedFn ( ( portId , channelId ) => { return this . channelMap . get ( portId ) ?. get ( channelId ) ; } ) ; @ flow * addChannel ( channel ) { if ( ! this . channelMap . has ( channel . portId ) ) { this . channelMap . set ( channel . portId , observable . map ( { } , { deep : false , } ) ) ; } this . channelMap . get ( channel . portId ) ! . set ( channel . channelId , channel ) ; yield this . saveChannels ( ) ; } @ flow protected * loadChannels ( ) { const obj = yield * toGenerator ( this . kvStore . get < { [ portId ] : { [ channelId ] : Channel ; } ; } > ( `${ ChainIdHelper . parse ( this . chainId ) . identifier }-channels` ) ) ; if ( obj ) { for ( const portId of Object . keys ( obj ) ) { const map = obj [ portId ] ; for ( const channelId of Object . keys ( map ) ) { if ( ! this . channelMap . has ( portId ) ) { this . channelMap . set ( portId , observable . map ( { } , { deep : false } ) ) ; } const innerMap = this . channelMap . get ( portId ) ! ; innerMap . set ( channelId , map [ channelId ] ) ; } } } } async saveChannels ( ) { const obj = { } ; this . channelMap . forEach ( ( v , portId ) => { obj [ portId ] = ( ( ) => { const obj = { } ; v . forEach ( ( channel , channelId ) => { obj [ channelId ] = channel ; } ) ; return obj ; } ) ( ) ; } ) ; await this . kvStore . set ( `${ ChainIdHelper . parse ( this . chainId ) . identifier }-channels` , obj ) ; } } /**
 * IBCChannelStore saves the IBC channel infomations to the storage.
 */ export class IBCChannelStore extends HasMapStore < IBCChannelStoreInner > { constructor ( protected readonly kvStore ) { super ( ( chainId ) => { return new IBCChannelStoreInner ( kvStore , chainId ) ; } ) ; } get ( chainId ) { return super . get ( chainId ) ; } }