Skip to content

Commit

Permalink
chore: add sa methods wagmi ethers (#3237)
Browse files Browse the repository at this point in the history
  • Loading branch information
svenvoskamp authored Nov 14, 2024
1 parent 0cc2b86 commit 9454e20
Show file tree
Hide file tree
Showing 12 changed files with 415 additions and 2 deletions.
42 changes: 42 additions & 0 deletions packages/adapters/ethers/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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']
Expand Down Expand Up @@ -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<unknown> {
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<unknown> {
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] })
}
}
57 changes: 57 additions & 0 deletions packages/adapters/ethers/src/tests/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down Expand Up @@ -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')
})
})
})
42 changes: 42 additions & 0 deletions packages/adapters/ethers5/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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']
Expand Down Expand Up @@ -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<unknown> {
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<unknown> {
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] })
}
}
57 changes: 57 additions & 0 deletions packages/adapters/ethers5/src/tests/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down Expand Up @@ -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')
})
})
})
8 changes: 8 additions & 0 deletions packages/adapters/ethers5/src/utils/Ethers5Methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
12 changes: 12 additions & 0 deletions packages/adapters/solana/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,18 @@ export class SolanaAdapter extends AdapterBlueprint {
})
}

public async getCapabilities(): Promise<unknown> {
return Promise.resolve({})
}

public async grantPermissions(): Promise<unknown> {
return Promise.resolve({})
}

public async revokePermissions(): Promise<`0x${string}`> {
return Promise.resolve('0x')
}

public async signMessage(
params: AdapterBlueprint.SignMessageParams
): Promise<AdapterBlueprint.SignMessageResult> {
Expand Down
75 changes: 75 additions & 0 deletions packages/adapters/wagmi/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 })
}
}
Loading

0 comments on commit 9454e20

Please sign in to comment.