diff --git a/packages/wallets/wallet-base/src/types/strategy.ts b/packages/wallets/wallet-base/src/types/strategy.ts index 7066fa0d9..42acf926a 100644 --- a/packages/wallets/wallet-base/src/types/strategy.ts +++ b/packages/wallets/wallet-base/src/types/strategy.ts @@ -115,13 +115,17 @@ export interface ConcreteCosmosWalletStrategy { }): Promise } +export type ConcreteStrategiesArg = { + [key in Wallet]?: ConcreteWalletStrategy +} + export interface WalletStrategyArguments { chainId: ChainId options?: ConcreteWalletStrategyOptions ethereumOptions?: WalletStrategyEthereumOptions disabledWallets?: Wallet[] wallet?: Wallet - strategies: Record + strategies: ConcreteStrategiesArg } export interface ConcreteWalletStrategy @@ -224,7 +228,7 @@ export interface ConcreteWalletStrategy } export interface WalletStrategy { - strategies: Record + strategies: ConcreteStrategiesArg wallet: Wallet args: WalletStrategyArguments diff --git a/packages/wallets/wallet-core/README.md b/packages/wallets/wallet-core/README.md index 3e907bc8a..e8e1d3d14 100644 --- a/packages/wallets/wallet-core/README.md +++ b/packages/wallets/wallet-core/README.md @@ -13,14 +13,32 @@ _Package to use MetaMask Wallets on Injective via the wallet strategy._ ## 📚 Installation ```bash -yarn add @injectivelabs/wallet-evm +yarn add @injectivelabs/wallet-cire ``` --- ## 📖 Documentation - +To instantiate your MsgBroadcaster, you need to pass it an instance of `BaseWalletStrategy`. You can specify any strategy you want in the `BaseWalletStrategy` constructor and pass it to the `MsgBroadcaster`. + +```ts +import { Wallet } from '@injectivelabs/wallet-base' +import { BaseWalletStrategy } from '@injectivelabs/wallet-core' +import { PrivateKeyWalletStrategy } from '@injectivelabs/wallet-private-key' + +const strategyArgs: WalletStrategyArguments = {} /** define the args */ +const strategyEthArgs: ConcreteEthereumWalletStrategyArgs = {} /** if the wallet is an Ethereum wallet */ +const strategies = { + [Wallet.PrivateKey]: new PrivateKeyWalletStrategy(strategyEthArgs) +} + +export const walletStrategy = new BaseWalletStrategy({...strategyArgs, strategies}) + +const broadcasterArgs: MsgBroadcasterOptions = {} /** define the broadcaster args */ +export const msgBroadcaster = new MsgBroadcaster({...broadcasterArgs, walletStrategy}) +``` + Read more and find example usages on our [WalletStrategy Docs](https://docs.ts.injective.network/wallet/wallet-wallet-strategy) diff --git a/packages/wallets/wallet-core/src/broadcaster/MsgBroadcaster.spec.ts b/packages/wallets/wallet-core/src/broadcaster/MsgBroadcaster.spec.ts new file mode 100644 index 000000000..1f5c5b2c4 --- /dev/null +++ b/packages/wallets/wallet-core/src/broadcaster/MsgBroadcaster.spec.ts @@ -0,0 +1,109 @@ +import { Network } from '@injectivelabs/networks' +import { MsgBroadcaster } from './MsgBroadcaster' +import { MsgBroadcasterOptions } from './types' +import { + Wallet, + WalletStrategyArguments, + ConcreteEthereumWalletStrategyArgs, +} from '@injectivelabs/wallet-base' +import { EthereumChainId } from '@injectivelabs/ts-types' +import { PrivateKeyWalletStrategy } from '@injectivelabs/wallet-private-key' + +const strategyArgs: WalletStrategyArguments = {} /** define the args */ +const strategyEthArgs: ConcreteEthereumWalletStrategyArgs = + {} /** if the wallet is an Ethereum wallet */ +const strategies = { + [Wallet.PrivateKey]: new PrivateKeyWalletStrategy(strategyEthArgs), +} + +export const walletStrategy = new BaseWalletStrategy({ + ...strategyArgs, + strategies, +}) + +const broadcasterArgs: MsgBroadcasterOptions = + {} /** define the broadcaster args */ +export const msgBroadcaster = new MsgBroadcaster({ + ...broadcasterArgs, + walletStrategy, +}) + +describe('MsgBroadcaster', () => { + test('prepares, simulates, signs and broadcasts a transaction', async () => { + const privateKey = PrivateKey.fromHex( + process.env.TEST_PRIVATE_KEY as string, + ) + + const network = Network.Devnet + const injectiveAddress = privateKey.toBech32() + + const message = MsgSend.fromJSON({ + srcInjectiveAddress: injectiveAddress, + dstInjectiveAddress: injectiveAddress, + amount: { + amount: '1', + denom: 'inj', + }, + }) + + const response = await new MsgBroadcasterWithPk({ + network, + privateKey, + simulateTx: true, + }).broadcast({ msgs: message }) + + expect(response.txHash).toBeDefined() + }, 60000) + + test.skip('prepares, simulates, signs and broadcasts a transaction with fee delegation', async () => { + const privateKey = PrivateKey.fromHex( + process.env.TEST_PRIVATE_KEY as string, + ) + + const network = Network.Devnet + const injectiveAddress = privateKey.toBech32() + + const message = MsgSend.fromJSON({ + srcInjectiveAddress: injectiveAddress, + dstInjectiveAddress: injectiveAddress, + amount: { + amount: '1', + denom: 'inj', + }, + }) + + const response = await new MsgBroadcasterWithPk({ + network, + privateKey, + simulateTx: true, + ethereumChainId: EthereumChainId.Sepolia, + }).broadcastWithFeeDelegation({ msgs: message }) + + expect(response.txHash).toBeDefined() + }, 60000) + + test.skip('simulates a transaction', async () => { + const privateKey = PrivateKey.fromHex( + process.env.TEST_PRIVATE_KEY as string, + ) + + const network = Network.Devnet + const injectiveAddress = privateKey.toBech32() + + const message = MsgSend.fromJSON({ + srcInjectiveAddress: injectiveAddress, + dstInjectiveAddress: injectiveAddress, + amount: { + amount: '1', + denom: 'inj', + }, + }) + + const response = await new MsgBroadcasterWithPk({ + network, + privateKey, + }).simulate({ msgs: message }) + + expect(response.result).toBeDefined() + }, 60000) +}) diff --git a/packages/wallets/wallet-core/src/strategy/BaseWalletStrategy.ts b/packages/wallets/wallet-core/src/strategy/BaseWalletStrategy.ts index 53407146f..a20d1beaa 100644 --- a/packages/wallets/wallet-core/src/strategy/BaseWalletStrategy.ts +++ b/packages/wallets/wallet-core/src/strategy/BaseWalletStrategy.ts @@ -1,8 +1,8 @@ import { TxRaw, TxResponse } from '@injectivelabs/sdk-ts' import { DirectSignResponse } from '@cosmjs/proto-signing' import { - AccountAddress, ChainId, + AccountAddress, EthereumChainId, } from '@injectivelabs/ts-types' import { GeneralException, WalletException } from '@injectivelabs/exceptions' @@ -11,6 +11,7 @@ import { isEthWallet, isCosmosWallet, WalletDeviceType, + ConcreteStrategiesArg, SendTransactionOptions, ConcreteWalletStrategy, onAccountChangeCallback, @@ -34,7 +35,7 @@ const getInitialWallet = (args: WalletStrategyArguments): Wallet => { } export default class BaseWalletStrategy implements WalletStrategyInterface { - public strategies: Record + public strategies: ConcreteStrategiesArg public wallet: Wallet diff --git a/packages/wallets/wallet-private-key/src/strategy/strategy.spec.ts b/packages/wallets/wallet-private-key/src/strategy/strategy.spec.ts new file mode 100644 index 000000000..dad935bc8 --- /dev/null +++ b/packages/wallets/wallet-private-key/src/strategy/strategy.spec.ts @@ -0,0 +1,53 @@ +import { Network } from '@injectivelabs/networks' +import { + MsgBroadcaster, + BaseWalletStrategy, + MsgBroadcasterOptions, +} from '@injectivelabs/wallet-core' +import { Wallet, WalletStrategyArguments } from '@injectivelabs/wallet-base' +import { MsgSend, PrivateKey } from '@injectivelabs/sdk-ts' +import { ChainId, EthereumChainId } from '@injectivelabs/ts-types' +import { PrivateKeyWalletStrategy } from '@injectivelabs/wallet-private-key' + +const strategyArgs: WalletStrategyArguments = { + chainId: ChainId.Devnet, + wallet: Wallet.PrivateKey, + strategies: { + [Wallet.PrivateKey]: new PrivateKeyWalletStrategy({ + chainId: ChainId.Devnet, + ethereumOptions: { + ethereumChainId: EthereumChainId.Sepolia, + rpcUrl: '', + }, + privateKey: process.env.TEST_PRIVATE_KEY as string, + }), + }, +} +const walletStrategy = new BaseWalletStrategy(strategyArgs) + +const broadcasterArgs: MsgBroadcasterOptions = { + walletStrategy, + simulateTx: true, + network: Network.Devnet, +} +const msgBroadcaster = new MsgBroadcaster(broadcasterArgs) + +describe('MsgBroadcaster', () => { + test('prepares, simulates, signs and broadcasts a transaction', async () => { + const pk = PrivateKey.fromHex(process.env.TEST_PRIVATE_KEY as string) + const injectiveAddress = pk.toBech32() + + const message = MsgSend.fromJSON({ + srcInjectiveAddress: injectiveAddress, + dstInjectiveAddress: injectiveAddress, + amount: { + amount: '1', + denom: 'inj', + }, + }) + + const response = await msgBroadcaster.broadcast({ msgs: message }) + + expect(response.txHash).toBeDefined() + }, 60000) +}) diff --git a/packages/wallets/wallet-strategy/src/strategy/WalletStrategy.ts b/packages/wallets/wallet-strategy/src/strategy/WalletStrategy.ts index 5e77ab408..b61f767d2 100644 --- a/packages/wallets/wallet-strategy/src/strategy/WalletStrategy.ts +++ b/packages/wallets/wallet-strategy/src/strategy/WalletStrategy.ts @@ -2,6 +2,7 @@ import { Wallet, isEthWallet, MagicMetadata, + ConcreteStrategiesArg, ConcreteWalletStrategy, WalletStrategyArguments, ConcreteWalletStrategyOptions, @@ -127,13 +128,13 @@ const createStrategy = ({ const createAllStrategies = ( args: WalletStrategyArguments, -): Record => { +): ConcreteStrategiesArg => { return Object.values(Wallet).reduce( (strategies, wallet) => ({ ...strategies, [wallet]: createStrategy({ args, wallet: wallet as Wallet }), }), - {} as Record, + {} as ConcreteStrategiesArg, ) }