import { AccountAddress, CosmosChainId } from '../../../'; import { DirectSignResponse } from '@cosmjs/proto-signing'; import { GeneralException } from '../../../exceptions'; import { TxRaw } from '@routerprotocol/chain-api/cosmos/tx/v1beta1/tx_pb'; import { Wallet, WalletDeviceType } from '../../types/enums'; import Keplr from './strategies/Keplr'; import Leap from './strategies/Leap'; import Cosmostation from './strategies/Cosmostation'; import { ConcreteCosmosWalletStrategy, CosmosWalletStrategyArguments, } from '../types/strategy'; import { isCosmosWallet } from '../../wallets/cosmos/utils'; export const cosmosWallets = [Wallet.Keplr, Wallet.Leap, Wallet.Cosmostation]; const createWallet = ({ wallet, args, }: { wallet: Wallet; args: CosmosWalletStrategyArguments; }): ConcreteCosmosWalletStrategy | undefined => { switch (wallet) { case Wallet.Keplr: return new Keplr({ ...args }); case Wallet.Leap: return new Leap({ ...args }); case Wallet.Cosmostation: return new Cosmostation({ ...args }); default: throw new GeneralException( new Error(`The ${wallet} concrete wallet strategy is not supported`) ); } }; const createWallets = ( args: CosmosWalletStrategyArguments ): Record => cosmosWallets.reduce( (strategies, wallet) => ({ ...strategies, [wallet]: createWallet({ wallet, args }), }), {} as Record ); export default class CosmosWalletStrategy { public strategies: Record; public wallet: Wallet; constructor(args: CosmosWalletStrategyArguments) { this.strategies = createWallets(args); this.wallet = args.wallet || Wallet.Keplr; } public getWallet(): Wallet { return this.wallet; } public setWallet(wallet: Wallet) { this.wallet = isCosmosWallet(wallet) ? wallet : Wallet.Keplr; } public getStrategy(): ConcreteCosmosWalletStrategy { if (!this.strategies[this.wallet]) { throw new GeneralException( new Error(`Wallet ${this.wallet} is not enabled/available!`) ); } return this.strategies[this.wallet] as ConcreteCosmosWalletStrategy; } public getWalletDeviceType(): Promise { return this.getStrategy().getWalletDeviceType(); } public getPubKey(): Promise { return this.getStrategy().getPubKey(); } public getAddresses(): Promise { return this.getStrategy().getAddresses(); } public isChainIdSupported(chainId?: CosmosChainId): Promise { return this.getStrategy().isChainIdSupported(chainId); } public async sendTransaction(tx: DirectSignResponse): Promise { return this.getStrategy().sendTransaction(tx); } public async signTransaction( transaction: { txRaw: TxRaw; accountNumber: number; chainId: string }, address: string ): Promise { return this.getStrategy().signTransaction(transaction, address); } }