July 30, 2023

Injective Typescript Wallet Strategy

Основная цель @injectivelabs/wallet-ts - предоставить разработчикам возможность иметь различные реализации кошельков в Injective. Все реализации этих кошельков открывают один и тот же интерфейс ConcreteStrategy, что означает, что пользователи могут просто использовать эти методы без необходимости знать базовые реализации конкретных кошельков, поскольку они абстрагированы от них.
Для начала необходимо создать экземпляр класса WalletStrategy, что дает возможность использовать различные кошельки. Переключить текущий используемый кошелек можно с помощью метода setWallet экземпляра walletStrategy.
Рассмотрим, какие методы открывает стратегия WalletStrategy и что они означают:

Нативные кошельки Ethereum и Cosmos:

getAddresses получает адреса из подключенного к стратегии кошелька. Этот метод возвращает Ethereum-адреса для Ethereum native кошельков (стратегий) и Injective-адреса для Cosmos native кошельков (стратегий).
signTransaction подписывает транзакцию, используя метод соответствующего типа кошелька (signCosmosTransaction для нативных кошельков Cosmos, signEip712TypedData для нативных кошельков Ethereum)
sendTransaction подписывает транзакцию, используя метод, соответствующий типу кошелька (если мы хотим использовать этот метод на родных кошельках Ethereum, то в опции необходимо передать sentryEndpoint - пояснения можно найти ниже)
getWalletDeviceType возвращает тип подключения к кошельку (мобильный, браузерный, аппаратный),
Нативные кошельки Cosmos:
signCosmosTransaction подписывает инъекционную транзакцию, используя стратегию подключенного кошелька,
getPublicKey получает открытый ключ для стратегий нативного кошелька

Cosmos,Ethereum native wallets:
getEthereumChainId получить идентификатор цепочки для стратегий нативных кошельков Ethereum,
signEip712TypedData подписать типизированные данные EIP712 с помощью стратегии подключенного кошелька,
sendEthereumTransaction отправляет транзакцию Ethereum Web3, используя стратегию подключенного кошелька,
signEthereumTransaction подписывает транзакцию Ethereum Web3 с использованием стратегии подключенного кошелька,
getEthereumTransactionReceipt получает чек транзакции для нативных транзакций Ethereum для стратегии кошелька,

Аргументы
Аргументы, передаваемые WalletStrategy, имеют следующий интерфейс:

export interface WalletStrategyEthereumOptions { rpcUrl: string // rpc url needed **ONLY** the Ethereum native methods on the strategies ethereumChainId: EthereumChainId // needed if you are signing EIP712 typed data using the Wallet Strategies }

export interface EthereumWalletStrategyArgs { chainId: ChainId // the Injective chain id ethereumOptions?: WalletStrategyEthereumOptions // optional, needed only if you are using Ethereum native wallets disabledWallets?: Wallet[] // optional, needed if you wanna disable some wallets for being instantiated wallet?: Wallet // optional, the initial wallet selected (defaults to Metamask if `ethereumOptions` are passed and Keplr if they are not) }

Примечание: Когда мы хотим использовать sendTransaction на родных кошельках Ethereum, наряду с другими опциями (chainId и адрес) нам также необходимо передать конечную точку gRPC часовому для трансляции транзакции. Это необходимо потому, что для родных кошельков Ethereum у нас нет доступа к методу broadcastTx, как в случае с Keplr или Leap, чтобы транслировать транзакцию, используя абстракцию кошелька, поэтому мы должны транслировать ее на стороне клиента непосредственно в цепочку.

Пример использования:

import { WalletStrategy } from '@injectivelabs/wallet-ts' import { EthereumChainId, ChainId } from '@injectivelabs/ts-types' import { CHAIN_ID, ETHEREUM_CHAIN_ID, IS_TESTNET } from '~/app/utils/constants'

export const alchemyRpcEndpoint = `https://eth-mainnet.alchemyapi.io/v2/${process.env.ALCHEMY_KEY}`

export const walletStrategy = new WalletStrategy({ chainId: ChainId.Mainnet, ethereumOptions: { ethereumChainId: EthereumChainId.Mainnet, rpcUrl: alchemyRpcEndpoint } })

// Get wallet's addresses export const getAddresses = async (): Promise<string[]> => { const addresses = await walletStrategy.getAddresses()

if (addresses.length === 0) { throw new Web3Exception('There are no addresses linked in this wallet.') }

return addresses }

// Sign an Injective transaction export const signTransaction = async (tx: TxRaw): Promise<string[]> => { const response = await walletStrategy.signCosmosTransaction( transaction: { txRaw: tx; accountNumber: /* */; chainId: 'injective-1' }, address: 'inj1...', )

return response }

// Send an Injective transaction export const signTransaction = async (tx: TxRaw): Promise<string[]> => { const response = await walletStrategy.sendTransaction( txRaw, // `sentryEndpoint` needed if Ethereum wallets are used {address: 'inj1...', chainId: 'injective-1', sentryEndpoint: 'https://grpc.injective.network' } )

return response }