diff --git a/app-developers/guides/configuring-actions.mdx b/app-developers/guides/configuring-actions.mdx index 5284e0216..d93f40a6d 100644 --- a/app-developers/guides/configuring-actions.mdx +++ b/app-developers/guides/configuring-actions.mdx @@ -147,7 +147,7 @@ Actions SDK lets you choose which assets, markets, chains, protocols, and provid - Configure which assets you want to support across all lend providers: + Configure which assets you want to support across all lend and swap providers: ```typescript title="actions.ts" // Additional config from previous steps... @@ -215,6 +215,74 @@ Actions SDK lets you choose which assets, markets, chains, protocols, and provid }; ``` + + + Configure which swap protocols you want to support. Actions SDK supports [Uniswap V4](https://uniswap.org/) on Ethereum mainnet and OP Stack chains, and [Velodrome](https://velodrome.finance/) / [Aerodrome](https://aerodrome.finance/) on OP Stack chains: + + + + ```typescript title="actions.ts" + // Additional config from previous steps... + + import { UniswapSwapProvider } from "@eth-optimism/actions-sdk"; + import type { SwapConfig } from "@eth-optimism/actions-sdk"; + + const swapConfig: SwapConfig = { + uniswap: { + // Optional: restrict to specific trading pairs + marketAllowlist: [ + { assets: [USDC, ETH] }, + { assets: [USDC, WETH], chainId: base.id }, + ], + defaultSlippage: 0.005, // 0.5% default slippage + maxSlippage: 0.5, // 50% max slippage guard + }, + }; + ``` + + + ```typescript title="actions.ts" + // Additional config from previous steps... + + import { VelodromeSwapProvider } from "@eth-optimism/actions-sdk"; + import type { SwapConfig } from "@eth-optimism/actions-sdk"; + + // Velodrome (Optimism) and Aerodrome (Base) use the same provider. + // Supported on Optimism, Base, and many OP Stack leaf chains. + const swapConfig: SwapConfig = { + velodrome: { + // Optional: restrict to specific trading pairs + // Set stable: true for correlated assets (e.g. USDC/USDT) + marketAllowlist: [ + { assets: [USDC, ETH], stable: false }, + { assets: [USDC, WETH], stable: false, chainId: base.id }, + ], + defaultSlippage: 0.005, + maxSlippage: 0.5, + }, + }; + ``` + {/* TODO: Confirm the full list of chains supported by the Velodrome leaf router and whether the `stable` flag is required or optional per market */} + + + ```typescript title="actions.ts" + // Configure both providers — Actions will use them independently + // based on the swap namespace's provider routing logic. + // TODO: confirm best-price routing behavior across providers + const swapConfig: SwapConfig = { + uniswap: { + marketAllowlist: [{ assets: [USDC, ETH] }], + }, + velodrome: { + marketAllowlist: [ + { assets: [USDC, ETH], stable: false }, + ], + }, + }; + ``` + + + Configure supported chains: @@ -259,6 +327,7 @@ Actions SDK lets you choose which assets, markets, chains, protocols, and provid wallet: walletConfig, assets: assetsConfig, lend: lendConfig, + swap: swapConfig, chains, }); ``` @@ -274,6 +343,14 @@ Actions SDK lets you choose which assets, markets, chains, protocols, and provid const market = await actions.lend.getMarket({ ... }); const wallet = await actions.wallet.createSmartWallet({ ... }); const receipt = await wallet.lend.openPosition({ ... }); + + // Swap tokens + const swapReceipt = await wallet.swap.execute({ + amountIn: 100, + assetIn: USDC, + assetOut: ETH, + chainId: base.id, + }); ``` diff --git a/app-developers/quickstarts/actions.mdx b/app-developers/quickstarts/actions.mdx index 5df2bcf62..a00b822eb 100644 --- a/app-developers/quickstarts/actions.mdx +++ b/app-developers/quickstarts/actions.mdx @@ -410,6 +410,30 @@ const lendPosition = await wallet.lend.getPosition(market); // Fetch wallet balance const balance = await wallet.getBalance(); +// Swap tokens via Uniswap (exact-in) +const swapReceipt = await wallet.swap.execute({ + amountIn: 1, + assetIn: USDC, + assetOut: ETH, + chainId: base.id, +}); + +// Swap tokens via Uniswap (exact-out) +const swapExactOutReceipt = await wallet.swap.execute({ + amountOut: 0.0003, + assetIn: USDC, + assetOut: ETH, + chainId: base.id, +}); + +// Get a price quote before swapping +const quote = await wallet.swap.price({ + assetIn: USDC, + assetOut: ETH, + amountIn: 100, + chainId: base.id, +}); + // ⚠️ COMING SOON const borrowReceipt = await wallet.borrow.openPosition({ amount: 1, @@ -417,13 +441,6 @@ const borrowReceipt = await wallet.borrow.openPosition({ ...market, }); -// ⚠️ COMING SOON -const swapReceipt = await wallet.swap.execute({ - amountIn: 1, - assetIn: USDC, - assetOut: ETH, -}); - // ⚠️ COMING SOON const sendReceipt = await wallet.send({ amount: 1, diff --git a/app-developers/reference/actions/integrating-wallets.mdx b/app-developers/reference/actions/integrating-wallets.mdx index 33b935267..7644a47af 100644 --- a/app-developers/reference/actions/integrating-wallets.mdx +++ b/app-developers/reference/actions/integrating-wallets.mdx @@ -71,10 +71,35 @@ Regardless of where and how transactions are signed, Actions has you covered. ](/app-developers/reference/actions/integrating-wallets#wallet-instance) is now capable of calling Actions [functions](/app-developers/quickstarts/actions#take-action) like Lend, - Borrow, Swap and Pay! + Swap, Borrow, and Pay! + + ```typescript + // Lend tokens + const lendReceipt = await wallet.lend.openPosition({ ... }); + + // Swap tokens via Uniswap or Velodrome/Aerodrome + const swapReceipt = await wallet.swap.execute({ + amountIn: 100, + assetIn: USDC, + assetOut: ETH, + chainId: base.id, + }); + ``` +## Wallet Namespaces + +Once you have an Actions wallet, it exposes DeFi operations through namespaces: + +| Namespace | Description | Reference | +|-----------|-------------|-----------| +| `wallet.lend` | Open, close, and query lending positions via Morpho, Aave, and more | [Lend Documentation](/app-developers/reference/actions/lend-documentation) | +| `wallet.swap` | Swap tokens via Uniswap V4 and Velodrome/Aerodrome | [Swap Documentation](/app-developers/reference/actions/swap-documentation) | +| `wallet.getBalance()` | Get wallet token balances | [Wallet Documentation](/app-developers/reference/actions/wallet-definitions) | +| `wallet.send()` | Send tokens to an address | Coming soon | +| `wallet.borrow` | Open and close borrow positions | Coming soon | + ## Smart wallets & signers In addition to using embedded provider wallets directly, Actions [supports the creation](/app-developers/quickstarts/actions#choose-a-wallet-provider) of custom smart contract wallets. This additional wallet type is separate from, but still controlled by the owner of the embedded wallet. diff --git a/app-developers/reference/actions/swap-documentation.mdx b/app-developers/reference/actions/swap-documentation.mdx new file mode 100644 index 000000000..de1d72f43 --- /dev/null +++ b/app-developers/reference/actions/swap-documentation.mdx @@ -0,0 +1,9 @@ +--- +title: Swap Documentation +description: API reference for Actions SDK swap operations, functions, and parameters. +--- + +import WalletSwapNamespace from "/snippets/actions/wallet-swap-namespace.mdx"; + +{/* This component is generated by script: scripts/generate-actions-components.ts */} + diff --git a/docs.json b/docs.json index c7ac1520b..cdd3bda5b 100644 --- a/docs.json +++ b/docs.json @@ -2204,7 +2204,8 @@ "pages": [ "app-developers/reference/actions/integrating-wallets", "app-developers/reference/actions/wallet-definitions", - "app-developers/reference/actions/lend-documentation" + "app-developers/reference/actions/lend-documentation", + "app-developers/reference/actions/swap-documentation" ] }, { diff --git a/scripts/generate-actions-components.ts b/scripts/generate-actions-components.ts index 45a019692..79313f9f5 100644 --- a/scripts/generate-actions-components.ts +++ b/scripts/generate-actions-components.ts @@ -14,6 +14,7 @@ const ACTIONS_COMPONENTS: Record = { WalletNamespace: "src/wallet/core/namespace/WalletNamespace.ts", Wallet: "src/wallet/core/wallets/abstract/Wallet.ts", WalletLendNamespace: "src/lend/namespaces/WalletLendNamespace.ts", + WalletSwapNamespace: "src/swap/namespaces/WalletSwapNamespace.ts", }; // SDK metadata diff --git a/snippets/actions/wallet-swap-namespace.mdx b/snippets/actions/wallet-swap-namespace.mdx new file mode 100644 index 000000000..73fdab84d --- /dev/null +++ b/snippets/actions/wallet-swap-namespace.mdx @@ -0,0 +1,108 @@ +{/* + ⚠️ WARNING: DO NOT EDIT THIS FILE DIRECTLY ⚠️ + + This file is auto-generated from the Actions SDK source code. + + To update this documentation: + 1. Bump the SDK version in package.json: pnpm add @eth-optimism/actions-sdk@latest + 2. Run the generation script: pnpm prebuild + + Any manual edits will be overwritten on the next generation. +*/} + +## WalletSwapNamespace + +Wallet swap namespace (full operations with signing) + +### Methods + +| Function | Description | +|----------|-------------| +| **[price()](#price)** | Get a price quote for a swap | +| **[getMarket()](#getmarket)** | Get a specific swap market | +| **[getMarkets()](#getmarkets)** | Get available swap markets across all providers | +| **[supportedChainIds()](#supportedchainids)** | Get all supported chain IDs across all providers | +| **[execute()](#execute)** | Execute a token swap | + +#### `price()` + +Get a price quote for a swap + +| Parameter | Type | Description | +|-----------|------|-------------| +| `params` | `SwapPriceParams` | Price quote parameters | +| `params.assetIn` | `Asset` | Token to get price for (required) | +| `params.assetOut` | `Asset` | Token to price against. Defaults to USDC if not provided. | +| `params.amountIn` | `number` | Amount of input token (human-readable). Defaults to 1 unit. For exact-in quotes. | +| `params.amountOut` | `number` | Amount of output token (human-readable). For exact-out quotes. | +| `params.chainId` | `SupportedChainId` | Chain to get price on | + +**Returns:** Promise resolving to `SwapPrice` with exchange rate, amounts, price impact, route, and gas estimate + +[ Source ↗](https://github.com/ethereum-optimism/actions/blob/main/packages/sdk/src/swap/namespaces/BaseSwapNamespace.ts) + +--- + +#### `getMarket()` + +Get a specific swap market + +| Parameter | Type | Description | +|-----------|------|-------------| +| `params` | `GetSwapMarketParams` | Market identifier | +| `params.poolId` | `string` | Pool identifier (keccak256 hash of PoolKey) | +| `params.chainId` | `SupportedChainId` | Chain ID where this market exists | + +**Returns:** Promise resolving to `SwapMarket` information + +[ Source ↗](https://github.com/ethereum-optimism/actions/blob/main/packages/sdk/src/swap/namespaces/BaseSwapNamespace.ts) + +--- + +#### `getMarkets()` + +Get available swap markets across all providers + +| Parameter | Type | Description | +|-----------|------|-------------| +| `params` | `GetSwapMarketsParams` | Optional filtering parameters | +| `params.chainId` | `SupportedChainId` | Filter by chain ID | +| `params.asset` | `Asset` | Filter by asset (returns markets containing this asset) | + +**Returns:** Promise resolving to array of `SwapMarket` from all providers + +[ Source ↗](https://github.com/ethereum-optimism/actions/blob/main/packages/sdk/src/swap/namespaces/BaseSwapNamespace.ts) + +--- + +#### `supportedChainIds()` + +Get all supported chain IDs across all providers + +**Returns:** Array of unique `SupportedChainId` values supported by any configured provider + +[ Source ↗](https://github.com/ethereum-optimism/actions/blob/main/packages/sdk/src/swap/namespaces/BaseSwapNamespace.ts) + +--- + +#### `execute()` + +Execute a token swap + +| Parameter | Type | Description | +|-----------|------|-------------| +| `params` | `WalletSwapParams` | Swap parameters | +| `params.assetIn` | `Asset` | Token to sell | +| `params.assetOut` | `Asset` | Token to buy | +| `params.chainId` | `SupportedChainId` | Chain to execute swap on | +| `params.amountIn` | `number` | Amount of input token (human-readable). For exact-in swaps. Mutually exclusive with `amountOut`. | +| `params.amountOut` | `number` | Amount of output token (human-readable). For exact-out swaps. Mutually exclusive with `amountIn`. | +| `params.slippage` | `number` | Slippage tolerance override (e.g., `0.01` for 1%). Overrides provider and config defaults. | +| `params.deadline` | `number` | Transaction deadline as Unix timestamp. Defaults to now + 1 minute. | +| `params.recipient` | `Address` | Recipient address. Defaults to wallet address. | + +**Returns:** Promise resolving to `SwapReceipt` with transaction receipt, amounts, assets, price, and price impact + +[ Source ↗](https://github.com/ethereum-optimism/actions/blob/main/packages/sdk/src/swap/namespaces/WalletSwapNamespace.ts) + +---