### Project Setup and Run Source: https://github.com/ithacaxyz/porto/blob/main/examples/authentication-rainbowkit/README.md Follow these steps to clone the example project, install dependencies, configure environment variables, and start the development server. ```bash pnpx gitpick ithacaxyz/porto/tree/main/examples/authentication-rainbowkit porto-rainbowkit && cd porto-rainbowkit pnpm i cp .env.example .env pnpm dev ``` -------------------------------- ### Setup and Run Porto Guest Checkout Example Source: https://github.com/ithacaxyz/porto/blob/main/examples/guest-checkout/README.md Clone the example repository, install dependencies using pnpm, and start the development server. ```sh pnpx gitpick ithacaxyz/porto/tree/main/examples/guest-checkout porto-guest-checkout && cd porto-guest-checkout pnpm i pnpm dev ``` -------------------------------- ### Setup and Run Vite React Example Source: https://github.com/ithacaxyz/porto/blob/main/apps/playground-interop/README.md Clone the example project, install dependencies using pnpm, and start the development server. ```sh pnpx gitpick ithacaxyz/porto/tree/main/examples/vite-react porto-vite && cd porto-vite pnpm i pnpm dev ``` -------------------------------- ### Project Setup and Development Source: https://github.com/ithacaxyz/porto/blob/main/examples/authentication/README.md Follow these commands to clone the example project, install dependencies, configure environment variables, and start the development server. ```bash pnpx gitpick ithacaxyz/porto/tree/main/examples/authentication porto-auth && cd porto-auth pnpm i cp .env.example .env pnpm dev ``` -------------------------------- ### Setup and Run Porto Theming Example Source: https://github.com/ithacaxyz/porto/blob/main/examples/theming/README.md Use these commands to clone the Porto theming example, install dependencies, and start the development server. ```sh pnpx gitpick ithacaxyz/porto/tree/main/examples/theming porto-theming && cd porto-theming pnpm i pnpm dev ``` -------------------------------- ### Setup Porto Payments Project Source: https://github.com/ithacaxyz/porto/blob/main/examples/payments/README.md Clone the Porto payments example, install dependencies, and start the development server. ```sh pnpx gitpick ithacaxyz/porto/tree/main/examples/payments porto-payments && cd porto-payments pnpm i pnpm dev ``` -------------------------------- ### Project Setup and Initialization Source: https://github.com/ithacaxyz/porto/blob/main/examples/authentication-better-auth/README.md Follow these commands to clone the project, install dependencies, configure environment variables, generate the database schema, and start the development server. ```sh pnpx gitpick ithacaxyz/porto/tree/main/examples/authentication-better-auth porto-better-auth && cd porto-better-auth ``` ```sh pnpm i ``` ```sh cp .env.example .env ``` ```sh pnpm db:generate ``` ```sh pnpm dev ``` -------------------------------- ### Setup Project Source: https://github.com/ithacaxyz/porto/blob/main/examples/sponsoring-vite/README.md Use this command to clone the example project and navigate into its directory. ```sh pnpx gitpick ithacaxyz/porto/tree/main/examples/sponsoring-vite porto-sponsoring && cd porto-sponsoring ``` -------------------------------- ### Setup and Run Dynamic Porto Project Source: https://github.com/ithacaxyz/porto/blob/main/examples/dynamic/README.md Use these commands to clone the dynamic Porto example, install its dependencies, and start the development server. ```sh pnpx gitpick ithacaxyz/porto/tree/main/examples/dynamic porto-dynamic && cd porto-dynamic ``` ```sh pnpm i ``` ```sh pnpm dev ``` -------------------------------- ### Project Setup and Initialization Source: https://github.com/ithacaxyz/porto/blob/main/examples/react-native-relay-mode/README.md Use these commands to clone the example project and set up the environment variables. ```sh pnpx gitpick ithacaxyz/porto/tree/main/examples/react-native-relay-mode porto-react-native-relay-app && cd porto-react-native-relay-app cp .env.example .env ``` -------------------------------- ### Install and Run Porto CLI Example Source: https://github.com/ithacaxyz/porto/blob/main/examples/cli/README.md Installs the Porto CLI from a specific Git branch, navigates into the project directory, installs dependencies, links the package, and then runs the example CLI command. ```sh pnpx gitpick ithacaxyz/porto/tree/main/examples/cli porto-cli && cd porto-cli pnpm i pnpm link example-cli ``` -------------------------------- ### Install Dependencies and Run Dev Server Source: https://github.com/ithacaxyz/porto/blob/main/apps/dialog/README.md Run these commands from the project root to install dependencies and start the development server. ```sh pnpm i pnpm dev ``` -------------------------------- ### Install Dependencies and Run Development Server Source: https://github.com/ithacaxyz/porto/blob/main/apps/id/README.md Run these commands from the project root to install dependencies and start the development server for the ID application. ```sh pnpm i pnpm dev:id ``` -------------------------------- ### Setup React Native Project Source: https://github.com/ithacaxyz/porto/blob/main/examples/react-native/README.md Use this command to clone the React Native example project and navigate into its directory. ```sh pnpx gitpick ithacaxyz/porto/tree/main/examples/react-native porto-react-native-app && cd porto-react-native-app ``` -------------------------------- ### Install and Run Porto Apps Source: https://github.com/ithacaxyz/porto/blob/main/README.md Installs project dependencies and starts the id, playground, and iframe dialog for Porto applications. Use this for local development. ```bash pnpm install pnpm dev ``` -------------------------------- ### Example: Prepare EOA Upgrade Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/rpc/wallet_prepareUpgradeAccount.mdx Demonstrates how to call `wallet_prepareUpgradeAccount` to get the necessary context and digests for upgrading an EOA, and then signing them with the EOA. ```typescript import { Porto } from 'porto' import { privateKeyToAccount } from 'viem/accounts' const { provider } = Porto.create() const eoa = privateKeyToAccount('0x...') const { context, digests } = await provider.request ({ method: 'wallet_prepareUpgradeAccount', // [!code focus] params: [{ address: eoa.address, // [!code focus] }], // [!code focus] }) // [!code focus] const signatures = { auth: await eoa.sign({ hash: digests.auth }), exec: await eoa.sign({ hash: digests.exec }), } as const const response = await provider.request({ method: 'wallet_upgradeAccount', params: [{ context, signatures, }], }) ``` -------------------------------- ### Porto CLI for Merchant Onboarding Source: https://context7.com/ithacaxyz/porto/llms.txt Use the Porto CLI to onboard new merchant accounts and manage credentials. This example shows how to install and run the CLI, onboard an account on the testnet, and set up environment variables. ```bash # Install and run via npx npx porto --help # Onboard a new merchant account on testnet npx porto onboard --admin-key --testnet # Output: # MERCHANT_ADDRESS=0x... # MERCHANT_PRIVATE_KEY=0x... # Place credentials in .env echo "MERCHANT_ADDRESS=0x..." >> .env echo "MERCHANT_PRIVATE_KEY=0x..." >> .env ``` -------------------------------- ### Get Wallet Capabilities using Porto SDK Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/rpc/wallet_getCapabilities.mdx Demonstrates how to use the Porto SDK to request wallet capabilities. This example shows the basic call to the provider to get the supported features of the wallet. ```typescript import { Porto } from 'porto' const { provider } = Porto.create() const capabilities = await provider.request({ method: 'wallet_getCapabilities', }) ``` -------------------------------- ### Wagmi Configuration Example Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/wagmi/getAssets.mdx This snippet shows a typical configuration setup for Wagmi, which is required for using actions like getAssets. ```typescript // [!include ~/snippets/wagmi/config.ts] ``` -------------------------------- ### Install Foundry and Build Contracts Source: https://github.com/ithacaxyz/porto/blob/main/README.md Installs the Foundry toolchain and builds the smart contracts for the account and demo modules. Ensure Foundry is installed before running. ```bash # Install Foundry foundryup forge build --config-path ./contracts/account/foundry.toml # Build forge test --config-path ./contracts/account/foundry.toml # Test forge build --config-path ./contracts/demo/foundry.toml # Build forge test --config-path ./contracts/demo/foundry.toml # Test ``` -------------------------------- ### Basic Wallet Connect Example Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/rpc/wallet_connect.mdx A basic example demonstrating how to initiate a wallet connection using the provider.request method with the 'wallet_connect' method. ```typescript import { Porto } from 'porto' const { provider } = Porto.create() const response = await provider.request({ method: 'wallet_connect', }) ``` -------------------------------- ### Clone and Navigate Project Source: https://github.com/ithacaxyz/porto/blob/main/examples/sponsoring-privy/README.md Use this command to clone the example project and navigate into its directory. ```sh pnpx gitpick ithacaxyz/porto/tree/main/examples/sponsoring-privy porto-sponsoring-privy && cd porto-sponsoring-privy ``` -------------------------------- ### Example: Sending Prepared Calls with wallet_sendPreparedCalls Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/rpc/wallet_sendPreparedCalls.md Demonstrates how to prepare calls using wallet_prepareCalls, sign the digest, and then send the prepared calls with the signature using wallet_sendPreparedCalls. This example utilizes WebCryptoP256 for key pair generation and signing. ```typescript import { Porto } from 'porto' import { PublicKey, Signature, WebCryptoP256 } from 'ox' const { provider } = Porto.create() const { publicKey, privateKey } = await WebCryptoP256.createKeyPair() const { digest, ...request } = await provider.request({ method: 'wallet_prepareCalls', params: [{ calls: [{ to: '0xcafebabecafebabecafebabecafebabecafebabe', value: '0x12345678', }], key: { publicKey: PublicKey.toHex(publicKey), type: 'p256' } }] }) const signature = await WebCryptoP256.sign({ payload: digest, privateKey, }) const response = await provider.request({ method: 'wallet_sendPreparedCalls', params: [{ ...request, signature: Signature.toHex(signature) }] }) ``` -------------------------------- ### Clone and Navigate Project Source: https://github.com/ithacaxyz/porto/blob/main/examples/sponsoring-next.js/README.md Use this command to clone the example project and navigate into its directory. ```sh pnpx gitpick ithacaxyz/porto/tree/main/examples/sponsoring-next.js porto-sponsoring && cd porto-sponsoring ``` -------------------------------- ### Install and Run Porto Tests Source: https://github.com/ithacaxyz/porto/blob/main/README.md Installs project dependencies and runs the test suite for Porto. Use this to verify the integrity of the project. ```bash pnpm install pnpm test ``` -------------------------------- ### Install Porto SDK with NPM, PNPM, or BUN Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/index.mdx Install the Porto SDK using your preferred package manager. ```bash npm i porto ``` ```bash pnpm i porto ``` ```bash bun i porto ``` -------------------------------- ### Clone Sponsoring Next.js Example Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/guides/sponsoring.mdx Use this command to clone the Next.js-based example for fee sponsoring. ```bash pnpx gitpick ithacaxyz/porto/tree/main/examples/sponsoring-next.js ``` -------------------------------- ### Clone and Run Next.js Project Source: https://github.com/ithacaxyz/porto/blob/main/examples/next.js/README.md Use these commands to clone a Next.js project from a GitHub repository, install its dependencies using pnpm, and start the development server. ```sh pnpx gitpick ithacaxyz/porto/tree/main/examples/next.js porto-next && cd porto-next pnpm i pnpm dev ``` -------------------------------- ### Install Dependencies Source: https://github.com/ithacaxyz/porto/blob/main/examples/react-native-relay-mode/README.md Installs all necessary project dependencies using pnpm. ```sh pnpm i ``` -------------------------------- ### Clone Sponsoring Vite Example Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/guides/sponsoring.mdx Use this command to clone the Vite-based example for fee sponsoring. ```bash pnpx gitpick ithacaxyz/porto/tree/main/examples/sponsoring-vite ``` -------------------------------- ### Example: Requesting Wallet Connect with Grant Permissions Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/rpc/capabilities.mdx This example demonstrates how to structure a `wallet_connect` request that includes the `grantPermissions` capability, specifying expiry, fee token, and detailed call and spend permissions. ```typescript // @noErrors const capabilities = await provider.request({ method: 'wallet_connect', params: [{ capabilities: { // [!code focus] grantPermissions: { // [!code focus] expiry: 1727078400, // [!code focus] feeToken: { // [!code focus] limit: '1', // [!code focus] symbol: 'USDC', // [!code focus] }, // [!code focus] permissions: { // [!code focus] calls: [{ signature: 'subscribe()' }], // [!code focus] spend: [{ // [!code focus] limit: '0x5f5e100', // 100 USDC // [!code focus] period: 'day', // [!code focus] token: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC // [!code focus] }] // [!code focus] } // [!code focus] }, }, // [!code focus] /* ... */ }] }) ``` -------------------------------- ### Run Server - Development Source: https://github.com/ithacaxyz/porto/blob/main/examples/react-native-relay-mode/README.md Starts the server in development mode with hot-reloading. ```sh bun --watch --hot ./server/index.ts --env-file .env ``` -------------------------------- ### Execution Example Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/contracts/account.md Example demonstrating how to construct and execute a batch of calls from an arbitrary sender. ```APIDOC ## Example ```solidity Call memory call = Call({ to:
, value: 0, data: }); uint256 nonce = account.getNonce(0); // 0 is the uint192 sequence key bytes memory signature = _sign(computeDigest(calls, nonce)); bytes memory opData = abi.encodePacked(nonce, signature); bytes memory executionData = abi.encode(calls, opData); account.execute(_ERC7821_BATCH_EXECUTION_MODE, executionData); ``` ``` -------------------------------- ### Start Development Environment with Anvil Source: https://github.com/ithacaxyz/porto/blob/main/apps/playground/README.md Use this command to start the local Anvil blockchain environment for development and testing. ```bash pnpm dev:anvil ``` -------------------------------- ### TryItOut Example for wallet_getCallsHistory Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/wagmi/useCallsHistory.mdx This example demonstrates how to use the TryItOut component to interact with the wallet_getCallsHistory RPC method. It requests accounts, fetches the call history, and transforms the result for display. ```javascript async ({ provider }) => { const [address] = await provider.request({ method: 'eth_requestAccounts' }) return provider.request({ method: 'wallet_getCallsHistory', params: [{ address, limit: 5, sort: 'desc', }], }) } ``` ```javascript (code) => { return 'const history = ' + code } ``` -------------------------------- ### Example JSON Response for wallet_getCapabilities Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/relay/wallet_getCapabilities.md An example of the JSON response returned by the `wallet_getCapabilities` method, detailing contract addresses and fee information for a specific chain. ```json { "0x14a34": { "contracts": { "orchestrator": { "address": "0xb447ba5a2fb841406cdac4585fdc28027d7ae503", "version": "0.4.6" }, "accountImplementation": { "address": "0xc4e1dc6045234b913db45e8f51e770d6d12e42a1", "version": "0.4.11" }, "legacyOrchestrators": [], "legacyAccountImplementations": [], "accountProxy": { "address": "0x5874f358359ee96d2b3520409018f1a6f59a2cdc", "version": null }, "simulator": { "address": "0xcb80788813c39d90c48c2733b43b3e47e23a2d3f", "version": null }, "funder": { "address": "0x665efbf4b831aac6b712471c6bbfdb11e1721b4f", "version": null }, "escrow": { "address": "0x55626138525a47af075322aafe1df8f68993b11d", "version": null } }, "fees": { "recipient": "0x665efbf4b831aac6b712471c6bbfdb11e1721b4f", "quoteConfig": { "constantRate": null, "gas": { "intentBuffer": 20000, "txBuffer": 10000 }, "ttl": 30, "rateTtl": 300 }, "tokens": [ { "uid": "exp2", "address": "0x2ace05bcb50b49953aaa4c00f318db908a512d99", "decimals": 18, "feeToken": true, "interop": true, "symbol": "EXP2", "nativeRate": "0xc536acbc02a4" }, { "uid": "exp1", "address": "0x74e294e9d05bace256796040ca6dc0c47efb9fff", "decimals": 18, "feeToken": true, "interop": true, "symbol": "EXP", "nativeRate": "0xc536acbc02a4" }, { "uid": "teth", "address": "0x0000000000000000000000000000000000000000", "decimals": 18, "feeToken": true, "interop": true, "symbol": "ETH", "nativeRate": "0xde0b6b3a7640000" } ] } } } ``` -------------------------------- ### prepareUpgradeAccount Usage Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/viem/RelayActions/prepareUpgradeAccount.mdx Demonstrates how to use the `prepareUpgradeAccount` function with an example. ```APIDOC ## `prepareUpgradeAccount` ### Description Prepares an EOA to be upgraded to a Porto Account. ### Method Signature `prepareUpgradeAccount(client, parameters)` ### Parameters #### `client` - **Type:** `Viem Client` - **Description:** The Viem client instance. #### `parameters` - **Type:** `object` - **`address`** (`Address.Address`) - Required - Address of the EOA account to upgrade. - **`authorizeKeys`** (`readonly Key.Key[]`) - Required - Keys to authorize on the upgraded account. - **`delegation`** (`Address.Address`) - Optional - Contract address to delegate to. Defaults to the account proxy contract. - **`feeToken`** (`'native' | Token.Symbol | Address.Address`) - Optional - Token to use to cover fees. Accepts: - `"native"` (Default): The native token of the chain. - Symbol: Symbol of the fee token (e.g. `"USDC"`). - Address: Address of the fee token (e.g. `"0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"`). ### Returns See [`wallet_prepareUpgradeAccount`](/relay/wallet_prepareUpgradeAccount#response). ### Example ```ts import { RelayActions, Key } from 'porto/viem' import { client } from './config' const adminKey = Key.createSecp256k1({ role: 'admin' }) const prepared = await RelayActions.prepareUpgradeAccount(client, { address: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', authorizeKeys: [adminKey], }) ``` ``` -------------------------------- ### Example Usage of eth_requestAccounts Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/rpc/eth_requestAccounts.mdx Demonstrates how to use the eth_requestAccounts method with a provider to get connected account addresses. Ensure you have Porto initialized. ```typescript import { Porto } from 'porto' const { provider } = Porto.create() const accounts = await provider.request({ method: 'eth_requestAccounts' }) // [!code focus] ``` -------------------------------- ### Get Assets for an Account - Wagmi Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/wagmi/getAssets.mdx Use Actions.getAssets to retrieve assets for an account. Ensure you have the config object imported from your wagmi setup. ```typescript import { Actions } from 'porto/wagmi' import { config } from './config' const assets = await Actions.getAssets(config, { account: '0x...', }) ``` -------------------------------- ### Get Account Assets Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/rpc/wallet_getAssets.mdx This example demonstrates how to request assets for an account. It first requests account authorization and then calls `wallet_getAssets` with the account address. ```typescript import { Porto } from 'porto' const { provider } = Porto.create() const [account] = await provider.request({ method: 'eth_requestAccounts' }) const assets = await provider.request({ method: 'wallet_getAssets', params: [{ account }], }) ``` -------------------------------- ### Initialize Porto with Viem Wallet Client Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/index.mdx Set up a Viem Wallet Client using Porto's provider for interacting with Viem Wallet Actions. ```typescript import { custom, createWalletClient } from 'viem' import { baseSepolia } from 'viem/chains' import { Porto } from 'porto' // 1. Initialize Porto. const porto = Porto.create() // 2. Initialize Wallet Client. const walletClient = createWalletClient({ chain: baseSepolia, transport: custom(porto.provider), }) // 3. Use Wallet Actions. const addresses = await walletClient.requestAddresses() ``` -------------------------------- ### Next.js Router Integration Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/api/router.mdx Integrate the Porto router into a Next.js application using the App Router. This example sets up routes for GET, OPTIONS, and POST requests. ```typescript import { Router, Route } from 'porto/server' const porto = Router({ basePath: '/porto' }) .route('/merchant', Route.merchant({ /* ... */ }) // .route('/auth', Route.auth({/* ... */}) 🚧 // .route('/rpc', Route.relay({/* ... */}) 🚧 ) export const GET = porto.fetch export const OPTIONS = porto.fetch export const POST = porto.fetch ``` -------------------------------- ### Get Relay Capabilities with Viem Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/viem/RelayActions/getCapabilities.mdx Import and use the `getCapabilities` action from `porto/viem` with your Viem client. Ensure your client configuration is set up correctly, as shown in the `config.ts` example. ```typescript import { RelayActions } from 'porto/viem' import { client } from './config' const capabilities = await RelayActions.getCapabilities(client) // [!code focus] ``` ```typescript // [!include ~/snippets/viem/config.server.ts] ``` -------------------------------- ### Broadcasting Prepared Calls with Viem RelayActions Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/viem/RelayActions/sendPreparedCalls.mdx This example demonstrates how to create an account, prepare calls, sign the digest, and then send the prepared calls using `RelayActions.sendPreparedCalls`. Ensure you have the necessary imports and client configuration. ```typescript import { RelayActions, Key } from 'porto/viem' import { parseEther } from 'viem' import { client } from './config' // Create (or import) account const key = Key.createP256() const account = await RelayActions.createAccount(client, { authorizeKeys: [key], }) // Prepare the calls const request = await RelayActions.prepareCalls(client, { account, calls: [{ to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8', value: parseEther('0.01'), }], key, }) // Sign the digest // [!code focus] const signature = await RelayActions.signCalls(request, { key }) // [!code focus] // Send the prepared calls // [!code focus] const result = await RelayActions.sendPreparedCalls(client, { // [!code focus] ...request, // [!code focus] signature, // [!code focus] }) // [!code focus] ``` ```typescript // [!include ~/snippets/viem/config.server.ts] ``` -------------------------------- ### SimpleSettler Usage Examples Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/contracts/interop/settlement.mdx Demonstrates how to use SimpleSettler for direct owner-initiated settlements or permissionless settlements using EIP-712 signatures, and how to verify settlement status. ```solidity // Owner directly writes settlement simpleSettler.write(senderAddress, settlementId, chainId); // Or use signature for permissionless settlement bytes memory signature = signSettlement(sender, settlementId, chainId); simpleSettler.write(sender, settlementId, chainId, signature); // Verify settlement bool isSettled = simpleSettler.read(settlementId, sender, chainId); ``` -------------------------------- ### Install Dependencies with pnpm Source: https://github.com/ithacaxyz/porto/blob/main/CLAUDE.md Use this command to install all project dependencies using pnpm. ```bash pnpm install # Install dependencies ``` -------------------------------- ### Instantiate Session Key with Permissions Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/viem/Key/fromWebCryptoP256.mdx This example shows how to create a session key with specific permissions, including call restrictions and spending limits. ```APIDOC ## Key.fromWebCryptoP256 Instantiates a WebCryptoP256 key from existing WebCrypto key pair parameters. ### Usage #### Session Key with Permissions ```ts import { Key } from 'porto/viem' import { WebCryptoP256 } from 'ox' import { parseEther } from 'viem' const keyPair = await WebCryptoP256.createKeyPair() const key = Key.fromWebCryptoP256({ expiry: Math.floor(Date.now() / 1000) + 60 * 60, // 1 hour keyPair, permissions: { calls: [{ signature: 'transfer(address,uint256)', to: '0xaf3b0a5b4becc4fa1dfafe74580efa19a2ea49fa', }], spend: [{ limit: parseEther('50'), // 50 EXP period: 'day', token: '0xaf3b0a5b4becc4fa1dfafe74580efa19a2ea49fa', }], }, role: 'session', }) ``` ### Parameters #### expiry - **Type:** `number | undefined` The expiry timestamp of the key (Unix timestamp). Defaults to 0 (never expires). #### keyPair - **Type:** `KeyPair` WebCrypto P256 key pair (required). ```ts type KeyPair = { /** Web Crypto private key */ privateKey: CryptoKey /** Web Crypto public key */ publicKey: CryptoKey } ``` #### permissions The permissions associated with the key. ```ts type Permissions = { /** Call permissions - which functions the key can call */ calls?: { /** Function signature or 4-byte selector */ signature?: string | undefined /** Target contract address */ to?: `0x${string}` | undefined }[] | undefined /** Spend permissions - spending limits for tokens */ spend?: { /** Spending limit per period (in wei) */ limit: `0x${string}` /** Time period for the spending limit */ period: 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year' /** ERC20 token address (defaults to native token if not provided) */ token?: `0x${string}` | undefined }[] | undefined } ``` #### role - **Type:** `"admin" | "session" | undefined` The role of the key. Defaults to 'admin'. ### Return Value ```ts type WebCryptoKey = { /** Key expiry timestamp */ expiry: number /** Key hash identifier */ hash: `0x${string}` /** Key ID (lowercase public key) */ id: `0x${string}` /** Optional permissions */ permissions?: Permissions | undefined /** Whether the key requires prehashing (always true for WebCrypto) */ prehash: true /** Web Crypto private key */ privateKey: CryptoKey /** Public key (64 bytes, uncompressed, without 0x04 prefix) */ publicKey: `0x${string}` /** Key role */ role: 'admin' | 'session' /** Key type - always 'p256' (reuses P256 type with WebCrypto backend) */ type: 'p256' } ``` ``` -------------------------------- ### Example Usage of wallet_upgradeAccount Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/rpc/wallet_upgradeAccount.mdx Demonstrates how to use `wallet_upgradeAccount` after preparing the upgrade with `wallet_prepareUpgradeAccount`. This involves obtaining context and digests, signing them, and then sending the upgrade request. ```typescript import { Porto } from 'porto' import { privateKeyToAccount } from 'viem/accounts' const { provider } = Porto.create() const eoa = privateKeyToAccount('0x...') const { context, digests } = await provider.request({ method: 'wallet_prepareUpgradeAccount', params: [{ address: eoa.address, }], }) const signatures = { auth: await eoa.sign({ hash: digests.auth }), exec: await eoa.sign({ hash: digests.exec }), } as const const response = await provider.request({ // [!code focus] method: 'wallet_upgradeAccount', // [!code focus] params: [{ context, // [!code focus] signatures, // [!code focus] }], // [!code focus] }) // [!code focus] ``` -------------------------------- ### Start Development Server with Tunnel Source: https://github.com/ithacaxyz/porto/blob/main/examples/react-native/README.md Starts the development server with a tunnel, useful for remote debugging or testing. ```sh pnpm expo start --dev-client --tunnel --clear ``` -------------------------------- ### Install vite-plugin-mkcert for Vite HTTPS Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/index.mdx Install the vite-plugin-mkcert package to enable HTTPS on Vite's development server. ```bash npm i vite-plugin-mkcert ``` -------------------------------- ### Example Request for Base Sepolia using `cast` Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/relay/wallet_addFaucetFunds.md Demonstrates how to use the `cast` command-line tool to request faucet funds for the Base Sepolia testnet. Ensure to replace placeholders with actual values. ```bash cast rpc --rpc-url https://rpc.porto.sh \ wallet_addFaucetFunds '[{"address":"0xYourAddress","chainId":84532,"tokenAddress":"0x3a9b126bf65c518f1e02602bd77bd1288147f94c","value":25}]' --raw ``` -------------------------------- ### Batch Execution Example Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/contracts/account.md Demonstrates how to construct and execute a batch of calls from an arbitrary sender. It involves signing the calls with a nonce and then encoding the calls and opData for the `execute` function. ```solidity Call memory call = Call({ to:
, value: 0, data: }); uint256 nonce = account.getNonce(0); // 0 is the uint192 sequence key bytes memory signature = _sign(computeDigest(calls, nonce)); bytes memory opData = abi.encodePacked(nonce, signature); bytes memory executionData = abi.encode(calls, opData); account.execute(_ERC7821_BATCH_EXECUTION_MODE, executionData); ``` -------------------------------- ### Complete Cross-Chain Trade Integration Example Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/contracts/interop/settlement.mdx Demonstrates the steps for executing a complete cross-chain trade using LayerZeroSettler, including escrow creation, sending settlement, and final settlement confirmation. ```solidity // 1. Create escrow with LayerZeroSettler Escrow memory escrowData = Escrow({ settler: address(layerZeroSettler), settlementId: tradeId, senderChainId: 137, // Expecting from Polygon // ... other fields }); // 2. On source chain (Polygon): Send settlement layerZeroSettler.send(tradeId, abi.encode([1])); // To Ethereum layerZeroSettler.executeSend{value: fee}( orchestrator, tradeId, abi.encode([1]) ); // 3. On destination chain: Settlement auto-recorded via _lzReceive // 4. Settle the escrow escrow.settle([escrowId]); // Automatically verified with settler ``` -------------------------------- ### Instantiate Key from WebCrypto Key Pair Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/viem/Key/fromWebCryptoP256.mdx This example demonstrates how to create a `Key` instance using an existing WebCrypto P256 key pair. ```APIDOC ## Key.fromWebCryptoP256 Instantiates a WebCryptoP256 key from existing WebCrypto key pair parameters. ### Usage #### From WebCrypto Key Pair ```ts import { Key } from 'porto/viem' import { WebCryptoP256 } from 'ox' const keyPair = await WebCryptoP256.createKeyPair() const key = Key.fromWebCryptoP256({ keyPair, }) ``` ### Parameters #### keyPair - **Type:** `KeyPair` WebCrypto P256 key pair (required). ```ts type KeyPair = { /** Web Crypto private key */ privateKey: CryptoKey /** Web Crypto public key */ publicKey: CryptoKey } ``` ### Return Value ```ts type WebCryptoKey = { /** Key expiry timestamp */ expiry: number /** Key hash identifier */ hash: `0x${string}` /** Key ID (lowercase public key) */ id: `0x${string}` /** Optional permissions */ permissions?: Permissions | undefined /** Whether the key requires prehashing (always true for WebCrypto) */ prehash: true /** Web Crypto private key */ privateKey: CryptoKey /** Public key (64 bytes, uncompressed, without 0x04 prefix) */ publicKey: `0x${string}` /** Key role */ role: 'admin' | 'session' /** Key type - always 'p256' (reuses P256 type with WebCrypto backend) */ type: 'p256' } ``` ``` -------------------------------- ### eth_sendTransaction Example Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/rpc/eth_sendTransaction.mdx This example demonstrates how to send a basic transaction using eth_sendTransaction. Ensure you have the Porto SDK initialized and a provider available. ```typescript import { Porto } from 'porto' const { provider } = Porto.create() const hash = await provider.request({ method: 'eth_sendTransaction', params: [{ from: '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', to: '0xcafebabecafebabecafebabecafebabecafebabe', value: '0x1', }], }) ``` -------------------------------- ### Example: Using Permissions Capability in `wallet_sendCalls` Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/rpc/capabilities.mdx This example shows how to include the `permissions` capability in a `wallet_sendCalls` request, referencing a specific permission ID. ```typescript // @noErrors const capabilities = await provider.request({ method: 'wallet_sendCalls', params: [{ capabilities: { // [!code focus] permissions: { // [!code focus] id: '0x...', // [!code focus] }, // [!code focus] }, // [!code focus] /* ... */ }] }) ``` -------------------------------- ### Build and Run Development Servers Source: https://github.com/ithacaxyz/porto/blob/main/CLAUDE.md Commands for building the core library and running development servers for the playground, dialog, and id services. Includes options for running with local Relay and Anvil services, or with the wagmi playground. ```bash pnpm build # Build the core library pnpm dev # Link library & run dev servers (playground, dialog, id) pnpm dev:anvil # Run `pnpm dev` with local Relay and Anvil services pnpm dev:wagmi # Run `pnpm dev` with wagmi playground ``` -------------------------------- ### Sign In with Ethereum Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/wagmi/connect.mdx This example shows how to use `Actions.connect` with the `signInWithEthereum` parameter to enable Sign-In with Ethereum (ERC-4361) authentication. ```APIDOC ## Actions.connect with Sign In with Ethereum ### Parameters #### signInWithEthereum `SignInWithEthereum` [ERC-4361](https://eips.ethereum.org/EIPS/eip-4361) Sign-In with Ethereum options. ```ts type SignInWithEthereum = { /* Required fields */ authUrl: string | { logout: string nonce: string verify: string } // OR nonce: string /* Optional fields */ chainId?: number | undefined domain?: string | undefined // Defaults to window/iframe parent expirationTime?: Date | undefined issuedAt?: Date | undefined notBefore?: Date | undefined requestId?: string | undefined resources?: string[] | undefined scheme?: string | undefined statement?: string | undefined uri?: string | undefined // Defaults to window/iframe parent version?: '1' | undefined } ``` ``` -------------------------------- ### Connect Account with Permissions Source: https://github.com/ithacaxyz/porto/blob/main/apps/docs/pages/sdk/wagmi/connect.mdx This example shows how to use `Actions.connect` with the `grantPermissions` parameter to allow the application to perform actions on behalf of the account. ```APIDOC ## Actions.connect with Grant Permissions ### Grant Permissions You can grant permissions for an application to perform actions on behalf of the account by providing the `grantPermissions` parameter. ```ts import { Actions } from 'porto/wagmi' import { porto } from 'wagmi/connectors' import { parseEther, toHex } from 'viem' import { config } from './config' const token = '0xaf3b0a5b4becc4fa1dfafe74580efa19a2ea49fa' const result = await Actions.connect(config, { connector: porto(), grantPermissions: { expiry: Math.floor(Date.now() / 1_000) + 60 * 60, // 1 hour permissions: { calls: [{ signature: 'transfer(address,uint256)', to: token, }], spend: [{ limit: toHex(parseEther('50')), // 50 EXP period: 'day', token: token, }], }, }, }) ``` ### Parameters #### grantPermissions `Permissions` to grant to the account. ```ts type GrantPermissions = { /** Expiry timestamp for the permissions */ expiry: number /** * Fee token that will be used with these permissions. */ feeToken: { /** Value of the limit in the symbols's unit (e.g. '1' = 1 USDC). */ limit: string /** Symbol of the fee token. `undefined` for native token. */ symbol?: Token.Symbol | undefined } | undefined, /** 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 to grant */ 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 (defaults to native token) */ token?: `0x${string}` }[] } } ``` ```