-
Notifications
You must be signed in to change notification settings - Fork 196
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support FoxWallet #514
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,287 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* eslint-disable class-methods-use-this */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { sleep } from '@injectivelabs/utils' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { AccountAddress, EthereumChainId } from '@injectivelabs/ts-types' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
ErrorType, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
CosmosWalletException, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
WalletException, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
UnspecifiedErrorCode, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
TransactionException, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} from '@injectivelabs/exceptions' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { DirectSignResponse } from '@cosmjs/proto-signing' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { TxRaw, toUtf8, TxGrpcApi, TxResponse } from '@injectivelabs/sdk-ts' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
ConcreteWalletStrategy, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
EthereumWalletStrategyArgs, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} from '../../../types' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { BrowserEip1993Provider, SendTransactionOptions } from '../../types' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
import BaseConcreteStrategy from './../Base' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
WalletAction, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
WalletDeviceType, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
WalletEventListener, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} from '../../../../types/enums' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { getFoxWalletProvider } from './utils' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
export default class FoxWallet | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
extends BaseConcreteStrategy | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
implements ConcreteWalletStrategy | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
constructor(args: EthereumWalletStrategyArgs) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
super(args) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
async getWalletDeviceType(): Promise<WalletDeviceType> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
return Promise.resolve(WalletDeviceType.Browser) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
async enable(): Promise<boolean> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
return Promise.resolve(true) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
public async disconnect() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (this.listeners[WalletEventListener.ChainIdChange]) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ethereum = await this.getEthereum() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
ethereum.removeListener( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
'chainChanged', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.listeners[WalletEventListener.ChainIdChange], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.listeners = {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
async getAddresses(): Promise<string[]> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ethereum = await this.getEthereum() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
return await ethereum.request({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
method: 'eth_requestAccounts', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (e: unknown) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new CosmosWalletException(new Error((e as any).message), { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
code: UnspecifiedErrorCode, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
type: ErrorType.WalletError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
contextModule: WalletAction.GetAccounts, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
// eslint-disable-next-line class-methods-use-this | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
async getSessionOrConfirm(address: AccountAddress): Promise<string> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
return Promise.resolve( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
`0x${Buffer.from( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
`Confirmation for ${address} at time: ${Date.now()}`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
).toString('hex')}`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
async sendEthereumTransaction( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
transaction: unknown, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
_options: { address: AccountAddress; ethereumChainId: EthereumChainId }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
): Promise<string> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ethereum = await this.getEthereum() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
return await ethereum.request({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
method: 'eth_sendTransaction', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
params: [transaction], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (e: unknown) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new CosmosWalletException(new Error((e as any).message), { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
code: UnspecifiedErrorCode, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
type: ErrorType.WalletError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
contextModule: WalletAction.SendEthereumTransaction, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
async sendTransaction( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
transaction: TxRaw, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
options: SendTransactionOptions, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
): Promise<TxResponse> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { endpoints, txTimeout } = options | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!endpoints) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new WalletException( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
new Error( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
'You have to pass endpoints within the options for using Ethereum native wallets', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
const txApi = new TxGrpcApi(endpoints.grpc) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const response = await txApi.broadcast(transaction, { txTimeout }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (response.code !== 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new TransactionException(new Error(response.rawLog), { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
code: UnspecifiedErrorCode, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
contextCode: response.code, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
contextModule: response.codespace, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
return response | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
/** @deprecated */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
async signTransaction( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
eip712json: string, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
address: AccountAddress, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
): Promise<string> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this.signEip712TypedData(eip712json, address) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
async signEip712TypedData( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
eip712json: string, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
address: AccountAddress, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
): Promise<string> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ethereum = await this.getEthereum() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
return await ethereum.request({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
method: 'eth_signTypedData_v4', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
params: [eip712json, address], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct parameter order for The parameters for Apply this diff to fix the parameter order: method: 'eth_signTypedData_v4',
- params: [eip712json, address],
+ params: [address, eip712json], 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (e: unknown) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new CosmosWalletException(new Error((e as any).message), { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
code: UnspecifiedErrorCode, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
type: ErrorType.WalletError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
contextModule: WalletAction.SignTransaction, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
async signAminoCosmosTransaction(_transaction: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
signDoc: any | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
accountNumber: number | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
chainId: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
address: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}): Promise<string> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new WalletException( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
new Error('This wallet does not support signing Cosmos transactions'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
code: UnspecifiedErrorCode, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
type: ErrorType.WalletError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
contextModule: WalletAction.SendTransaction, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
// eslint-disable-next-line class-methods-use-this | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
async signCosmosTransaction(_transaction: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
txRaw: TxRaw | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
accountNumber: number | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
chainId: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
address: string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}): Promise<DirectSignResponse> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new WalletException( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
new Error('This wallet does not support signing Cosmos transactions'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
code: UnspecifiedErrorCode, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
type: ErrorType.WalletError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
contextModule: WalletAction.SendTransaction, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
async signArbitrary( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
signer: AccountAddress, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
data: string | Uint8Array, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
): Promise<string> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ethereum = await this.getEthereum() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const signature = await ethereum.request({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
method: 'personal_sign', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
params: [toUtf8(data), signer], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Convert data to a hex string for The Apply this diff to convert the data to a hex string: - params: [toUtf8(data), signer],
+ params: [`0x${Buffer.from(data).toString('hex')}`, signer], Ensure that 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
return signature | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (e: unknown) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new CosmosWalletException(new Error((e as any).message), { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
code: UnspecifiedErrorCode, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
type: ErrorType.WalletError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
contextModule: WalletAction.SignArbitrary, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
async getEthereumChainId(): Promise<string> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ethereum = await this.getEthereum() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
return ethereum.request({ method: 'eth_chainId' }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (e: unknown) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new CosmosWalletException(new Error((e as any).message), { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
code: UnspecifiedErrorCode, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
type: ErrorType.WalletError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
contextModule: WalletAction.GetChainId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+217
to
+222
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Use appropriate exception type for Ethereum-related errors In Ethereum-related methods, wrapping errors in Update the exception to use - throw new CosmosWalletException(new Error((e as any).message), {
+ throw new WalletException(new Error((e as any).message), { Apply similar changes in other Ethereum-related methods where
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
async getEthereumTransactionReceipt(txHash: string): Promise<string> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ethereum = await this.getEthereum() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
const interval = 1000 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const transactionReceiptRetry = async () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const receipt = await ethereum.request({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
method: 'eth_getTransactionReceipt', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
params: [txHash], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!receipt) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
await sleep(interval) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
await transactionReceiptRetry() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
return receipt | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+229
to
+241
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid potential stack overflow due to recursive retry logic The Refactor the function to use a loop instead of recursion: const transactionReceiptRetry = async () => {
- const receipt = await ethereum.request({
- method: 'eth_getTransactionReceipt',
- params: [txHash],
- })
-
- if (!receipt) {
- await sleep(interval)
- await transactionReceiptRetry()
- }
-
- return receipt
+ let receipt = null
+ while (!receipt) {
+ receipt = await ethereum.request({
+ method: 'eth_getTransactionReceipt',
+ params: [txHash],
+ })
+ if (!receipt) {
+ await sleep(interval)
+ }
+ }
+ return receipt
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
return await transactionReceiptRetry() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (e: unknown) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new CosmosWalletException(new Error((e as any).message), { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
code: UnspecifiedErrorCode, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
type: ErrorType.WalletError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
contextModule: WalletAction.GetEthereumTransactionReceipt, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
// eslint-disable-next-line class-methods-use-this | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
async getPubKey(): Promise<string> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new WalletException( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
new Error('You can only fetch PubKey from Cosmos native wallets'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
async onChainIdChanged(callback: (chain: string) => void): Promise<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ethereum = await this.getEthereum() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.listeners = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
[WalletEventListener.ChainIdChange]: callback, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
ethereum.on('chainChanged', callback) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
private async getEthereum(): Promise<BrowserEip1993Provider> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
const provider = await getFoxWalletProvider() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!provider) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw new CosmosWalletException( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
new Error('Please install the FoxWallet wallet extension.'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
code: UnspecifiedErrorCode, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
type: ErrorType.WalletNotInstalledError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
contextModule: WalletAction.GetAccounts, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
return provider | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,66 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { isServerSide } from '@injectivelabs/sdk-ts' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { BrowserEip1993Provider, WindowWithEip1193Provider } from '../../types' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const $window = (isServerSide() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
? {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
: window) as unknown as WindowWithEip1193Provider | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export async function getFoxWalletProvider({ timeout } = { timeout: 3000 }) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const provider = getFoxWalletFromWindow() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (provider) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return provider | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return listenForFoxWalletInitialized({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
timeout, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) as Promise<BrowserEip1993Provider> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async function listenForFoxWalletInitialized( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{ timeout } = { timeout: 3000 }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return new Promise((resolve) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const handleInitialization = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
resolve(getFoxWalletFromWindow()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$window.addEventListener('foxwallet#initialized', handleInitialization, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
once: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setTimeout(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$window.removeEventListener( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
'foxwallet#initialized', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
handleInitialization, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
resolve(null) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, timeout) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+20
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve error handling and prevent potential memory leaks The current implementation has several potential issues:
async function listenForFoxWalletInitialized(
{ timeout } = { timeout: 3000 },
) {
- return new Promise((resolve) => {
+ return new Promise((resolve, reject) => {
+ let isResolved = false;
const handleInitialization = () => {
- resolve(getFoxWalletFromWindow())
+ if (isResolved) return;
+ isResolved = true;
+ try {
+ const provider = getFoxWalletFromWindow();
+ resolve(provider);
+ } catch (error) {
+ reject(error);
+ }
}
$window.addEventListener('foxwallet#initialized', handleInitialization, {
once: true,
})
- setTimeout(() => {
+ const timeoutId = setTimeout(() => {
+ if (isResolved) return;
+ isResolved = true;
$window.removeEventListener(
'foxwallet#initialized',
handleInitialization,
)
resolve(null)
}, timeout)
})
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
function getFoxWalletFromWindow() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const injectedProviderExist = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
typeof window !== 'undefined' && | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
(typeof $window.ethereum !== 'undefined' || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
typeof $window.foxwallet !== 'undefined') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// No injected providers exist. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!injectedProviderExist) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ($window.foxwallet?.ethereum) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return $window.foxwallet.ethereum | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ($window.ethereum.isFoxWallet) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return $window.ethereum | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ($window.providers) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return $window.providers.find((p) => p.isFoxWallet) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+42
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Enhance type safety and return consistency The function could benefit from improved type safety and consistent return types. -function getFoxWalletFromWindow() {
+function getFoxWalletFromWindow(): BrowserEip1993Provider | undefined {
const injectedProviderExist =
- typeof window !== 'undefined' &&
- (typeof $window.ethereum !== 'undefined' ||
+ (typeof $window.ethereum !== 'undefined' ||
typeof $window.foxwallet !== 'undefined')
// No injected providers exist.
if (!injectedProviderExist) {
return
}
if ($window.foxwallet?.ethereum) {
return $window.foxwallet.ethereum
}
if ($window.ethereum?.isFoxWallet) {
return $window.ethereum
}
- if ($window.providers) {
+ if (Array.isArray($window.providers)) {
return $window.providers.find((p) => p.isFoxWallet)
}
return
} 📝 Committable suggestion
Suggested change
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Specify the type of the
transaction
parameterThe
transaction
parameter is currently typed asunknown
. Providing a specific type will improve type safety and code readability.Please specify the appropriate type for
transaction
. For example:Replace
EthereumTransactionRequest
with the actual type that matches the expected transaction object.