Capabilities
Porto supports EIP-5792 Capabilities.
Capabilites are extension features that allow for extra functionality to be requested on particular JSON-RPC requests such as wallet_connect
and wallet_sendCalls
, and also enable additional JSON-RPC methods. Such features could be requesting to grant permissions on connection, or setting a custom fee token.
Porto supports the following capabilities:
Capability | Description | Standard |
---|---|---|
feeToken | Indicates if custom fee tokens are supported. | Experimental |
permissions | Indicates if permissions can be requested by the app. | Experimental |
sponsor | Indicates if app sponsoring is supported. | Experimental |
Fee Tokens
Porto allows for an application developer to use custom fee (gas) tokens to pay for the execution of a call bundle.
Custom fee tokens are indicated by the feeToken
capability on wallet_getCapabilities
Discovery
Tokens can be discovered by the application via feeToken.tokens
on the wallet_getCapabilities
method.
import { Porto } from 'porto'
const { provider } = Porto.create()
const capabilities = await provider.request({
method: 'wallet_getCapabilities',
})
const tokens = Object.values(capabilities)[0].feeToken.tokens
Request Capabilities
feeToken
Custom fee token to use for the request.
The following JSON-RPC methods support the feeToken
request capability:
type Capability = {
/** Custom fee token address. */
feeToken: `0x${string}`
}
Example
const capabilities = await provider.request({
method: 'wallet_sendCalls',
params: [{
capabilities: {
feeToken: '0x036cbd53842c5426634e7929541ec2318f3dcf7e', // USDC
},
/* ... */
}]
})
permissions
Porto supports account permission management.
Methods
The permissions
capability enables the following methods:
Request Capabilities
grantPermissions
Requests for the wallet to grant permissions.
The following JSON-RPC methods support the grantPermissions
request capability:
type Capability = {
/** Requests for the wallet to grant these permissions. */
grantPermissions: {
/** Expiry of the permissions. */
expiry: number
/**
* Key to grant permissions to.
* Defaults to a wallet-managed key.
*/
key?: {
/**
* Public key.
* Accepts an address for `address` & `secp256k1` types.
*/
publicKey?: `0x${string}`,
/** Key type. */
type?: 'address' | 'p256' | 'secp256k1' | 'webauthn-p256',
}
/** Permissions. */
permissions: {
/** Call permissions. */
calls: {
/** Function signature or 4-byte signature. */
signature?: string
/** Authorized target address. */
to?: `0x${string}`
}[],
/** Spend permissions. */
spend: {
/** Spending limit (in wei) per period. */
limit: `0x${string}`,
/** Period of the spend limit. */
period: 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year'
/**
* ERC20 token to set the limit on.
* If not provided, the limit will be set on the
* native token (e.g. ETH).
*/
token?: `0x${string}`
}[],
}
},
}
Example
const capabilities = await provider.request({
method: 'wallet_connect',
params: [{
capabilities: {
grantPermissions: {
expiry: 1727078400,
permissions: {
calls: [{ signature: 'subscribe()' }],
spend: [{
limit: '0x5f5e100', // 100 USDC
period: 'day',
token: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC
}]
}
},
},
/* ... */
}]
})
permissions
Use a provided permission for the request.
The following JSON-RPC methods support the permissions
request capability:
type Capability = {
/** Permission to use for the request. */
permissions: {
/** ID of the permission to use. */
id: `0x${string}`
}
}
Example
const capabilities = await provider.request({
method: 'wallet_sendCalls',
params: [{
capabilities: {
permissions: {
id: '0x...',
},
},
/* ... */
}]
})
Response Capabilities
permissions
Returns the permissions granted on the request.
The following JSON-RPC methods support the permissions
response capability:
type Capability = {
permissions: {
expiry: number,
id: `0x${string}`,
key: {
publicKey: `0x${string}`,
type: 'address' | 'p256' | 'secp256k1' | 'webauthn-p256',
},
permissions: {
calls: {
signature?: string
to?: `0x${string}`
}[],
spend: {
limit: bigint
period: 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year'
token?: `0x${string}`
}[]
}
publicKey: `0x${string}`,
type: 'address' | 'p256' | 'secp256k1' | 'webauthn-p256'
}[]
}
Example
const capabilities = await provider.request({
method: 'wallet_connect',
params: [{
capabilities: {
grantPermissions: { /* ... */ },
},
/* ... */
}]
})
[{ address: '0x1234567890123456789012345678901234567890', capabilities: { permissions: [{ expiry: 1727078400, id: '0x...', key: { publicKey: '0x...', type: 'p256' }, permissions: { calls: [{ signature: 'subscribe()', }], spend: [{ limit: '0x5f5e100', // 100 USDC period: 'day', token: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC }] } }] }, }]
sponsor
A sponsor server can be set up by the Application to sponsor actions on behalf of their users.
Request Capabilities
sponsorUrl
URL of the endpoint that will be used to front and sponsor call bundles for users.
The following JSON-RPC methods support the sponsorUrl
request capability:
type Capability = {
sponsorUrl: string
}
Example
const capabilities = await provider.request({
method: 'wallet_sendCalls',
params: [{
capabilities: {
sponsorUrl: 'https://myapp.com/sponsor'
},
/* ... */
}]
})