diff --git a/REDIRECTS_GUIDE.md b/REDIRECTS_GUIDE.md
index 1f3a50a40..eb1fb5a58 100644
--- a/REDIRECTS_GUIDE.md
+++ b/REDIRECTS_GUIDE.md
@@ -16,6 +16,7 @@ A comprehensive guide for managing redirects in Mintlify documentation (migrated
## Overview
Redirects are essential when restructuring documentation (IA refactor) to ensure:
+
- Old links don't break
- Search engine rankings are preserved
- User bookmarks continue to work
@@ -67,7 +68,7 @@ Add a new object to the array:
```bash
# Run the dev server
-mintlify dev
+mint dev
# Test the redirect
# Navigate to http://localhost:3000/old-page-path
@@ -150,11 +151,13 @@ mintlify dev
### No Wildcard support
**Nextra** (supported):
+
```
/docs/* /tutorials/:splat 301
```
**Mintlify** (NOT supported):
+
```json
{
"source": "/docs/*",
@@ -167,10 +170,9 @@ mintlify dev
```json
{
"redirects": [
- {"source": "/docs/page1", "destination": "/tutorials/page1"},
- {"source": "/docs/page2", "destination": "/tutorials/page2"},
- {"source": "/docs/page3", "destination": "/tutorials/page3"}
+ { "source": "/docs/page1", "destination": "/tutorials/page1" },
+ { "source": "/docs/page2", "destination": "/tutorials/page2" },
+ { "source": "/docs/page3", "destination": "/tutorials/page3" }
]
}
```
-
diff --git a/app-developers/quickstarts/actions.mdx b/app-developers/quickstarts/actions.mdx
new file mode 100644
index 000000000..4f494dea8
--- /dev/null
+++ b/app-developers/quickstarts/actions.mdx
@@ -0,0 +1,530 @@
+---
+title: Integrating DeFi with Actions SDK
+description: Perform DeFi actions with lightweight, composable, and type-safe modules.
+---
+
+
+ Actions SDK is still under construction and not ready for production use! This guide is meant for early testing purposes only.
+
+
+The [Actions SDK](https://actions.money/) is an open source Typescript development toolkit that simplifies the act of integrating DeFi into your application.
+
+## How it works
+
+Here's a breakdown of what's under the hood:
+
+- **Modular Providers**: Actions is built with a set of core adapters called "Providers". Providers let you to pick an choose the right services and protocols for your use-case.
+
+- **Embedded Wallets**: Actions supports popular embedded [wallet providers](https://actions.money/#wallet), allowing your users to access DeFi with email authentication flows alone.
+
+- **Configure Actions**: Extend your embedded wallet with DeFi actions like Lend, Borrow, Swap, and Pay. Set multiple providers for each Action to choose the best markets across DeFi.
+
+- **Customize assets & chains**: Allow and block assets, markets, chains, and protocols from your application from a single config.
+
+
+## Installation
+
+Install the Actions SDK in your project:
+
+
+```bash npm
+npm install @eth-optimism/actions-sdk
+```
+
+```bash pnpm
+pnpm add @eth-optimism/actions-sdk
+```
+
+```bash yarn
+yarn add @eth-optimism/actions-sdk
+```
+
+```bash bun
+bun add @eth-optimism/actions-sdk
+```
+
+```bash deno
+deno add @eth-optimism/actions-sdk
+```
+
+
+## Choose a Wallet Provider
+
+Actions works with both frontend and backend wallets depending on your needs:
+
+
+
+ Select a wallet provider:
+
+
+
+ Install and setup [Privy](https://docs.privy.io/basics/react/installation).
+
+ **Configure Wallet Provider**
+
+ Give your embedded wallets the ability to take Action:
+
+ ```typescript
+ import { actions } from './config'
+ import { useWallets } from '@privy-io/react-auth'
+
+ // PRIVY: Fetch wallet
+ const { wallets } = useWallets()
+ const embeddedWallet = wallets.find(
+ (wallet) => wallet.walletClientType === 'privy',
+ )
+
+ // ACTIONS: Let wallet make onchain Actions
+ const wallet = await actions.wallet.toActionsWallet({
+ connectedWallet: embeddedWallet,
+ })
+ ```
+
+ **Configure Smart Wallets**
+
+ Optionally, create signers for smart wallets you control:
+
+ ```typescript
+ import { actions } from './config'
+ import { useWallets } from '@privy-io/react-auth'
+
+ // PRIVY: Fetch wallet
+ const { wallets } = useWallets()
+ const embeddedWallet = wallets.find(
+ (wallet) => wallet.walletClientType === 'privy',
+ )
+
+ // ACTIONS: Create signer from hosted wallet
+ const signer = await actions.wallet.createSigner({
+ connectedWallet: embeddedWallet,
+ })
+
+ // ACTIONS: Create smart wallet
+ const { wallet } = await actions.wallet.createSmartWallet({
+ signer: signer
+ })
+ ```
+
+
+
+ Install and setup [Turnkey](https://docs.turnkey.com/sdks/react/getting-started).
+
+ **Configure Wallet Provider**
+
+ Give your embedded wallets the ability to take Action:
+
+ ```typescript
+ import { useTurnkey, WalletSource } from "@turnkey/react-wallet-kit"
+ import { actions, USDC, ExampleMarket } from './config'
+
+ // Fetch Turnkey wallet
+ const { wallets, httpClient, session } = useTurnkey()
+ const embeddedWallet = wallets.find(
+ (wallet) =>
+ wallet.accounts.some(
+ (account) => account.addressFormat === 'ADDRESS_FORMAT_ETHEREUM',
+ ) && wallet.source === WalletSource.Embedded,
+ )
+
+ const walletAddress = embeddedWallet.accounts[0].address
+
+ // Convert to Actions wallet
+ const wallet = await actions.wallet.toActionsWallet({
+ client: httpClient,
+ organizationId: session.organizationId,
+ signWith: walletAddress,
+ })
+
+ // Wallet can now take action
+ const receipt = await wallet.lend.openPosition({
+ amount: 100,
+ asset: USDC,
+ ...ExampleMarket
+ })
+ ```
+
+ **Configure Smart Wallets**
+
+ Optionally, create signers for smart wallets you control:
+
+ ```typescript
+ import { useTurnkey, WalletSource } from "@turnkey/react-wallet-kit"
+ import { actions } from './config'
+
+ // Fetch Turnkey wallet
+ const { wallets, httpClient, session } = useTurnkey()
+ const embeddedWallet = wallets.find(
+ (wallet) =>
+ wallet.accounts.some(
+ (account) => account.addressFormat === 'ADDRESS_FORMAT_ETHEREUM',
+ ) && wallet.source === WalletSource.Embedded,
+ )
+ const walletAddress = embeddedWallet.accounts[0].address
+
+ // Create signer
+ const signer = await actions.wallet.createSigner({
+ client: httpClient,
+ organizationId: session.organizationId,
+ signWith: walletAddress,
+ })
+
+ // Create smart wallet
+ const { wallet } = await actions.wallet.createSmartWallet({
+ signer: signer
+ })
+ ```
+
+
+
+ Install and setup [Dynamic](https://www.dynamic.xyz/docs/wallets/embedded-wallets/mpc/setup).
+
+ **Configure Wallet Provider**
+
+ Give your embedded wallets the ability to take Action:
+
+ ```typescript
+ import { useDynamicContext } from "@dynamic-labs/sdk-react-core"
+ import { actions, USDC, ExampleMarket } from './config'
+
+ // Fetch Dynamic wallet
+ const { primaryWallet } = useDynamicContext()
+
+ // Convert to Actions wallet
+ const wallet = await actions.wallet.toActionsWallet({
+ wallet: primaryWallet,
+ })
+
+ // Wallet can now take action
+ const receipt = await wallet.lend.openPosition({
+ amount: 100,
+ asset: USDC,
+ ...ExampleMarket
+ })
+ ```
+
+ **Configure Smart Wallets**
+
+ Optionally, create signers for smart wallets you control:
+
+ ```typescript
+ import { useDynamicContext } from "@dynamic-labs/sdk-react-core"
+ import { actions } from './config'
+
+ // Fetch Dynamic wallet
+ const { primaryWallet } = useDynamicContext()
+
+ // Create signer
+ const signer = await actions.wallet.createSigner({
+ wallet: primaryWallet
+ })
+
+ // Create smart wallet
+ const { wallet } = await actions.wallet.createSmartWallet({
+ signer: signer
+ })
+ ```
+
+
+
+
+
+ Select a wallet provider:
+
+
+
+ Install and setup [Privy](https://docs.privy.io/basics/nodeJS/installation).
+
+ **Configure Wallet Provider**
+
+ Give your embedded wallets the ability to take Action:
+
+ ```typescript
+ import { actions } from './config'
+ import { PrivyClient } from '@privy-io/node'
+
+ // PRIVY: Create wallet
+ const privyClient = new PrivyClient(env.PRIVY_APP_ID, env.PRIVY_APP_SECRET)
+
+ const privyWallet = await privyClient.wallets().create({
+ chain_type: 'ethereum',
+ owner: { user_id: 'privy:did:xxxxx' },
+ })
+
+ // ACTIONS: Let wallet make onchain Actions
+ const wallet = await actions.wallet.toActionsWallet({
+ walletId: privyWallet.id,
+ address: privyWallet.address,
+ })
+ ```
+
+ **Configure Smart Wallets**
+
+ Optionally, create signers for smart wallets you control:
+
+ ```typescript
+ import { actions } from './config'
+ import { PrivyClient } from '@privy-io/node'
+ import { getAddress } from 'viem'
+
+ const privyClient = new PrivyClient(env.PRIVY_APP_ID, env.PRIVY_APP_SECRET)
+
+ // PRIVY: Create wallet
+ const privyWallet = await privyClient.wallets().create({
+ chain_type: 'ethereum',
+ owner: { user_id: 'privy:did:xxxxx' },
+ })
+
+ // ACTIONS: Create signer
+ const signer = await actions.wallet.createSigner({
+ walletId: privyWallet.id,
+ address: getAddress(privyWallet.address),
+ })
+
+ // ACTIONS: Create smart wallet
+ const { wallet } = await actions.wallet.createSmartWallet({
+ signer: signer
+ })
+ ```
+
+
+
+ Install and setup [Turnkey](https://docs.turnkey.com/sdks/javascript-server).
+
+ **Configure Wallet Provider**
+
+ Give your embedded wallets the ability to take Action:
+
+ ```typescript
+ import { Turnkey } from '@turnkey/sdk-server'
+ import { actions, USDC, ExampleMarket } from './config'
+
+ const turnkeyClient = new Turnkey({
+ apiBaseUrl: 'https://api.turnkey.com',
+ apiPublicKey: process.env.TURNKEY_API_KEY,
+ apiPrivateKey: process.env.TURNKEY_API_SECRET,
+ defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
+ })
+
+ // Create Turnkey wallet
+ const turnkeyWallet = await turnkeyClient.apiClient().createWallet({
+ walletName: 'ETH Wallet',
+ accounts: [{
+ curve: 'CURVE_SECP256K1',
+ pathFormat: 'PATH_FORMAT_BIP32',
+ path: "m/44'/60'/0'/0/0",
+ addressFormat: 'ADDRESS_FORMAT_ETHEREUM',
+ }],
+ })
+
+ // Convert to Actions wallet
+ const wallet = await actions.wallet.toActionsWallet({
+ organizationId: turnkeyWallet.activity.organizationId,
+ signWith: turnkeyWallet.addresses[0],
+ })
+
+ // Wallet can now take action
+ const receipt = await wallet.lend.openPosition({
+ amount: 100,
+ asset: USDC,
+ ...ExampleMarket
+ })
+ ```
+
+ **Configure Smart Wallets**
+
+ Optionally, create signers for smart wallets you control:
+
+ ```typescript
+ import { Turnkey } from '@turnkey/sdk-server'
+ import { actions } from './config'
+
+ const turnkeyClient = new Turnkey({
+ apiBaseUrl: 'https://api.turnkey.com',
+ apiPublicKey: process.env.TURNKEY_API_KEY,
+ apiPrivateKey: process.env.TURNKEY_API_SECRET,
+ defaultOrganizationId: process.env.TURNKEY_ORGANIZATION_ID,
+ })
+
+ // Create Turnkey wallet
+ const turnkeyWallet = await turnkeyClient.apiClient().createWallet({
+ walletName: 'ETH Wallet',
+ accounts: [{
+ curve: 'CURVE_SECP256K1',
+ pathFormat: 'PATH_FORMAT_BIP32',
+ path: "m/44'/60'/0'/0/0",
+ addressFormat: 'ADDRESS_FORMAT_ETHEREUM',
+ }],
+ })
+
+ // Create signer
+ const signer = await actions.wallet.createSigner({
+ organizationId: turnkeyWallet.activity.organizationId,
+ signWith: turnkeyWallet.addresses[0],
+ })
+
+ // Create smart wallet
+ const { wallet } = await actions.wallet.createSmartWallet({
+ signer: signer
+ })
+ ```
+
+
+
+
+
+## Create your ActionsConfig
+
+Create your Actions configuration to define which protocols, chains, and assets to support.
+
+Configure a wallet provider:
+
+```typescript
+import type { WalletConfig } from '@eth-optimism/actions-sdk'
+
+const walletConfig: WalletConfig = {
+ hostedWalletConfig: {
+ provider: {
+ type: 'privy', // your provider chosen in previous step
+ },
+ },
+ smartWalletConfig: {
+ provider: {
+ type: 'default',
+ attributionSuffix: 'actions',
+ },
+ },
+}
+```
+
+Configure a lend provider with `LendConfig`:
+
+```typescript
+import type { LendConfig } from '@eth-optimism/actions-sdk'
+import { USDC, ETH, WBTC } from '@eth-optimism/actions-sdk/assets'
+import { USDCMorphoMarket } from './actions/markets'
+
+const lendConfig: LendConfig = {
+ type: 'morpho',
+ assetAllowlist: [USDC, ETH, WBTC],
+ assetBlocklist: [],
+ marketAllowlist: [USDCMorphoMarket],
+ marketBlocklist: [],
+}
+```
+
+Configure a borrow provider with `BorrowConfig`:
+
+```typescript
+import type { BorrowConfig } from '@eth-optimism/actions-sdk'
+import { USDC, ETH, WBTC } from '@eth-optimism/actions-sdk/assets'
+import { USDCMorphoMarket } from './actions/markets'
+
+const borrowConfig: BorrowConfig = {
+ type: 'morpho',
+ assetAllowlist: [USDC, ETH, WBTC],
+ assetBlocklist: [],
+ marketAllowlist: [USDCMorphoMarket],
+ marketBlocklist: [],
+}
+```
+
+Configure a swap provider with `SwapConfig`:
+
+```typescript
+import type { SwapConfig } from '@eth-optimism/actions-sdk'
+import { USDC, ETH, WBTC } from '@eth-optimism/actions-sdk/assets'
+
+const swapConfig: SwapConfig = {
+ type: 'uniswap',
+ defaultSlippage: 100, // 100 bips or 1%
+ assetAllowList: [USDC, ETH, WBTC],
+ assetBlocklist: [],
+}
+```
+
+Configure supported chains:
+
+```typescript
+import { optimism, base } from 'viem/chains'
+
+// Define any EVM chain
+const OPTIMISM = {
+ chainId: optimism.id,
+ rpcUrls: env.OPTIMISM_RPC_URL,
+ bundler: { // Bundle and sponsor txs with a gas paymaster
+ type: 'simple' as const,
+ url: env.OPTIMISM_BUNDLER_URL,
+ },
+}
+
+const BASE = {
+ chainId: base.id,
+ rpcUrls: env.BASE_RPC_URL,
+ bundler: { // Bundle and sponsor txs with a gas paymaster
+ type: 'simple' as const,
+ url: env.BASE_BUNDLER_URL,
+ },
+}
+
+const chains = [OPTIMISM, BASE]
+```
+
+Finally, bring it all together and initialize Actions:
+
+```typescript
+export const actions = createActions({
+ wallet: walletConfig,
+ lend: lendConfig,
+ borrow: borrowConfig,
+ swap: swapConfig,
+ chains,
+})
+```
+
+## Using Actions
+
+Once configured, you can use Actions to perform DeFi operations:
+
+```typescript
+import { USDC, ETH, USDT } from '@eth-optimism/actions-sdk/assets'
+import { ExampleMarket } from '@/actions/markets'
+
+// Enable asset lending in DeFi
+const lendReceipt = await wallet.lend.openPosition({
+ amount: 1,
+ asset: USDC,
+ ...ExampleMarket
+})
+
+// Manage user market positions
+const lendPosition = await wallet.lend.getPosition(market)
+
+// Fetch wallet balance
+const balance = await wallet.getBalance()
+
+// ⚠️ COMING SOON
+const borrowReceipt = await wallet.borrow.openPosition({
+ amount: 1,
+ asset: USDT,
+ ...market
+})
+
+// ⚠️ COMING SOON
+const swapReceipt = await wallet.swap.execute({
+ amountIn: 1,
+ assetIn: USDC,
+ assetOut: ETH,
+})
+
+// ⚠️ COMING SOON
+const sendReceipt = await wallet.send({
+ amount: 1,
+ asset: USDC,
+ to: 'vitalik.eth',
+})
+```
+
+## Next Steps
+
+- Check out the [Actions demo](https://actions.money/earn) for a complete example application
+- Join the [Optimism Discord](https://discord.optimism.io) for support and updates
diff --git a/docs.json b/docs.json
index d0e483f18..af751602d 100644
--- a/docs.json
+++ b/docs.json
@@ -1646,7 +1646,8 @@
{
"group": "Quickstarts",
"pages": [
- "app-developers/quickstarts/starter-kit"
+ "app-developers/quickstarts/starter-kit",
+ "app-developers/quickstarts/actions"
]
},
{
diff --git a/package.json b/package.json
index 80852de65..d743c47e2 100644
--- a/package.json
+++ b/package.json
@@ -4,8 +4,8 @@
"description": "Optimism Documentation",
"main": "index.js",
"scripts": {
- "dev": "mintlify dev",
- "build": "mintlify build"
+ "dev": "mint dev",
+ "build": "mint build"
},
"dependencies": {
"toml": "^3.0.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 000000000..bae195950
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,115 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ react:
+ specifier: ^18.0.0
+ version: 18.2.0
+ react-dom:
+ specifier: ^18.0.0
+ version: 18.2.0(react@18.2.0)
+ toml:
+ specifier: ^3.0.0
+ version: 3.0.0
+ devDependencies:
+ '@types/react':
+ specifier: ^18.0.0
+ version: 18.2.36
+ '@types/react-dom':
+ specifier: ^18.0.0
+ version: 18.2.16
+ typescript:
+ specifier: ^5.0.0
+ version: 5.3.2
+
+packages:
+
+ '@types/prop-types@15.7.9':
+ resolution: {integrity: sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g==}
+
+ '@types/react-dom@18.2.16':
+ resolution: {integrity: sha512-766c37araZ9vxtYs25gvY2wNdFWsT2ZiUvOd0zMhTaoGj6B911N8CKQWgXXJoPMLF3J82thpRqQA7Rf3rBwyJw==}
+
+ '@types/react@18.2.36':
+ resolution: {integrity: sha512-o9XFsHYLLZ4+sb9CWUYwHqFVoG61SesydF353vFMMsQziiyRu8np4n2OYMUSDZ8XuImxDr9c5tR7gidlH29Vnw==}
+
+ '@types/scheduler@0.16.5':
+ resolution: {integrity: sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw==}
+
+ csstype@3.1.2:
+ resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
+
+ js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ loose-envify@1.4.0:
+ resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
+ hasBin: true
+
+ react-dom@18.2.0:
+ resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==}
+ peerDependencies:
+ react: ^18.2.0
+
+ react@18.2.0:
+ resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
+ engines: {node: '>=0.10.0'}
+
+ scheduler@0.23.0:
+ resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==}
+
+ toml@3.0.0:
+ resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==}
+
+ typescript@5.3.2:
+ resolution: {integrity: sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+snapshots:
+
+ '@types/prop-types@15.7.9': {}
+
+ '@types/react-dom@18.2.16':
+ dependencies:
+ '@types/react': 18.2.36
+
+ '@types/react@18.2.36':
+ dependencies:
+ '@types/prop-types': 15.7.9
+ '@types/scheduler': 0.16.5
+ csstype: 3.1.2
+
+ '@types/scheduler@0.16.5': {}
+
+ csstype@3.1.2: {}
+
+ js-tokens@4.0.0: {}
+
+ loose-envify@1.4.0:
+ dependencies:
+ js-tokens: 4.0.0
+
+ react-dom@18.2.0(react@18.2.0):
+ dependencies:
+ loose-envify: 1.4.0
+ react: 18.2.0
+ scheduler: 0.23.0
+
+ react@18.2.0:
+ dependencies:
+ loose-envify: 1.4.0
+
+ scheduler@0.23.0:
+ dependencies:
+ loose-envify: 1.4.0
+
+ toml@3.0.0: {}
+
+ typescript@5.3.2: {}