Skip to content
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 listen to transactions for every adapter. #3382

Merged
merged 24 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
61df3ef
Merge branch 'main' of github.com:reown-com/appkit
svenvoskamp Nov 25, 2024
2cb1a1b
Merge branch 'main' of github.com:reown-com/appkit
svenvoskamp Nov 26, 2024
d2bf2bc
Merge branch 'main' of github.com:reown-com/appkit
svenvoskamp Nov 27, 2024
0bd4276
Merge branch 'main' of github.com:reown-com/appkit
svenvoskamp Nov 28, 2024
a4c24da
Merge branch 'main' of github.com:reown-com/appkit
svenvoskamp Nov 28, 2024
5eecce4
Merge branch 'main' of github.com:reown-com/appkit
svenvoskamp Nov 29, 2024
b3d2efe
Merge branch 'main' of github.com:reown-com/appkit
svenvoskamp Nov 29, 2024
0a0aeca
Merge branch 'main' of github.com:reown-com/appkit
svenvoskamp Dec 2, 2024
6f7efc2
fix subscribeProviders method
svenvoskamp Dec 2, 2024
fb4c93e
add test
svenvoskamp Dec 2, 2024
33f67bb
feat: Fetch balance of specific adapter after a transactions has been…
svenvoskamp Dec 3, 2024
26ef8ff
add to walletConnectProvider
svenvoskamp Dec 3, 2024
b4e340f
Merge branch 'main' into feat/listen-pending-transactions
svenvoskamp Dec 3, 2024
c2be2fb
fix typecheck
svenvoskamp Dec 3, 2024
322f050
Merge branch 'feat/listen-pending-transactions' of github.com:reown-c…
svenvoskamp Dec 3, 2024
1efcff5
handle authConnector
svenvoskamp Dec 3, 2024
f7d0073
fix wagmi
svenvoskamp Dec 3, 2024
15088e2
fix wagmi
svenvoskamp Dec 3, 2024
480b84f
Merge branch 'main' into feat/listen-pending-transactions
svenvoskamp Dec 3, 2024
2b2d9c3
feedback
svenvoskamp Dec 5, 2024
50f193d
Merge branch 'feat/listen-pending-transactions' of github.com:reown-c…
svenvoskamp Dec 5, 2024
16ac3c3
Merge branch 'main' of github.com:reown-com/appkit into feat/listen-p…
svenvoskamp Dec 5, 2024
b6d4049
Merge branch 'main' into feat/listen-pending-transactions
svenvoskamp Dec 5, 2024
eb3abe5
Merge branch 'main' into feat/listen-pending-transactions
svenvoskamp Dec 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .changeset/chilly-cameras-juggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
'@reown/appkit': patch
'@reown/appkit-adapter-ethers': patch
'@reown/appkit-adapter-ethers5': patch
'@reown/appkit-adapter-solana': patch
'@reown/appkit-adapter-wagmi': patch
'@reown/appkit-utils': patch
'@reown/appkit-cdn': patch
'@reown/appkit-common': patch
'@reown/appkit-core': patch
'@reown/appkit-experimental': patch
'@reown/appkit-polyfills': patch
'@reown/appkit-scaffold-ui': patch
'@reown/appkit-siwe': patch
'@reown/appkit-siwx': patch
'@reown/appkit-ui': patch
'@reown/appkit-wallet': patch
---

Fix subscribeProviders method in AppKit client
20 changes: 20 additions & 0 deletions .changeset/sour-buttons-train.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
'@reown/appkit-adapter-ethers5': patch
'@reown/appkit-adapter-ethers': patch
'@reown/appkit-adapter-solana': patch
'@reown/appkit-adapter-wagmi': patch
'@reown/appkit-utils': patch
'@reown/appkit': patch
'@reown/appkit-cdn': patch
'@reown/appkit-common': patch
'@reown/appkit-core': patch
'@reown/appkit-experimental': patch
'@reown/appkit-polyfills': patch
'@reown/appkit-scaffold-ui': patch
'@reown/appkit-siwe': patch
'@reown/appkit-siwx': patch
'@reown/appkit-ui': patch
'@reown/appkit-wallet': patch
---

feat: Fetch balance of specific adapter after a transactions has been made
16 changes: 16 additions & 0 deletions packages/adapters/ethers/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { CoinbaseWalletSDK, type ProviderInterface } from '@coinbase/wallet-sdk'
import type { W3mFrameProvider } from '@reown/appkit-wallet'
import { EthersMethods } from './utils/EthersMethods.js'
import { ProviderUtil } from '@reown/appkit/store'
import { BrowserProvider } from 'ethers'

export interface EIP6963ProviderDetail {
info: Connector['info']
Expand Down Expand Up @@ -479,6 +480,19 @@ export class EthersAdapter extends AdapterBlueprint {
return { profileName: undefined, profileImage: undefined }
}

private listenPendingTransactions(provider: Provider) {
const browserProvider = new BrowserProvider(provider)

try {
browserProvider.on('pending', () => {
this.emit('pendingTransactions')
})
} catch (error) {
// eslint-disable-next-line no-console
console.error('Error listening to pending transactions', error)
svenvoskamp marked this conversation as resolved.
Show resolved Hide resolved
svenvoskamp marked this conversation as resolved.
Show resolved Hide resolved
}
}

private providerHandlers: {
disconnect: () => void
accountsChanged: (accounts: string[]) => void
Expand Down Expand Up @@ -506,6 +520,8 @@ export class EthersAdapter extends AdapterBlueprint {
this.emit('switchNetwork', { chainId: chainIdNumber })
}

this.listenPendingTransactions(provider)

provider.on('disconnect', disconnectHandler)
provider.on('accountsChanged', accountsChangedHandler)
provider.on('chainChanged', chainChangedHandler)
Expand Down
39 changes: 38 additions & 1 deletion packages/adapters/ethers/src/tests/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CaipNetworksUtil } from '@reown/appkit-utils'
import type { Provider } from '@reown/appkit-core'
import type { W3mFrameProvider } from '@reown/appkit-wallet'
import UniversalProvider from '@walletconnect/universal-provider'
import { JsonRpcProvider, InfuraProvider } from 'ethers'
import { JsonRpcProvider, InfuraProvider, BrowserProvider } from 'ethers'
import { mainnet } from '@reown/appkit/networks'
import { EthersMethods } from '../utils/EthersMethods'
import { ProviderUtil } from '@reown/appkit/store'
Expand All @@ -21,6 +21,13 @@ vi.mock('ethers', async importOriginal => {
})),
JsonRpcProvider: vi.fn(() => ({
getBalance: vi.fn()
})),
BrowserProvider: vi.fn(() => ({
on: vi.fn((event, callback) => {
if (event === 'pending') {
callback()
}
})
}))
}
})
Expand Down Expand Up @@ -398,4 +405,34 @@ describe('EthersAdapter', () => {
expect(result).toBe('0x123')
})
})

describe('EthersAdapter - ListenPendingTransactions', () => {
it('should listen for pending transactions and emit event', () => {
const adapter = new EthersAdapter()
const mockProvider = {
request: vi.fn(),
on: vi.fn(),
removeListener: vi.fn(),
send: vi.fn(),
sendAsync: vi.fn()
} as unknown as Provider

const emitSpy = vi.spyOn(adapter, 'emit' as any)

vi.mocked(BrowserProvider).mockImplementation(
() =>
({
on: vi.fn((event, callback) => {
if (event === 'pending') {
callback()
}
})
}) as any
)
;(adapter as any).listenPendingTransactions(mockProvider)

expect(BrowserProvider).toHaveBeenCalledWith(mockProvider)
expect(emitSpy).toHaveBeenCalledWith('pendingTransactions')
})
})
})
10 changes: 10 additions & 0 deletions packages/adapters/ethers5/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,14 @@ export class Ethers5Adapter extends AdapterBlueprint {
return { profileName: undefined, profileImage: undefined }
}

private listenPendingTransactions(provider: Provider) {
const browserProvider = new ethers.providers.Web3Provider(provider)

browserProvider.on('pending', () => {
this.emit('pendingTransactions')
})
}

private providerHandlers: {
disconnect: () => void
accountsChanged: (accounts: string[]) => void
Expand Down Expand Up @@ -510,6 +518,8 @@ export class Ethers5Adapter extends AdapterBlueprint {
this.emit('switchNetwork', { chainId: chainIdNumber })
}

this.listenPendingTransactions(provider)

provider.on('disconnect', disconnectHandler)
provider.on('accountsChanged', accountsChangedHandler)
provider.on('chainChanged', chainChangedHandler)
Expand Down
37 changes: 37 additions & 0 deletions packages/adapters/ethers5/src/tests/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ vi.mock('ethers', async importOriginal => {
})),
JsonRpcProvider: vi.fn(() => ({
getBalance: vi.fn()
})),
Web3Provider: vi.fn(() => ({
on: vi.fn((event, callback) => {
if (event === 'pending') {
callback()
}
})
}))
}
}
Expand Down Expand Up @@ -400,4 +407,34 @@ describe('Ethers5Adapter', () => {
expect(result).toBe('0x123')
})
})

describe('Ethers5Adapter - ListenPendingTransactions', () => {
it('should listen for pending transactions and emit event', () => {
const adapter = new Ethers5Adapter()
const mockProvider = {
request: vi.fn(),
on: vi.fn(),
removeListener: vi.fn(),
send: vi.fn(),
sendAsync: vi.fn()
} as unknown as Provider

const emitSpy = vi.spyOn(adapter, 'emit' as any)

vi.mocked(providers.Web3Provider).mockImplementation(
() =>
({
on: vi.fn((event, callback) => {
if (event === 'pending') {
callback()
}
})
}) as any
)
;(adapter as any).listenPendingTransactions(mockProvider)

expect(providers.Web3Provider).toHaveBeenCalledWith(mockProvider)
expect(emitSpy).toHaveBeenCalledWith('pendingTransactions')
})
})
})
3 changes: 3 additions & 0 deletions packages/adapters/solana/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,9 @@ export class SolanaAdapter extends AdapterBlueprint {
provider.on('disconnect', disconnectHandler)
provider.on('accountsChanged', accountsChangedHandler)
provider.on('connect', accountsChangedHandler)
provider.on('pendingTransaction', () => {
this.emit('pendingTransactions')
})

this.providerHandlers = {
disconnect: disconnectHandler,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ export class WalletConnectProvider extends ProviderEventEmitter implements Provi
sendOptions
})

this.emit('pendingTransaction', undefined)

return result.signature
}

Expand All @@ -185,6 +187,8 @@ export class WalletConnectProvider extends ProviderEventEmitter implements Provi
const signedTransaction = await this.signTransaction(transaction)
const signature = await connection.sendRawTransaction(signedTransaction.serialize(), options)

this.emit('pendingTransaction', undefined)

return signature
}

Expand All @@ -209,6 +213,8 @@ export class WalletConnectProvider extends ProviderEventEmitter implements Provi
return VersionedTransaction.deserialize(decodedTransaction)
}

this.emit('pendingTransaction', undefined)

return Transaction.from(decodedTransaction)
}) as T
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ export class WalletStandardProvider extends ProviderEventEmitter implements Prov
throw new WalletSignTransactionError('Empty result')
}

this.emit('pendingTransaction', undefined)

if (isVersionedTransaction(transaction)) {
return VersionedTransaction.deserialize(result.signedTransaction) as T
}
Expand Down Expand Up @@ -175,6 +177,8 @@ export class WalletStandardProvider extends ProviderEventEmitter implements Prov
throw new WalletSendTransactionError('Empty result')
}

this.emit('pendingTransaction', undefined)

return base58.encode(result.signature)
}

Expand Down Expand Up @@ -210,6 +214,8 @@ export class WalletStandardProvider extends ProviderEventEmitter implements Prov
throw new WalletSignTransactionError('Invalid transaction signature response')
}

this.emit('pendingTransaction', undefined)

if (isVersionedTransaction(transaction)) {
return VersionedTransaction.deserialize(signedTransaction)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export class ProviderEventEmitter implements ProviderEventEmitterMethods {
chainChanged: [],
connect: [],
disconnect: [],

pendingTransaction: [],
auth_rpcRequest: [],
auth_rpcSuccess: [],
auth_rpcError: []
Expand Down
20 changes: 12 additions & 8 deletions packages/adapters/solana/src/tests/WalletStandardProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,8 @@ describe('WalletStandardProvider specific tests', () => {
let wallet = mockWalletStandard()
let getActiveChain = vi.fn(() => TestConstants.chains[0])
let requestedChains = vi.mocked(structuredClone(TestConstants.chains))
let walletStandardProvider = new WalletStandardProvider({
wallet,
getActiveChain,
requestedChains
})
let walletStandardProvider: WalletStandardProvider
let emitSpy: ReturnType<typeof vi.spyOn>

beforeEach(() => {
wallet = mockWalletStandard()
Expand All @@ -29,6 +26,7 @@ describe('WalletStandardProvider specific tests', () => {
getActiveChain,
requestedChains
})
emitSpy = vi.spyOn(walletStandardProvider, 'emit' as any)
})

it('should call connect', async () => {
Expand All @@ -53,7 +51,7 @@ describe('WalletStandardProvider specific tests', () => {
})
})

it('should call signTransaction with correct params', async () => {
it('should call signTransaction with correct params and emit pendingTransaction', async () => {
const transaction = mockLegacyTransaction()
await walletStandardProvider.signTransaction(transaction)

Expand All @@ -62,6 +60,7 @@ describe('WalletStandardProvider specific tests', () => {
account: wallet.accounts[0],
chain: 'solana:mainnet'
})
expect(emitSpy).toHaveBeenCalledWith('pendingTransaction', undefined)
})

it('should call signTransaction with correct params for VersionedTransaction', async () => {
Expand All @@ -75,7 +74,7 @@ describe('WalletStandardProvider specific tests', () => {
})
})

it('should call signAndSendTransaction with correct params', async () => {
it('should call signAndSendTransaction with correct params and emit pendingTransaction', async () => {
const transaction = mockLegacyTransaction()

await walletStandardProvider.signAndSendTransaction(transaction)
Expand All @@ -87,6 +86,7 @@ describe('WalletStandardProvider specific tests', () => {
chain: 'solana:mainnet',
options: { preflighCommitment: undefined }
})
expect(emitSpy).toHaveBeenCalledWith('pendingTransaction', undefined)

await walletStandardProvider.signAndSendTransaction(transaction, {
preflightCommitment: 'singleGossip',
Expand All @@ -107,6 +107,7 @@ describe('WalletStandardProvider specific tests', () => {
skipPreflight: true
}
})
expect(emitSpy).toHaveBeenCalledWith('pendingTransaction', undefined)
})

it('should throw if features are not available', async () => {
Expand All @@ -130,7 +131,7 @@ describe('WalletStandardProvider specific tests', () => {
).rejects.toThrowError(WalletStandardFeatureNotSupportedError)
})

it('should call signTransaction with correct params for multiple transactions over singAllTransactions method', async () => {
it('should call signAllTransactions with correct params and emit pendingTransaction', async () => {
const transactions = [mockLegacyTransaction(), mockVersionedTransaction()]
await walletStandardProvider.signAllTransactions(transactions)

Expand All @@ -141,6 +142,9 @@ describe('WalletStandardProvider specific tests', () => {
chain: 'solana:mainnet'
}))
)
transactions.forEach(() => {
expect(emitSpy).toHaveBeenCalledWith('pendingTransaction', undefined)
})
})

it('should use the same requestedChains to return chains', () => {
Expand Down
11 changes: 10 additions & 1 deletion packages/adapters/wagmi/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import {
waitForTransactionReceipt,
getAccount,
prepareTransactionRequest,
reconnect
reconnect,
watchPendingTransactions
} from '@wagmi/core'
import { type Chain } from '@wagmi/core/chains'

Expand Down Expand Up @@ -155,6 +156,14 @@ export class WagmiAdapter extends AdapterBlueprint {
}

private setupWatchers() {
watchPendingTransactions(this.wagmiConfig, {
/* Magic RPC does not support the pending transactions. We handle transaction for the AuthConnector cases in AppKit client to handle all clients at once. Adding the onError handler to avoid the error to throw. */
// eslint-disable-next-line @typescript-eslint/no-empty-function
onError: () => {},
onTransactions: () => {
this.emit('pendingTransactions')
}
})
watchAccount(this.wagmiConfig, {
onChange: accountData => {
if (accountData.address) {
Expand Down
Loading
Loading