From 9454e20699cf0af8847e032b97a7a7a606a2b50c Mon Sep 17 00:00:00 2001 From: Sven <38101365+svenvoskamp@users.noreply.github.com> Date: Thu, 14 Nov 2024 12:45:22 +0100 Subject: [PATCH 1/3] chore: add sa methods wagmi ethers (#3237) --- packages/adapters/ethers/src/client.ts | 42 +++++++++++ .../adapters/ethers/src/tests/client.test.ts | 57 ++++++++++++++ packages/adapters/ethers5/src/client.ts | 42 +++++++++++ .../adapters/ethers5/src/tests/client.test.ts | 57 ++++++++++++++ .../ethers5/src/utils/Ethers5Methods.ts | 8 ++ packages/adapters/solana/src/client.ts | 12 +++ packages/adapters/wagmi/src/client.ts | 75 +++++++++++++++++++ .../adapters/wagmi/src/tests/client.test.ts | 58 ++++++++++++++ .../src/adapters/ChainAdapterBlueprint.ts | 21 ++++++ packages/appkit/src/client.ts | 32 +++++++- .../appkit/src/universal-adapter/client.ts | 12 +++ .../controllers/SmartSessionsController.ts | 1 + 12 files changed, 415 insertions(+), 2 deletions(-) diff --git a/packages/adapters/ethers/src/client.ts b/packages/adapters/ethers/src/client.ts index 683e1d3728..3dc6de1db8 100644 --- a/packages/adapters/ethers/src/client.ts +++ b/packages/adapters/ethers/src/client.ts @@ -15,6 +15,7 @@ import { formatEther, InfuraProvider, JsonRpcProvider } from 'ethers' 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' export interface EIP6963ProviderDetail { info: Connector['info'] @@ -542,4 +543,45 @@ export class EthersAdapter extends AdapterBlueprint { console.info('Could not revoke permissions from wallet. Disconnecting...', error) } } + + public async getCapabilities(params: AdapterBlueprint.GetCapabilitiesParams): Promise { + const provider = ProviderUtil.getProvider(CommonConstantsUtil.CHAIN.EVM) + + if (!provider) { + throw new Error('Provider is undefined') + } + + const walletCapabilitiesString = provider.session?.sessionProperties?.['capabilities'] + if (walletCapabilitiesString) { + const walletCapabilities = EthersMethods.parseWalletCapabilities(walletCapabilitiesString) + const accountCapabilities = walletCapabilities[params] + if (accountCapabilities) { + return accountCapabilities + } + } + + return await provider.request({ method: 'wallet_getCapabilities', params: [params] }) + } + + public async grantPermissions(params: AdapterBlueprint.GrantPermissionsParams): Promise { + const provider = ProviderUtil.getProvider(CommonConstantsUtil.CHAIN.EVM) + + if (!provider) { + throw new Error('Provider is undefined') + } + + return await provider.request({ method: 'wallet_grantPermissions', params }) + } + + public async revokePermissions( + params: AdapterBlueprint.RevokePermissionsParams + ): Promise<`0x${string}`> { + const provider = ProviderUtil.getProvider(CommonConstantsUtil.CHAIN.EVM) + + if (!provider) { + throw new Error('Provider is undefined') + } + + return await provider.request({ method: 'wallet_revokePermissions', params: [params] }) + } } diff --git a/packages/adapters/ethers/src/tests/client.test.ts b/packages/adapters/ethers/src/tests/client.test.ts index d2579c96b7..9fa052506f 100644 --- a/packages/adapters/ethers/src/tests/client.test.ts +++ b/packages/adapters/ethers/src/tests/client.test.ts @@ -7,6 +7,7 @@ import UniversalProvider from '@walletconnect/universal-provider' import { JsonRpcProvider, InfuraProvider } from 'ethers' import { mainnet } from '@reown/appkit/networks' import { EthersMethods } from '../utils/EthersMethods' +import { ProviderUtil } from '@reown/appkit/store' // Mock external dependencies vi.mock('ethers', async importOriginal => { @@ -320,4 +321,60 @@ describe('EthersAdapter', () => { expect(result).toBe('1.5') }) }) + + describe('EthersAdapter - Permissions', () => { + const mockProvider = { + request: vi.fn() + } as unknown as UniversalProvider + + beforeEach(() => { + vi.spyOn(ProviderUtil, 'getProvider').mockImplementation(() => mockProvider) + }) + + it('should call wallet_getCapabilities', async () => { + await adapter.getCapabilities('eip155:1:0x123') + + expect(mockProvider.request).toHaveBeenCalledWith({ + method: 'wallet_getCapabilities', + params: ['eip155:1:0x123'] + }) + }) + + it('should call wallet_grantPermissions', async () => { + const mockParams = { + pci: 'test-pci', + expiry: 1234567890, + address: '0x123', + permissions: ['eth_accounts'] + } + + await adapter.grantPermissions(mockParams) + + expect(mockProvider.request).toHaveBeenCalledWith({ + method: 'wallet_grantPermissions', + params: mockParams + }) + }) + + it('should call wallet_revokePermissions', async () => { + vi.mocked(mockProvider.request).mockImplementation(() => + Promise.resolve('0x123' as `0x${string}`) + ) + + const mockParams = { + pci: 'test-pci', + expiry: 1234567890, + address: '0x123' as `0x${string}`, + permissions: ['eth_accounts'] + } + + const result = await adapter.revokePermissions(mockParams) + + expect(mockProvider.request).toHaveBeenCalledWith({ + method: 'wallet_revokePermissions', + params: [mockParams] + }) + expect(result).toBe('0x123') + }) + }) }) diff --git a/packages/adapters/ethers5/src/client.ts b/packages/adapters/ethers5/src/client.ts index c15e1c6191..f65b0c3363 100644 --- a/packages/adapters/ethers5/src/client.ts +++ b/packages/adapters/ethers5/src/client.ts @@ -16,6 +16,7 @@ import { CoinbaseWalletSDK, type ProviderInterface } from '@coinbase/wallet-sdk' import type { W3mFrameProvider } from '@reown/appkit-wallet' import { Ethers5Methods } from './utils/Ethers5Methods.js' import { formatEther } from 'ethers/lib/utils.js' +import { ProviderUtil } from '@reown/appkit/store' export interface EIP6963ProviderDetail { info: Connector['info'] @@ -546,4 +547,45 @@ export class Ethers5Adapter extends AdapterBlueprint { console.info('Could not revoke permissions from wallet. Disconnecting...', error) } } + + public async getCapabilities(params: AdapterBlueprint.GetCapabilitiesParams): Promise { + const provider = ProviderUtil.getProvider(CommonConstantsUtil.CHAIN.EVM) + + if (!provider) { + throw new Error('Provider is undefined') + } + + const walletCapabilitiesString = provider.session?.sessionProperties?.['capabilities'] + if (walletCapabilitiesString) { + const walletCapabilities = Ethers5Methods.parseWalletCapabilities(walletCapabilitiesString) + const accountCapabilities = walletCapabilities[params] + if (accountCapabilities) { + return accountCapabilities + } + } + + return await provider.request({ method: 'wallet_getCapabilities', params: [params] }) + } + + public async grantPermissions(params: AdapterBlueprint.GrantPermissionsParams): Promise { + const provider = ProviderUtil.getProvider(CommonConstantsUtil.CHAIN.EVM) + + if (!provider) { + throw new Error('Provider is undefined') + } + + return await provider.request({ method: 'wallet_grantPermissions', params }) + } + + public async revokePermissions( + params: AdapterBlueprint.RevokePermissionsParams + ): Promise<`0x${string}`> { + const provider = ProviderUtil.getProvider(CommonConstantsUtil.CHAIN.EVM) + + if (!provider) { + throw new Error('Provider is undefined') + } + + return await provider.request({ method: 'wallet_revokePermissions', params: [params] }) + } } diff --git a/packages/adapters/ethers5/src/tests/client.test.ts b/packages/adapters/ethers5/src/tests/client.test.ts index 2b12848a42..a3eaffc11a 100644 --- a/packages/adapters/ethers5/src/tests/client.test.ts +++ b/packages/adapters/ethers5/src/tests/client.test.ts @@ -7,6 +7,7 @@ import UniversalProvider from '@walletconnect/universal-provider' import { providers } from 'ethers' import { mainnet } from '@reown/appkit/networks' import { Ethers5Methods } from '../utils/Ethers5Methods' +import { ProviderUtil } from '@reown/appkit/store' // Mock external dependencies vi.mock('ethers', async importOriginal => { @@ -322,4 +323,60 @@ describe('Ethers5Adapter', () => { expect(result).toBe('1.5') }) }) + + describe('Ethers5Adapter - Permissions', () => { + const mockProvider = { + request: vi.fn() + } as unknown as UniversalProvider + + beforeEach(() => { + vi.spyOn(ProviderUtil, 'getProvider').mockImplementation(() => mockProvider) + }) + + it('should call wallet_getCapabilities', async () => { + await adapter.getCapabilities('eip155:1:0x123') + + expect(mockProvider.request).toHaveBeenCalledWith({ + method: 'wallet_getCapabilities', + params: ['eip155:1:0x123'] + }) + }) + + it('should call wallet_grantPermissions', async () => { + const mockParams = { + pci: 'test-pci', + expiry: 1234567890, + address: '0x123', + permissions: ['eth_accounts'] + } + + await adapter.grantPermissions(mockParams) + + expect(mockProvider.request).toHaveBeenCalledWith({ + method: 'wallet_grantPermissions', + params: mockParams + }) + }) + + it('should call wallet_revokePermissions', async () => { + vi.mocked(mockProvider.request).mockImplementation(() => + Promise.resolve('0x123' as `0x${string}`) + ) + + const mockParams = { + pci: 'test-pci', + expiry: 1234567890, + address: '0x123' as `0x${string}`, + permissions: ['eth_accounts'] + } + + const result = await adapter.revokePermissions(mockParams) + + expect(mockProvider.request).toHaveBeenCalledWith({ + method: 'wallet_revokePermissions', + params: [mockParams] + }) + expect(result).toBe('0x123') + }) + }) }) diff --git a/packages/adapters/ethers5/src/utils/Ethers5Methods.ts b/packages/adapters/ethers5/src/utils/Ethers5Methods.ts index fb8d3dc368..ee30bdbaa5 100644 --- a/packages/adapters/ethers5/src/utils/Ethers5Methods.ts +++ b/packages/adapters/ethers5/src/utils/Ethers5Methods.ts @@ -143,6 +143,14 @@ export const Ethers5Methods = { return false }, + parseWalletCapabilities: (str: string) => { + try { + return JSON.parse(str) + } catch (error) { + throw new Error('Error parsing wallet capabilities') + } + }, + parseUnits: (value: string, _: number) => ethers.utils.parseUnits(value, 'gwei').toBigInt(), formatUnits: ethers.utils.formatUnits } diff --git a/packages/adapters/solana/src/client.ts b/packages/adapters/solana/src/client.ts index 5bdae738b7..bd9c7793dd 100644 --- a/packages/adapters/solana/src/client.ts +++ b/packages/adapters/solana/src/client.ts @@ -162,6 +162,18 @@ export class SolanaAdapter extends AdapterBlueprint { }) } + public async getCapabilities(): Promise { + return Promise.resolve({}) + } + + public async grantPermissions(): Promise { + return Promise.resolve({}) + } + + public async revokePermissions(): Promise<`0x${string}`> { + return Promise.resolve('0x') + } + public async signMessage( params: AdapterBlueprint.SignMessageParams ): Promise { diff --git a/packages/adapters/wagmi/src/client.ts b/packages/adapters/wagmi/src/client.ts index 6c8ef0b6e1..91e5e5ef77 100644 --- a/packages/adapters/wagmi/src/client.ts +++ b/packages/adapters/wagmi/src/client.ts @@ -53,6 +53,7 @@ import { } from 'viem' import type { W3mFrameProvider } from '@reown/appkit-wallet' import { normalize } from 'viem/ens' +import { parseWalletCapabilities } from './utils/helpers.js' export class WagmiAdapter extends AdapterBlueprint { public wagmiChains: readonly [Chain, ...Chain[]] | undefined @@ -487,4 +488,78 @@ export class WagmiAdapter extends AdapterBlueprint { public async switchNetwork(params: AdapterBlueprint.SwitchNetworkParams) { await switchChain(this.wagmiConfig, { chainId: params.caipNetwork.id as number }) } + + public async getCapabilities(params: string) { + if (!this.wagmiConfig) { + throw new Error('connectionControllerClient:getCapabilities - wagmiConfig is undefined') + } + + const connections = getConnections(this.wagmiConfig) + const connection = connections[0] + + if (!connection?.connector) { + throw new Error('connectionControllerClient:getCapabilities - connector is undefined') + } + + const provider = (await connection.connector.getProvider()) as UniversalProvider + + if (!provider) { + throw new Error('connectionControllerClient:getCapabilities - provider is undefined') + } + + const walletCapabilitiesString = provider.session?.sessionProperties?.['capabilities'] + if (walletCapabilitiesString) { + const walletCapabilities = parseWalletCapabilities(walletCapabilitiesString) + const accountCapabilities = walletCapabilities[params] + if (accountCapabilities) { + return accountCapabilities + } + } + + return await provider.request({ method: 'wallet_getCapabilities', params: [params] }) + } + + public async grantPermissions(params: AdapterBlueprint.GrantPermissionsParams) { + if (!this.wagmiConfig) { + throw new Error('connectionControllerClient:grantPermissions - wagmiConfig is undefined') + } + + const connections = getConnections(this.wagmiConfig) + const connection = connections[0] + + if (!connection?.connector) { + throw new Error('connectionControllerClient:grantPermissions - connector is undefined') + } + + const provider = (await connection.connector.getProvider()) as UniversalProvider + + if (!provider) { + throw new Error('connectionControllerClient:grantPermissions - provider is undefined') + } + + return provider.request({ method: 'wallet_grantPermissions', params }) + } + + public async revokePermissions( + params: AdapterBlueprint.RevokePermissionsParams + ): Promise<`0x${string}`> { + if (!this.wagmiConfig) { + throw new Error('connectionControllerClient:revokePermissions - wagmiConfig is undefined') + } + + const connections = getConnections(this.wagmiConfig) + const connection = connections[0] + + if (!connection?.connector) { + throw new Error('connectionControllerClient:revokePermissions - connector is undefined') + } + + const provider = (await connection.connector.getProvider()) as UniversalProvider + + if (!provider) { + throw new Error('connectionControllerClient:revokePermissions - provider is undefined') + } + + return provider.request({ method: 'wallet_revokePermissions', params }) + } } diff --git a/packages/adapters/wagmi/src/tests/client.test.ts b/packages/adapters/wagmi/src/tests/client.test.ts index 223c21046b..3b9c93317a 100644 --- a/packages/adapters/wagmi/src/tests/client.test.ts +++ b/packages/adapters/wagmi/src/tests/client.test.ts @@ -18,6 +18,7 @@ import { } from '@wagmi/core' import { mainnet } from '@wagmi/core/chains' import { CaipNetworksUtil } from '@reown/appkit-utils' +import type UniversalProvider from '@walletconnect/universal-provider' vi.mock('@wagmi/core', async () => { const actual = await vi.importActual('@wagmi/core') @@ -322,4 +323,61 @@ describe('WagmiAdapter', () => { ) }) }) + + describe('WagmiAdapter - Permissions', () => { + const mockProvider = { + request: vi.fn() + } as unknown as UniversalProvider + + beforeEach(() => { + vi.mocked(getConnections).mockReturnValue([ + { + connector: { + getProvider: () => Promise.resolve(mockProvider) + } + } + ] as any) + }) + + it('should get capabilities from session properties', async () => { + await adapter.getCapabilities('eip155:1:0x123') + + expect(mockProvider.request).toHaveBeenCalledWith({ + method: 'wallet_getCapabilities', + params: ['eip155:1:0x123'] + }) + }) + + it('should call provider request with correct params', async () => { + const mockParams = { + pci: 'test-pci', + expiry: 1234567890, + address: '0x123', + permissions: ['eth_accounts'] + } + + await adapter.grantPermissions(mockParams) + + expect(mockProvider.request).toHaveBeenCalledWith({ + method: 'wallet_grantPermissions', + params: mockParams + }) + }) + + it('should call provider request with correct params', async () => { + const mockParams = { + pci: 'test-pci', + expiry: 1234567890, + address: '0x123' as `0x${string}`, + permissions: ['eth_accounts'] + } + + await adapter.revokePermissions(mockParams) + + expect(mockProvider.request).toHaveBeenCalledWith({ + method: 'wallet_revokePermissions', + params: mockParams + }) + }) + }) }) diff --git a/packages/appkit/src/adapters/ChainAdapterBlueprint.ts b/packages/appkit/src/adapters/ChainAdapterBlueprint.ts index cb407bd185..15714e51ef 100644 --- a/packages/appkit/src/adapters/ChainAdapterBlueprint.ts +++ b/packages/appkit/src/adapters/ChainAdapterBlueprint.ts @@ -328,6 +328,16 @@ export abstract class AdapterBlueprint< * @param {AdapterBlueprint.ReconnectParams} params - Reconnection parameters */ public reconnect?(params: AdapterBlueprint.ReconnectParams): Promise + + public abstract getCapabilities(params: AdapterBlueprint.GetCapabilitiesParams): Promise + + public abstract grantPermissions( + params: AdapterBlueprint.GrantPermissionsParams + ): Promise + + public abstract revokePermissions( + params: AdapterBlueprint.RevokePermissionsParams + ): Promise<`0x${string}`> } export namespace AdapterBlueprint { @@ -440,6 +450,17 @@ export namespace AdapterBlueprint { export type GetWalletConnectProviderResult = AppKitConnector['provider'] + export type GetCapabilitiesParams = string + + export type GrantPermissionsParams = object | readonly unknown[] + + export type RevokePermissionsParams = { + pci: string + permissions: unknown[] + expiry: number + address: `0x${string}` + } + export type SendTransactionParams = { address: `0x${string}` to: string diff --git a/packages/appkit/src/client.ts b/packages/appkit/src/client.ts index 78e2edd9ee..21b77141ca 100644 --- a/packages/appkit/src/client.ts +++ b/packages/appkit/src/client.ts @@ -691,8 +691,6 @@ export class AppKit { } private createClients() { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error this.connectionControllerClient = { connectWalletConnect: async (onUri: (uri: string) => void) => { const adapter = this.getAdapter(ChainController.state.activeChain as ChainNamespace) @@ -836,6 +834,8 @@ export class AppKit { await adapter?.disconnect({ provider, providerType }) + this.setStatus('disconnected', ChainController.state.activeChain as ChainNamespace) + localStorage.removeItem(SafeLocalStorageKeys.CONNECTED_CONNECTOR) localStorage.removeItem(SafeLocalStorageKeys.ACTIVE_CAIP_NETWORK_ID) @@ -939,6 +939,25 @@ export class AppKit { const adapter = this.getAdapter(ChainController.state.activeChain as ChainNamespace) return adapter?.formatUnits({ value, decimals }) ?? '0' + }, + getCapabilities: async (params: AdapterBlueprint.GetCapabilitiesParams) => { + const adapter = this.getAdapter(ChainController.state.activeChain as ChainNamespace) + + await adapter?.getCapabilities(params) + }, + grantPermissions: async (params: AdapterBlueprint.GrantPermissionsParams) => { + const adapter = this.getAdapter(ChainController.state.activeChain as ChainNamespace) + + return await adapter?.grantPermissions(params) + }, + revokePermissions: async (params: AdapterBlueprint.RevokePermissionsParams) => { + const adapter = this.getAdapter(ChainController.state.activeChain as ChainNamespace) + + if (adapter?.revokePermissions) { + return await adapter.revokePermissions(params) + } + + return '0x' } } @@ -1100,6 +1119,13 @@ export class AppKit { provider.connect() }) provider.onConnect(async user => { + this.syncProvider({ + type: 'AUTH', + provider, + id: 'ID_AUTH', + chainNamespace: ChainController.state.activeChain as ChainNamespace + }) + const caipAddress = ChainController.state.activeChain === 'eip155' ? (`eip155:${user.chainId}:${user.address}` as CaipAddress) @@ -1376,6 +1402,8 @@ export class AppKit { chainNamespace ) + this.setStatus('connected', chainNamespace) + if (chainNamespace === ChainController.state.activeChain) { const caipNetwork = this.caipNetworks?.find( n => n.id === chainId && n.chainNamespace === chainNamespace diff --git a/packages/appkit/src/universal-adapter/client.ts b/packages/appkit/src/universal-adapter/client.ts index cc84396965..9b97a21d3d 100644 --- a/packages/appkit/src/universal-adapter/client.ts +++ b/packages/appkit/src/universal-adapter/client.ts @@ -113,6 +113,18 @@ export class UniversalAdapter extends AdapterBlueprint { return '0' } + public async getCapabilities(): Promise { + return Promise.resolve({}) + } + + public async grantPermissions(): Promise { + return Promise.resolve({}) + } + + public async revokePermissions(): Promise<`0x${string}`> { + return Promise.resolve('0x') + } + public async syncConnection() { return Promise.resolve({ id: 'WALLET_CONNECT', diff --git a/packages/experimental/src/smart-session/controllers/SmartSessionsController.ts b/packages/experimental/src/smart-session/controllers/SmartSessionsController.ts index 3cc4071979..f97b2671b2 100644 --- a/packages/experimental/src/smart-session/controllers/SmartSessionsController.ts +++ b/packages/experimental/src/smart-session/controllers/SmartSessionsController.ts @@ -174,6 +174,7 @@ export const SmartSessionsController = { isSmartSessionSupported(): boolean { const provider = ProviderUtil.getProvider(CommonConstantsUtil.CHAIN.EVM) + if (!provider) { return false } From 81785b5d19d5e6a5b13bdf347c59a6a70ab8d2a6 Mon Sep 17 00:00:00 2001 From: tomiir Date: Thu, 14 Nov 2024 13:33:53 +0100 Subject: [PATCH 2/3] feat: serialize context from the example (#3241) --- ...WagmiSendCallsWithPaymasterServiceTest.tsx | 53 +++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/apps/laboratory/src/components/Wagmi/WagmiSendCallsWithPaymasterServiceTest.tsx b/apps/laboratory/src/components/Wagmi/WagmiSendCallsWithPaymasterServiceTest.tsx index 59175ac292..69c84c5ff7 100644 --- a/apps/laboratory/src/components/Wagmi/WagmiSendCallsWithPaymasterServiceTest.tsx +++ b/apps/laboratory/src/components/Wagmi/WagmiSendCallsWithPaymasterServiceTest.tsx @@ -1,7 +1,7 @@ import { Button, Input, Stack, Text, Tooltip } from '@chakra-ui/react' import { useAccount } from 'wagmi' import { useSendCalls } from 'wagmi/experimental' -import { useCallback, useState } from 'react' +import { useCallback, useMemo, useState } from 'react' import { useChakraToast } from '../Toast' import { parseGwei, type Address } from 'viem' import { vitalikEthAddress } from '../../utils/DataUtil' @@ -18,6 +18,19 @@ const TEST_TX_2 = { data: '0xdeadbeef' as `0x${string}` } +const BICONOMY_PAYMASTER_CONTEXT = { + mode: 'SPONSORED', + calculateGasLimits: false, + expiryDuration: 300, + sponsorshipInfo: { + webhookData: {}, + smartAccountInfo: { + name: 'SAFE', + version: '1.4.1' + } + } +} + export function WagmiSendCallsWithPaymasterServiceTest() { const { provider, supportedChains, supportedChainsName, currentChainsInfo, supported } = useWagmiAvailableCapabilities({ @@ -66,11 +79,32 @@ export function WagmiSendCallsWithPaymasterServiceTest() { } function AvailableTestContent() { + const [paymasterProvider, setPaymasterProvider] = useState() + const [reownPolicyId, setReownPolicyId] = useState('') const [paymasterServiceUrl, setPaymasterServiceUrl] = useState('') const [isLoading, setLoading] = useState(false) - const toast = useChakraToast() + const context = useMemo(() => { + const contexts: Record = { + biconomy: BICONOMY_PAYMASTER_CONTEXT, + reown: { + policyId: reownPolicyId + } + } + + return contexts[paymasterProvider || ''] + }, [paymasterProvider]) + + function onPaymasterUrlChange(url: string) { + setPaymasterServiceUrl(url) + + const match = url.match(/pimlico|biconomy|reown/u) + if (match?.[0]) { + setPaymasterProvider(match?.[0]) + } + } + const { sendCalls } = useSendCalls({ mutation: { onSuccess: hash => { @@ -101,7 +135,8 @@ function AvailableTestContent() { calls: [TEST_TX_1, TEST_TX_2], capabilities: { paymasterService: { - url: paymasterServiceUrl + url: paymasterServiceUrl, + context } } }) @@ -112,13 +147,23 @@ function AvailableTestContent() { setPaymasterServiceUrl(e.target.value)} + onChange={e => onPaymasterUrlChange(e.target.value)} value={paymasterServiceUrl} isDisabled={isLoading} whiteSpace="nowrap" textOverflow="ellipsis" /> + {paymasterProvider === 'reown' && ( + setReownPolicyId(e.target.value)} + value={reownPolicyId} + isDisabled={isLoading} + whiteSpace="nowrap" + textOverflow="ellipsis" + /> + )}