Skip to content

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:

CapabilityDescriptionStandard
feeTokenIndicates if custom fee tokens are supported.Experimental
permissionsIndicates if permissions can be requested by the app.Experimental
sponsorIndicates 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'
    },
    /* ... */
  }]
})