Skip to content

Commit 23ef8a4

Browse files
authored
Merge branch 'main' into kevin/tree-shakeability
2 parents 7d0079d + 19e0790 commit 23ef8a4

File tree

3 files changed

+414
-0
lines changed

3 files changed

+414
-0
lines changed

AGENTS.md

Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
# Actions SDK Integration Guide
2+
3+
This file is an integration playbook for AI coding agents helping developers add Actions SDK to their application. Actions SDK is an open source TypeScript toolkit by Optimism for integrating DeFi (lending, borrowing, swaps, payments) into apps.
4+
5+
> **For agents**: This guide uses concrete examples but the SDK evolves. When you encounter references to specific providers, assets, or chains, always verify against the actual codebase to discover what is currently supported. Source-of-truth locations are called out in each section.
6+
7+
## Overview
8+
9+
Actions SDK follows a provider pattern. Developers configure:
10+
11+
1. **A wallet provider** — an embedded wallet (Privy, Turnkey, Dynamic, etc.) that handles key management and signing
12+
2. **DeFi action providers** — protocols for lending (Morpho, Aave), borrowing, swaps, etc.
13+
3. **Chains** — which EVM networks to support
14+
4. **Assets** — which tokens to allow or block
15+
16+
Then they call `createActions(config)` to get an `actions` instance, convert a user's wallet into an Actions wallet, and call DeFi operations on it.
17+
18+
## Step 1: Detect Project Environment
19+
20+
Before starting, determine the developer's environment and existing integrations.
21+
22+
**Check the environment** by reading the project's `package.json`:
23+
24+
- If `react`, `next`, `remix`, or similar React framework is in dependencies → **React/frontend** environment. Use `@eth-optimism/actions-sdk/react` imports.
25+
- If it's a Node.js backend (hono, express, fastify, etc.) → **Node/backend** environment. Use `@eth-optimism/actions-sdk/node` imports (or the default import which resolves to node).
26+
- The available wallet providers differ by environment. Check the SDK's `peerDependencies` in `node_modules/@eth-optimism/actions-sdk/package.json` to see which provider packages exist for each environment.
27+
28+
**Check for existing wallet provider integrations** by scanning the project's `package.json` dependencies for:
29+
30+
- `@privy-io/react-auth` or `@privy-io/node` → Privy is already integrated
31+
- `@turnkey/*` packages → Turnkey is already integrated
32+
- `@dynamic-labs/*` packages → Dynamic is already integrated (React only)
33+
34+
If a wallet provider is already present, use it. If not, see Step 3.
35+
36+
## Step 2: Install the SDK
37+
38+
```bash
39+
npm install @eth-optimism/actions-sdk
40+
```
41+
42+
The SDK has peer dependencies for whichever wallet provider the developer chooses. These are optional — only the selected provider's packages need to be installed.
43+
44+
## Step 3: Choose a Wallet Provider
45+
46+
The wallet provider is the biggest integration decision because it involves third-party account setup, authentication flows, and potentially significant frontend/backend work.
47+
48+
**If the developer already has a wallet provider** (detected in Step 1): skip this step and use their existing integration.
49+
50+
**If no wallet provider exists**: Present the available options and help the developer choose, but do not block the rest of the setup. The wallet provider can be integrated in parallel.
51+
52+
> **For agents with interactive UX** (e.g. choice selection): present the wallet provider options as a choice. Otherwise, list them and ask which the developer prefers.
53+
54+
Available wallet providers (verify the current list by checking the SDK's `peerDependencies`):
55+
56+
| Provider | Frontend (React) | Backend (Node) | Setup Guide |
57+
| -------- | :--------------: | :------------: | ---------------------------- |
58+
| Privy | Yes | Yes | https://docs.privy.io |
59+
| Turnkey | Yes | Yes | https://docs.turnkey.com |
60+
| Dynamic | Yes | No | https://www.dynamic.xyz/docs |
61+
62+
Each provider requires its own account setup, API keys, and SDK installation. Direct the developer to the provider's documentation for initial setup, then return here to wire it into Actions.
63+
64+
**Important**: The developer does not need to finish wallet provider setup before continuing. You can scaffold the full Actions config with a placeholder and fill in the wallet section once the provider is ready.
65+
66+
## Step 4: Create the Actions Config File
67+
68+
Create a config file (e.g. `actions.ts`) that centralizes the Actions SDK configuration. This is the main integration point.
69+
70+
### 4a: Wallet Config
71+
72+
The wallet config declares which hosted wallet provider to use and enables smart wallets. Here's an example using Privy on a React frontend:
73+
74+
```typescript
75+
const walletConfig = {
76+
hostedWalletConfig: {
77+
provider: {
78+
type: 'privy' as const,
79+
},
80+
},
81+
smartWalletConfig: {
82+
provider: {
83+
type: 'default' as const,
84+
},
85+
},
86+
}
87+
```
88+
89+
Each provider has different config requirements depending on the environment (React vs Node). For the full setup code for each provider, see the [Integrating Wallets](https://docs.optimism.io/app-developers/reference/actions/integrating-wallets) guide.
90+
91+
> **Source of truth for provider config shapes**: Check the SDK source at `src/wallet/node/providers/hosted/types/` (Node) or `src/wallet/react/providers/hosted/types/` (React) for the exact config each provider expects.
92+
93+
### 4b: DeFi Provider Config (Lend, Borrow, Swap, etc.)
94+
95+
The SDK uses a modular provider pattern for DeFi actions. Each action type (lend, borrow, swap) can have one or more protocol providers. **Configure DeFi providers first** — the market selections will inform which chains and assets need to be configured in the following steps.
96+
97+
> **For agents**: Ask the developer which DeFi actions and providers they want to support. Check `src/lend/` for lending providers and look for other action directories (e.g. `src/borrow/`, `src/swap/`) as the SDK evolves. The `ActionsConfig` type in `src/types/actions.ts` shows all configurable action categories.
98+
99+
#### Morpho
100+
101+
Morpho uses individual vault markets. Ask the developer which Morpho vaults they want to support. The developer may:
102+
103+
- **Provide a vault URL** (e.g. `https://app.morpho.org/unichain/vault/0x38f4...`). Parse the chain name and vault address from the URL to construct the `LendMarketConfig`.
104+
- **Want demo/testnet markets** for development — see `packages/demo/backend/src/config/markets.ts` for examples.
105+
- **Not know yet** — scaffold with an empty allowlist and a TODO comment.
106+
107+
```typescript
108+
// Morpho market — address is the vault address from the Morpho app URL
109+
const MorphoUSDC: LendMarketConfig = {
110+
address: '0x...', // e.g. from https://app.morpho.org/{chain}/vault/{address}
111+
chainId: unichain.id,
112+
name: 'Gauntlet USDC',
113+
asset: USDC,
114+
lendProvider: 'morpho',
115+
}
116+
```
117+
118+
#### Aave
119+
120+
Aave uses a singleton lending pool per chain — there is no per-vault address. Instead, each Aave "market" in the config represents an **underlying asset** you want to support lending for on Aave. The `address` field is the asset's token address on that chain.
121+
122+
> **For agents**: Ask the developer which assets they want to lend via Aave and on which chains. Then construct the `LendMarketConfig` for each, using the asset's token address on that chain. Look up the address from the SDK's built-in asset constants in `src/constants/assets.ts`, or if the asset isn't built-in, look up the token address on the target chain.
123+
124+
```typescript
125+
// Aave market — address is the underlying token address on the target chain
126+
const AaveETH: LendMarketConfig = {
127+
address: '0x4200000000000000000000000000000000000006', // WETH on Optimism
128+
chainId: optimism.id,
129+
name: 'Aave ETH',
130+
asset: ETH,
131+
lendProvider: 'aave',
132+
}
133+
```
134+
135+
#### Bringing it together
136+
137+
```typescript
138+
import type { LendConfig, LendMarketConfig } from '@eth-optimism/actions-sdk'
139+
import { ETH, USDC } from '@eth-optimism/actions-sdk'
140+
import { optimism, unichain } from 'viem/chains'
141+
142+
const lendConfig: LendConfig = {
143+
morpho: {
144+
marketAllowlist: [MorphoUSDC],
145+
},
146+
aave: {
147+
marketAllowlist: [AaveETH],
148+
},
149+
}
150+
```
151+
152+
For more on configuring lend providers, see the [Configuring Actions](https://docs.optimism.io/app-developers/guides/configuring-actions) guide and the [Lend Reference](https://docs.optimism.io/app-developers/reference/actions/lend-documentation).
153+
154+
> **Source of truth**: `src/lend/` for available lending providers. `packages/demo/backend/src/config/markets.ts` for working market examples.
155+
156+
### 4c: Chain Config
157+
158+
> **For agents**: Start by including every chain already referenced by the markets configured in 4b. Then ask the developer if they want to support any additional chains. Check `src/constants/supportedChains.ts` in the SDK for the full list, and present the remaining chains as options. If your tool supports multi-select, use it here.
159+
160+
Each chain needs an RPC URL and optionally a bundler for smart wallet gas sponsorship.
161+
162+
```typescript
163+
import { optimism, base, unichain } from 'viem/chains'
164+
165+
const chains = [
166+
{
167+
chainId: optimism.id,
168+
rpcUrls: [process.env.OPTIMISM_RPC_URL],
169+
bundler: {
170+
type: 'pimlico' as const, // or 'simple'
171+
url: process.env.OPTIMISM_BUNDLER_URL,
172+
},
173+
},
174+
{
175+
chainId: unichain.id,
176+
rpcUrls: [process.env.UNICHAIN_RPC_URL],
177+
bundler: {
178+
type: 'simple' as const,
179+
url: process.env.UNICHAIN_BUNDLER_URL,
180+
},
181+
},
182+
]
183+
```
184+
185+
### 4d: Asset Config
186+
187+
> **For agents**: Start by including every asset already referenced by the markets configured in 4b. Then ask the developer if they want to support any additional tokens. Check `src/constants/assets.ts` for built-in asset constants (ETH, USDC, WETH, etc.) and present remaining options. If the developer needs a token not built into the SDK, help them define a custom `Asset` object — you'll need the token's contract address on each supported chain, decimals, symbol, and name.
188+
189+
```typescript
190+
import { USDC, ETH } from '@eth-optimism/actions-sdk'
191+
192+
const assetsConfig = {
193+
allow: [USDC, ETH], // Only these assets are available in the app
194+
}
195+
```
196+
197+
Custom assets can be defined inline:
198+
199+
```typescript
200+
import type { Asset } from '@eth-optimism/actions-sdk'
201+
import { unichain } from 'viem/chains'
202+
203+
const CUSTOM_TOKEN: Asset = {
204+
address: {
205+
[unichain.id]: '0x...',
206+
},
207+
metadata: {
208+
decimals: 18,
209+
name: 'Custom Token',
210+
symbol: 'CUSTOM',
211+
},
212+
type: 'erc20',
213+
}
214+
```
215+
216+
> **Source of truth**: `src/constants/assets.ts` for built-in assets, `src/supported/tokens.ts` for the `SUPPORTED_TOKENS` list.
217+
218+
### 4e: Initialize Actions
219+
220+
Bring everything together:
221+
222+
```typescript
223+
// React frontend
224+
import { createActions } from '@eth-optimism/actions-sdk/react'
225+
226+
export const actions = createActions({
227+
wallet: walletConfig,
228+
chains,
229+
assets: assetsConfig,
230+
lend: lendConfig,
231+
})
232+
```
233+
234+
```typescript
235+
// Node backend
236+
import { createActions } from '@eth-optimism/actions-sdk/node'
237+
238+
export const actions = createActions({
239+
wallet: walletConfig,
240+
chains,
241+
assets: assetsConfig,
242+
lend: lendConfig,
243+
})
244+
```
245+
246+
In a backend, initialize once at startup and export a singleton. In React, memoize the instance to avoid recreating on every render.
247+
248+
## Step 5: Use Actions
249+
250+
### Convert a wallet to an Actions wallet
251+
252+
Once the developer has a wallet from their provider, convert it to an Actions wallet. Each provider passes different arguments. Example with Privy on React:
253+
254+
```typescript
255+
import { useWallets } from '@privy-io/react-auth'
256+
257+
const { wallets } = useWallets()
258+
const embeddedWallet = wallets.find(
259+
(wallet) => wallet.walletClientType === 'privy',
260+
)
261+
262+
const wallet = await actions.wallet.toActionsWallet({
263+
connectedWallet: embeddedWallet,
264+
})
265+
```
266+
267+
For all provider-specific `toActionsWallet` code, see the [Quickstart](https://docs.optimism.io/app-developers/quickstarts/actions#choose-a-wallet-provider) guide.
268+
269+
### Create a smart wallet (optional)
270+
271+
Smart wallets add ERC-4337 features (gas sponsorship, batch transactions). Create a signer from the provider wallet, then create a smart wallet. Example with Privy on React:
272+
273+
```typescript
274+
const signer = await actions.wallet.createSigner({
275+
connectedWallet: embeddedWallet,
276+
})
277+
278+
const { wallet } = await actions.wallet.createSmartWallet({ signer })
279+
```
280+
281+
For all provider-specific `createSigner` parameters, see the [Integrating Wallets](https://docs.optimism.io/app-developers/reference/actions/integrating-wallets) reference.
282+
283+
### Perform DeFi actions
284+
285+
For the full list of wallet methods and lend operations, see the [Wallet Reference](https://docs.optimism.io/app-developers/reference/actions/wallet-definitions) and [Lend Reference](https://docs.optimism.io/app-developers/reference/actions/lend-documentation).
286+
287+
```typescript
288+
// Get token balances across all configured chains
289+
const balances = await wallet.getBalance()
290+
291+
// Open a lending position
292+
const receipt = await wallet.lend.openPosition({
293+
amount: 100,
294+
asset: USDC,
295+
...market, // { address, chainId } of the market — a LendMarketId
296+
})
297+
298+
// Get current position
299+
const position = await wallet.lend.getPosition(market)
300+
301+
// Close a position (withdraw)
302+
const closeReceipt = await wallet.lend.closePosition({
303+
amount: 50,
304+
asset: USDC,
305+
...market,
306+
})
307+
308+
// Browse available markets
309+
const markets = await actions.lend.getMarkets()
310+
```
311+
312+
> **Source of truth for available actions**: The wallet instance exposes namespaces for each action type. Check which namespaces exist on the `Wallet` and `SmartWallet` classes in `src/wallet/core/wallets/`. The `actions` instance also exposes top-level namespaces for read-only operations (e.g. `actions.lend.getMarkets()`).
313+
314+
## Reference
315+
316+
### Key types
317+
318+
```typescript
319+
import type {
320+
ActionsConfig, // Top-level config
321+
Asset, // Token definition (address per chain + metadata)
322+
TokenBalance, // Balance result (total + per-chain breakdown)
323+
LendConfig, // Lend provider configuration
324+
LendMarketConfig, // Market definition
325+
LendMarketId, // Market identifier ({ address, chainId })
326+
LendMarket, // Market data (name, asset, supply, APY)
327+
LendMarketPosition, // User position in a market
328+
LendTransaction, // Transaction result from lend operations
329+
WalletConfig, // Wallet provider configuration
330+
SupportedChainId, // Union of supported chain IDs
331+
} from '@eth-optimism/actions-sdk'
332+
```
333+
334+
### Key imports
335+
336+
```typescript
337+
// Assets
338+
import { ETH, USDC, WETH } from '@eth-optimism/actions-sdk'
339+
340+
// Utilities
341+
import {
342+
getTokenAddress,
343+
getTokenBySymbol,
344+
SUPPORTED_TOKENS,
345+
} from '@eth-optimism/actions-sdk'
346+
347+
// Wallet classes (for type checking)
348+
import { Wallet, SmartWallet } from '@eth-optimism/actions-sdk'
349+
350+
// Factory (environment-specific)
351+
import { createActions } from '@eth-optimism/actions-sdk/react' // or /node
352+
```
353+
354+
### Documentation
355+
356+
- Quickstart: https://docs.optimism.io/app-developers/quickstarts/actions
357+
- Configuring Actions: https://docs.optimism.io/app-developers/guides/configuring-actions
358+
- Integrating Wallets: https://docs.optimism.io/app-developers/reference/actions/integrating-wallets
359+
- Wallet Reference: https://docs.optimism.io/app-developers/reference/actions/wallet-definitions
360+
- Lend Reference: https://docs.optimism.io/app-developers/reference/actions/lend-documentation
361+
362+
### Example code
363+
364+
The demo applications in this repository show complete working integrations:
365+
366+
- `packages/demo/backend/` — Node.js backend with Privy, Morpho, and Aave
367+
- `packages/demo/frontend/` — React frontend with Privy, Turnkey, and Dynamic

SKILL.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
name: actions-sdk-integration
3+
description: Integrate the Optimism Actions SDK into a TypeScript application. Handles wallet provider setup (Privy, Turnkey, Dynamic), DeFi provider configuration (Morpho, Aave lending), chain and asset selection, and smart wallet creation. Use when the developer wants to add DeFi capabilities like lending, borrowing, swaps, or payments to their app.
4+
---
5+
6+
# Actions SDK Integration
7+
8+
See [AGENTS.md](AGENTS.md) for the full step-by-step integration guide.

0 commit comments

Comments
 (0)