diff --git a/src/app/connect/pay/faqs/page.mdx b/src/app/connect/pay/faqs/page.mdx
index ac1e8b0e..ee2bbbae 100644
--- a/src/app/connect/pay/faqs/page.mdx
+++ b/src/app/connect/pay/faqs/page.mdx
@@ -71,13 +71,15 @@ We offer direct onramping **internationally** to the following tokens:
We offer direct onramping to the following tokens in the **US only**:
+- ETH (Base)\*
- USDC (Ethereum)
- USDC (Polygon)\*
- USDC (Avalanche)\*
+- USDC (Base)\*
All other tokens will require an additional Buy With Crypto step.
-\* USDC (Polygon) and USDC (Avalanche) are not available in New York.
+\* Not available in New York or the EU.
### How does KYC work with Buy With Fiat
diff --git a/src/app/connect/sidebar.tsx b/src/app/connect/sidebar.tsx
index a55cb50e..8c6655bc 100644
--- a/src/app/connect/sidebar.tsx
+++ b/src/app/connect/sidebar.tsx
@@ -191,7 +191,7 @@ export const sidebar: SideBar = {
{
name: "React Native",
// TODO - add react-native dedicated page
- href: "/react/v5",
+ href: "/react/v5/in-app-wallet/get-started",
icon: ,
},
{
@@ -293,15 +293,34 @@ export const sidebar: SideBar = {
},
{
name: "Get Started",
- href: `${aAslug}/get-started`,
- },
- {
- name: "Permissions & Session Keys",
- href: `${aAslug}/permissions`,
- },
- {
- name: "Batching Transactions",
- href: `${aAslug}/batching-transactions`,
+ links: [
+ {
+ name: "TypeScript",
+ href: "/typescript/v5/account-abstraction/get-started",
+ icon: ,
+ },
+ {
+ name: "React",
+ href: "/react/v5/account-abstraction/get-started",
+ icon: ,
+ },
+ {
+ name: "React Native",
+ // TODO - add react-native dedicated page
+ href: "/react/v5/account-abstraction/get-started",
+ icon: ,
+ },
+ {
+ name: "Dotnet",
+ href: "/dotnet/wallets/providers/account-abstraction",
+ icon: ,
+ },
+ {
+ name: "Unity",
+ href: "/unity/wallets/providers/account-abstraction",
+ icon: ,
+ },
+ ],
},
{
name: "Account Factories",
@@ -315,25 +334,9 @@ export const sidebar: SideBar = {
name: "Sponsorship rules",
href: `${aAslug}/sponsorship-rules`,
},
- {
- name: "Guides",
- isCollapsible: true,
- expanded: true,
- links: [
- {
- name: "Usage in React",
- href: `${aAslug}/guides/react`,
- },
- {
- name: "Usage in Typescript",
- href: `${aAslug}/guides/typescript`,
- },
- ],
- },
{
name: "Gasless",
isCollapsible: true,
- expanded: true,
links: [
{
name: "Engine",
diff --git a/src/app/react-native/v5/sidebar.tsx b/src/app/react-native/v5/sidebar.tsx
index ba87dca5..37a2c845 100644
--- a/src/app/react-native/v5/sidebar.tsx
+++ b/src/app/react-native/v5/sidebar.tsx
@@ -109,6 +109,26 @@ export const sidebar: SideBar = {
icon: ,
})) || [],
},
+ {
+ name: "In-App Wallets",
+ links: [
+ {
+ name: "React API",
+ href: "/react/v5/in-app-wallet/get-started",
+ icon: ,
+ },
+ ],
+ },
+ {
+ name: "Account Abstraction",
+ links: [
+ {
+ name: "React API",
+ href: "/react/v5/account-abstraction/get-started",
+ icon: ,
+ },
+ ],
+ },
{
name: "Supported Wallets",
href: "/typescript/v5/supported-wallets",
diff --git a/src/app/react/v5/account-abstraction/batching-transactions/page.mdx b/src/app/react/v5/account-abstraction/batching-transactions/page.mdx
new file mode 100644
index 00000000..4fd93397
--- /dev/null
+++ b/src/app/react/v5/account-abstraction/batching-transactions/page.mdx
@@ -0,0 +1,42 @@
+import { createMetadata } from "@doc";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
+
+# Batching transactions
+
+export const metadata = createMetadata({
+ image: {
+ title: "Batching transactions",
+ icon: "wallets",
+ },
+ title: "Batching transactions | thirdweb",
+ description: "How to batch transactions with smart accounts",
+});
+
+Batching transactions allows sending multiple transactions in a single user operation. This can be useful to save on fees, reduce number of user confimations or to ensure that multiple transactions are executed atomically.
+
+A typical example is to do an approval and a transfer in a single userOperation. This way, the transfer will only happen if the approval is successful.
+
+```tsx
+import { useActiveAccount, useSendBatchTransaction } from "thirdweb/react";
+import { approve, transferFrom } from "thirdweb/extensions/erc20";
+
+const smartAccount = useActiveAccount();
+const { mutate: sendBatchTransaction } = useSendBatchTransaction();
+
+const approveAndTransfer = async () => {
+ const transactions = [
+ approve({
+ contract,
+ spender: "0x...",
+ value: 100,
+ }),
+ transferFrom({
+ contract,
+ from: "0x...",
+ to: "0x...",
+ amount: 100,
+ }),
+ ];
+ await sendBatchTransaction(transactions);
+};
+```
\ No newline at end of file
diff --git a/src/app/react/v5/account-abstraction/build-your-own-ui/page.mdx b/src/app/react/v5/account-abstraction/build-your-own-ui/page.mdx
new file mode 100644
index 00000000..4b7b33fc
--- /dev/null
+++ b/src/app/react/v5/account-abstraction/build-your-own-ui/page.mdx
@@ -0,0 +1,139 @@
+import {
+ Grid,
+ Callout,
+ OpenSourceCard,
+ ArticleIconCard,
+ createMetadata,
+ Steps,
+ Step,
+} from "@doc";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
+import { WalletsSmartIcon } from "@/icons";
+
+export const metadata = createMetadata({
+ image: {
+ title: "Build a custom UI for connecting smart accounts",
+ icon: "wallets",
+ },
+ title: "Build a custom UI for smart accounts | thirdweb",
+ description:
+ "You have full control with the connection hooks and functions to build your own UI",
+});
+
+# Build your own UI
+
+You can also use the connection hooks and functions to connect to your smart accounts and build your fully custom UI.
+
+
+
+
+You will require an API key to use thirdweb's infrastructure services such as the bundler and paymaster.
+
+Obtain an API key from the [thirdweb dashboard Settings page](https://thirdweb.com/create-api-key).
+
+The API key lets you access thirdweb's bundler and paymaster infrastructure, which is required for smart accounts to operate and optionally enable [gasless transactions](/glossary/gasless-transactions).
+
+Learn more about creating an API key and restricting which contracts the smart account can interact with [here](/api-keys).
+
+
+
+
+Using `useConnect`, you can pass the `accountAbstraction` prop to automatically convert any connected wallet to a smart account.
+
+The connected wallet will be the admin wallet of the smart account.
+
+
+
+To set up sponsored transactions, set the `sponsorGas` option to `true` in the smart account configuration.
+All transactions performed with the smart account will then be sponsored by your application. Testnet transactions are free, but you need a valid credit card on file for mainnet transactions.
+
+
+
+```tsx
+import { useConnect } from "thirdweb/react";
+import { inAppWallet } from "thirdweb/wallets";
+import { sepolia } from "thirdweb/chains";
+
+function App() {
+ // 1. set the `accountAbstraction` configuration
+ const { connect } = useConnect({
+ client,
+ accountAbstraction: {
+ chain: sepolia, // the chain where your smart accounts will be or is deployed
+ sponsorGas: true, // enable or disable sponsored transactions
+ },
+ });
+
+ const connectToSmartAccount = async () => {
+ // 2. connect with the admin wallet of the smart account
+ connect(async () => {
+ const wallet = inAppWallet(); // or any other wallet
+ await wallet.connect({
+ client,
+ chain: sepolia,
+ strategy: "google",
+ });
+ return wallet;
+ });
+ };
+
+ return ;
+}
+```
+
+
+
+
+Once setup, you can use the Connect [TypeScript](/typescript/v5), [React](/react/v5), or [React Native](/react-native/v5) SDKs to deploy contracts, perform transactions, and manipulate smart accounts like any other wallet.
+
+```tsx
+import { getContract } from "thirdweb";
+import { useActiveAccount, useSendTransaction } from "thirdweb/react";
+import { claimTo, balanceOf } from "thirdweb/extensions/erc721";
+
+const contract = getContract({ client, chain, address: "0x..." });
+
+// The ThirdwebProvider setup above already handles the connection to the smart account
+// Within the provider, you can use the SDK normally to interact with the blockchain
+export default function MyComponent() {
+ // Get the connected smart account
+ const smartAccount = useActiveAccount();
+ // Example read
+ const { data, isLoading } = useReadContract(
+ balanceOf,
+ {
+ contract,
+ owner: smartAccount.address,
+ },
+ {
+ enabled: !!smartAccount,
+ },
+ );
+ // Example write
+ const { mutate: sendTransaction, isPending } = useSendTransaction();
+ const mint = () => {
+ sendTransaction({
+ transaction: claimTo({
+ contract,
+ to: smartAccount.address,
+ quantity: 1n,
+ }),
+ });
+ };
+ // Mint a new NFT
+ return ;
+}
+```
+
+
+
+
+### Demos
+
+Learn by example with these open-source demos:
+
+
diff --git a/src/app/react/v5/account-abstraction/get-started/page.mdx b/src/app/react/v5/account-abstraction/get-started/page.mdx
new file mode 100644
index 00000000..2a1539bc
--- /dev/null
+++ b/src/app/react/v5/account-abstraction/get-started/page.mdx
@@ -0,0 +1,132 @@
+import {
+ Grid,
+ Callout,
+ OpenSourceCard,
+ ArticleIconCard,
+ createMetadata,
+ Steps,
+ Step,
+} from "@doc";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
+import { WalletsSmartIcon } from "@/icons";
+
+export const metadata = createMetadata({
+ image: {
+ title: "Get started with Account Abstraction",
+ icon: "wallets",
+ },
+ title: "Getting Started with Account Abstraction | thirdweb",
+ description:
+ "Getting started to add ERC-4337 Account Abstraction support to your application easily.",
+});
+
+# Getting Started
+
+Getting started to add ERC-4337 compatible smart accounts to your application easily.
+
+Once set, your application will:
+
+- Let users **connect to their smart account** using any personal wallet, including in-app wallets for easy onboarding.
+- Automatically **deploy individual account contracts** for your users when they do their first onchain transaction.
+- **Handle all transaction gas costs** via the thirdweb paymaster.
+
+
+
+
+You will require an API key to use thirdweb's infrastructure services such as the bundler and paymaster.
+
+Obtain an API key from the [thirdweb dashboard Settings page](https://thirdweb.com/create-api-key).
+
+The API key lets you access thirdweb's bundler and paymaster infrastructure, which is required for smart accounts to operate and optionally enable [gasless transactions](/glossary/gasless-transactions).
+
+Learn more about creating an API key and restricting which contracts the smart account can interact with [here](/api-keys).
+
+
+
+
+The easiest way to get started with account abstraction is to use the [ConnectButton](/connect/sign-in/ConnectButton) component. Simply add the `accountAbstraction` property with the desired chain and whether to sponsor gas for your users.
+
+With this property, all connected wallets will be automatically converted to smart accounts. The connected wallet will be the admin wallet of the smart account.
+
+
+
+To set up sponsored transactions, set the `sponsorGas` option to `true` in the smart account configuration.
+All transactions performed with the smart account will then be sponsored by your application. Testnet transactions are free, but you need a valid credit card on file for mainnet transactions.
+
+
+
+```tsx
+import { createThirdwebClient } from "thirdweb";
+import { ThirdwebProvider, ConnectButton } from "thirdweb/react";
+
+const client = createThirdwebClient({
+clientId: "YOUR_CLIENT_ID",
+});
+
+export default function App() {
+return (
+
+
+
+ );
+}
+```
+
+
+
+Once setup, you can use the rest of the Connect [React SDK](/react/latest) to deploy contracts, perform transactions, and manipulate smart accounts like any other wallet.
+
+```tsx
+import { getContract } from "thirdweb";
+import { useActiveAccount, TransactionButton } from "thirdweb/react";
+import { claimTo } from "thirdweb/extensions/erc721";
+
+const contract = getContract({ client, chain, address: "0x..." });
+
+// The ThirdwebProvider setup above already handles the connection to the smart account
+// Within the provider, you can use the SDK normally to interact with the blockchain
+export default function MyComponent() {
+ // Get the connected smart account
+ const smartAccount = useActiveAccount();
+ // Mint a new NFT
+ return (
+ {
+ if (!account) return;
+ return claimTo({
+ contract,
+ to: account.address,
+ quantity: 1n,
+ });
+ }}
+ >
+ Mint NFT
+
+ );
+}
+```
+
+
+
+
+### Build your own UI
+
+You can also use the connection hooks and functions to connect to your smart accounts and build your fully custom UI.
+
+See the [Build your own UI](/react/v5/account-abstraction/build-your-own-ui) guide for more information.
+
+### Demos
+
+Learn by example with these open-source demos:
+
+
diff --git a/src/app/react/v5/account-abstraction/permissions/page.mdx b/src/app/react/v5/account-abstraction/permissions/page.mdx
new file mode 100644
index 00000000..3c8144e4
--- /dev/null
+++ b/src/app/react/v5/account-abstraction/permissions/page.mdx
@@ -0,0 +1,93 @@
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
+import { createMetadata } from "@doc";
+import { V4SDKbanner } from "@/components/others/V4SDKBanner";
+
+export const metadata = createMetadata({
+ image: {
+ title: "Account Permissions & Session Keys",
+ icon: "thirdweb",
+ },
+ title: "Account Permissions & Session Keys | thirdweb",
+ description:
+ "All of the account contracts - Simple and Managed - share the same permission model. In this section, we'll describe this permission model in detail",
+});
+
+# Account Permissions & Session Keys
+
+All of the account contracts - [Simple](https://thirdweb.com/thirdweb.eth/AccountFactory) and [Managed](https://thirdweb.com/thirdweb.eth/ManagedAccountFactory) - share the same permission model. In this section, we'll describe this permission model in detail.
+
+An account recognizes only two types of actors: _Session Keys_ and _Admins_.
+
+## 1. Admins
+
+Admins have **unrestricted access** to the account; call any functions on the contract, use the contract without going through the ERC-4337 infrastructure (bundlers, EntryPoint, etc.), withdraw the account's native token balance, and so on.
+
+### Assigning Admin Permissions
+
+Existing admins on the account can add new admins, remove existing admins or renounce their own admin status.
+
+```tsx
+import { addAdmin } from "thirdweb/extensions/erc4337";
+import { useSendTransaction, useActiveAccount } from "thirdweb/react";
+import { getContract } from "thirdweb";
+
+const { mutate: sendTransaction } = useSendTransaction();
+const smartAccount = useActiveAccount();
+
+const onClick = () => {
+ if (!smartAccount) return;
+ const transaction = addAdmin({
+ contract: getContract({
+ address: smartAccount.address,
+ chain,
+ client,
+ }),
+ account: smartAccount,
+ adminAddress: "0x...", // the address of the new admin
+ });
+ sendTransaction(transaction);
+};
+```
+
+## 2. Session Keys
+
+Session Keys are additional authorized signers that must go through ERC-4337 infrastructure (bundlers, EntryPoint, etc.) to use an account to execute transactions. Session keys can use an account under certain restrictions.
+
+### Assigning Session Key Permissions
+
+Each individual session key has its own permissions to use the account. Only admins can set the permissions for session keys.
+
+Session keys can be assigned the following permissions:
+
+- [Required] Allow interaction with specific contracts with the account ("*" for any contracts)
+- [Optional] Have a maximum amount of native tokens that can be transferred per transaction (defaults to 0 eth, transactions with value will be rejected)
+- [Optional] Have access to the account only during a specific time window (defaults to 10 years from now)
+
+```tsx
+import { addSessionKey } from "thirdweb/extensions/erc4337";
+import { useSendTransaction, useActiveAccount } from "thirdweb/react";
+import { getContract } from "thirdweb";
+
+const { mutate: sendTransaction } = useSendTransaction();
+const smartAccount = useActiveAccount();
+
+const onClick = () => {
+ if (!smartAccount) return;
+ const transaction = addSessionKey({
+ contract: getContract({
+ address: smartAccount.address,
+ chain,
+ client,
+ }),
+ account: smartAccount,
+ sessionKeyAddress: "0x...", // the address of the new session key
+ permissions: {
+ approvedTargets: "*", // the addresses of allowed contracts, or '*' for any contract
+ nativeTokenLimitPerTransaction: 0.1, // the maximum amount of native token (in ETH) that the session key can spend per transaction
+ permissionStartTimestamp: new Date(), // the date when the session key becomes active
+ permissionEndTimestamp: new Date(Date.now() + 24 * 60 * 60 * 1000), // the date when the session key expires
+ },
+ });
+ sendTransaction(transaction);
+};
+```
diff --git a/src/app/react/v5/in-app-wallet/enable-gasless/page.mdx b/src/app/react/v5/in-app-wallet/enable-gasless/page.mdx
index ee0914bc..e7142825 100644
--- a/src/app/react/v5/in-app-wallet/enable-gasless/page.mdx
+++ b/src/app/react/v5/in-app-wallet/enable-gasless/page.mdx
@@ -32,10 +32,11 @@ To enable account abstraction in your app, you need to add the `smartAccount` pr
```jsx
import { ConnectButton } from "thirdweb/react";
import { inAppWallet } from "thirdweb/wallets";
+import { sepolia } from "thirdweb/chains";
const wallets = [inAppWallet({
smartAccount: {
- chain: "sepolia",
+ chain: sepolia,
sponsorGas: true,
},
})];
diff --git a/src/app/react/v5/migrate/use-v5-with-ethers/page.mdx b/src/app/react/v5/migrate/use-v5-with-ethers/page.mdx
new file mode 100644
index 00000000..1a1aebed
--- /dev/null
+++ b/src/app/react/v5/migrate/use-v5-with-ethers/page.mdx
@@ -0,0 +1 @@
+# WIP
\ No newline at end of file
diff --git a/src/app/react/v5/sidebar.tsx b/src/app/react/v5/sidebar.tsx
index b4523fe2..fe2a97bb 100644
--- a/src/app/react/v5/sidebar.tsx
+++ b/src/app/react/v5/sidebar.tsx
@@ -161,6 +161,36 @@ export const sidebar: SideBar = {
})),
],
},
+ {
+ name: "Account Abstraction",
+ links: [
+ {
+ name: "Get Started",
+ href: `${slug}/account-abstraction/get-started`,
+ icon: ,
+ },
+ {
+ name: "Build your own UI",
+ href: `${slug}/account-abstraction/build-your-own-ui`,
+ icon: ,
+ },
+ {
+ name: "Admins & Session Keys",
+ href: `${slug}/account-abstraction/permissions`,
+ icon: ,
+ },
+ {
+ name: "Batching Transactions",
+ href: `${slug}/account-abstraction/batching-transactions`,
+ icon: ,
+ },
+ {
+ name: "Core API",
+ href: "/typescript/v5/smartWallet",
+ icon: ,
+ },
+ ],
+ },
{
name: "All Supported Wallets",
href: "/typescript/v5/supported-wallets",
diff --git a/src/app/typescript/v5/account-abstraction/batching-transactions/page.mdx b/src/app/typescript/v5/account-abstraction/batching-transactions/page.mdx
new file mode 100644
index 00000000..ab431947
--- /dev/null
+++ b/src/app/typescript/v5/account-abstraction/batching-transactions/page.mdx
@@ -0,0 +1,48 @@
+import { createMetadata } from "@doc";
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
+
+# Batching transactions
+
+export const metadata = createMetadata({
+ image: {
+ title: "Batching transactions",
+ icon: "wallets",
+ },
+ title: "Batching transactions | thirdweb",
+ description: "How to batch transactions with smart accounts",
+});
+
+Batching transactions allows sending multiple transactions in a single user operation. This can be useful to save on fees, reduce number of user confimations or to ensure that multiple transactions are executed atomically.
+
+A typical example is to do an approval and a transfer in a single userOperation. This way, the transfer will only happen if the approval is successful.
+
+```tsx
+import { smartWallet } from "thirdweb/wallets";
+import { sendBatchTransaction } from "thirdweb";
+import { approve, transferFrom } from "thirdweb/extensions/erc20";
+
+const smartWallet = new smartWallet(config);
+const smartAccount = await smartWallet.connect({
+ client,
+ personalAccount,
+});
+
+const transactions = [
+ approve({
+ contract,
+ spender: "0x...",
+ value: 100,
+ }),
+ transferFrom({
+ contract,
+ from: "0x...",
+ to: "0x...",
+ amount: 100,
+ }),
+];
+
+await sendBatchTransaction({
+ transactions,
+ account: smartAccount,
+});
+```
diff --git a/src/app/typescript/v5/account-abstraction/get-started/page.mdx b/src/app/typescript/v5/account-abstraction/get-started/page.mdx
new file mode 100644
index 00000000..41afb613
--- /dev/null
+++ b/src/app/typescript/v5/account-abstraction/get-started/page.mdx
@@ -0,0 +1,162 @@
+import { Grid, OpenSourceCard, ArticleIconCard, Steps, Step } from "@doc";
+import { WalletsSmartIcon } from "@/icons";
+import { createMetadata } from "@doc";
+
+export const metadata = createMetadata({
+ image: {
+ title: "Get Started with Account Abstraction",
+ icon: "typescript",
+ },
+ title: "Using Account Abstraction in Typescript | thirdweb",
+ description:
+ "By using the wallet SDK alongside the TypeScript SDK, you can use smart accounts in your applications easily",
+});
+
+# Using Account abstraction in Typescript
+
+By using the [wallet SDK](/references/wallets/latest) alongside the [TypeScript SDK](/typescript/latest), you can use smart accounts in your applications easily.
+
+## Example Use Cases
+
+The wallet SDK with the TypeScript SDK is primarily used when creating a backend for your application or when creating a node script.
+In this guide, we will be using the wallet SDK to create a Node script but the logic for creating a backend is the same.
+
+If you are working in a React environment, you are recommended to follow [this guide](/connect/account-abstraction/guides/react).
+
+
+
+
+To use the bundler and paymaster, you must create an API key and a billing account.
+
+To create an API Key:
+
+- Head to the settings page in the dashboard and click the **API Keys** tab.
+- Click on **Create API Key**.
+- Follow the steps to create your API key.
+
+To use account abstraction infrastructure on mainnet you will also need to [create an account and add a payment method](https://thirdweb.com/dashboard/settings/billing).
+
+
+
+
+To use smart accounts in a node script, simply create a new Node.js project and install the `thirdweb` package.
+
+```bash
+npm i thirdweb
+```
+
+Create a `.env` file and add the following:
+
+```bash
+THIRDWEB_SECRET_KEY=
+PRIVATE_KEY=
+```
+
+Create an `index.ts` file where we'll write our script.
+
+
+
+
+This smart account is unlocked by a 'key' - a personal wallet.
+This key can be anything from a MetaMask wallet or an In-App Wallet or just a private key and is used as a way to 'sign in' to the smart account.
+
+To create a personal wallet key, we are going to use the [`privateKeyAccount`](/references/typescript/v5/privateKeyAccount), which we need to import from the `thirdweb/wallets` package.
+
+```typescript
+import { createThirdwebClient } from "thirdweb";
+import { privateKeyAccount } from "thirdweb/wallets";
+
+const client = createThirdwebClient({
+ secretKey: process.env.THIRDWEB_SECRET_KEY as string,
+});
+
+const personalAccount = privateKeyAccount({
+ client,
+ privateKey: process.env.PRIVATE_KEY as string,
+});
+console.log("Personal account address:", personalAccount.address);
+```
+
+
+
+
+Now, let's create a smart account using the SmartWallet class from the `@thirdweb-dev/wallets` package.
+To do this, we need to pass a `SmartWalletConfig` object to the constructor. This object contains the following properties:
+
+- `chain`: the chain that the smart account will be deployed on.
+- `sponsorGas`: whether the smart account should have sponsored transactions or not.
+
+Once we have created the config and instantiated the `SmartWallet` class, we can connect the personal wallet to the smart account using the `connect` method.
+
+```typescript
+// Configure the smart wallet
+const wallet = smartWallet({
+ chain: sepolia,
+ sponsorGas: true,
+});
+
+// Connect the smart wallet
+const smartAccount = await wallet.connect({
+ client,
+ personalAccount,
+});
+```
+
+
+
+
+Now that we have created a smart account object and connected it, we can use it to perform onchain actions gaslessly.
+
+In this example, we will claim a NFT using the `claimTo` method and then send the transaction using the `sendTransaction` method.
+
+```typescript
+const balance = await getWalletBalance({
+ client,
+ chain,
+ address: smartAccount.address,
+});
+console.log("Smart account balance:", balance.displayValue);
+
+const contract = getContract({
+ client,
+ chain: sepolia,
+ address: "0x...", // deploy a drop contract from thirdweb.com/explore
+});
+
+const transaction = await claimTo({
+ contract,
+ to: smartAccount.address,
+ quantity: 1,
+});
+const { transactionHash } = await sendTransaction({
+ transaction,
+ smartAccount,
+});
+console.log(`Minted NFT with transaction hash: ${transactionHash}`);
+```
+
+We have also passed our `secretKey` to the SDK so that we can use the bundler and paymaster.
+
+We have also added some helpful logs to view the smart account address and balance using the associated `balance` and `getAddress` methods.
+
+
+
+
+To run the script, run the following command:
+
+```bash
+bun index.ts
+```
+
+As you can see in the terminal output, upon claiming the token, the smart account is deployed. This is because smart account contracts are deployed when the first transaction is initiated.
+
+We have successfully deployed a smart account and claimed an ERC20 token!
+
+
+
+
+In this guide, we have learned how to use the wallet SDK with the TypeScript SDK to
+create a smart account and claim an NFT.
+
+
+
diff --git a/src/app/typescript/v5/account-abstraction/permissions/page.mdx b/src/app/typescript/v5/account-abstraction/permissions/page.mdx
new file mode 100644
index 00000000..3e684c65
--- /dev/null
+++ b/src/app/typescript/v5/account-abstraction/permissions/page.mdx
@@ -0,0 +1,100 @@
+import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
+import { createMetadata } from "@doc";
+import { V4SDKbanner } from "@/components/others/V4SDKBanner";
+
+export const metadata = createMetadata({
+ image: {
+ title: "Account Permissions & Session Keys",
+ icon: "thirdweb",
+ },
+ title: "Account Permissions & Session Keys | thirdweb",
+ description:
+ "All of the account contracts - Simple and Managed - share the same permission model. In this section, we'll describe this permission model in detail",
+});
+
+# Account Permissions & Session Keys
+
+All of the account contracts - [Simple](https://thirdweb.com/thirdweb.eth/AccountFactory) and [Managed](https://thirdweb.com/thirdweb.eth/ManagedAccountFactory) - share the same permission model. In this section, we'll describe this permission model in detail.
+
+An account recognizes only two types of actors: _Session Keys_ and _Admins_.
+
+## 1. Admins
+
+Admins have **unrestricted access** to the account; call any functions on the contract, use the contract without going through the ERC-4337 infrastructure (bundlers, EntryPoint, etc.), withdraw the account's native token balance, and so on.
+
+### Assigning Admin Permissions
+
+Existing admins on the account can add new admins, remove existing admins or renounce their own admin status.
+
+
+```typescript
+import { addAdmin } from "thirdweb/extensions/erc4337";
+import { smartWallet } from "thirdweb/wallets";
+import { sendTransaction, getContract } from "thirdweb";
+
+const smartWallet = new smartWallet(config);
+const smartAccount = await smartWallet.connect({
+ client,
+ personalAccount,
+});
+
+const transaction = addAdmin({
+ contract: getContract({
+ address: smartAccount.address,
+ chain,
+ client,
+ }),
+ account: smartAccount,
+ adminAddress: "0x...", // the address of the new admin
+});
+await sendTransaction({
+ transaction,
+ account: smartAccount,
+});
+```
+
+## 2. Session Keys
+
+Session Keys are additional authorized signers that must go through ERC-4337 infrastructure (bundlers, EntryPoint, etc.) to use an account to execute transactions. Session keys can use an account under certain restrictions.
+
+### Assigning Session Key Permissions
+
+Each individual session key has its own permissions to use the account. Only admins can set the permissions for session keys.
+
+Session keys can be assigned the following permissions:
+
+- [Required] Allow interaction with specific contracts with the account ("*" for any contracts)
+- [Optional] Have a maximum amount of native tokens that can be transferred per transaction (defaults to 0 eth, transactions with value will be rejected)
+- [Optional] Have access to the account only during a specific time window (defaults to 10 years from now)
+
+```ts
+import { addAdmin } from "thirdweb/extensions/erc4337";
+import { smartWallet } from "thirdweb/wallets";
+import { sendTransaction, getContract } from "thirdweb";
+
+const smartWallet = new smartWallet(config);
+const smartAccount = await smartWallet.connect({
+ client,
+ personalAccount,
+});
+
+const transaction = addSessionKey({
+ contract: getContract({
+ address: smartAccount.address,
+ chain,
+ client,
+ }),
+ account: smartAccount,
+ sessionKeyAddress: "0x...", // the address of the new session key
+ permissions: {
+ approvedTargets: "*", // the addresses of allowed contracts, or '*' for any contract
+ nativeTokenLimitPerTransaction: 0.1, // the maximum amount of native token (in ETH) that the session key can spend per transaction
+ permissionStartTimestamp: new Date(), // the date when the session key becomes active
+ permissionEndTimestamp: new Date(Date.now() + 24 * 60 * 60 * 1000), // the date when the session key expires
+ },
+});
+await sendTransaction({
+ transaction,
+ account: smartAccount,
+});
+```
diff --git a/src/app/typescript/v5/sidebar.tsx b/src/app/typescript/v5/sidebar.tsx
index 372c243b..016f8a0c 100644
--- a/src/app/typescript/v5/sidebar.tsx
+++ b/src/app/typescript/v5/sidebar.tsx
@@ -119,23 +119,46 @@ export const sidebar: SideBar = {
{
name: "Account Abstraction",
links: [
- "smartWallet",
- "addAdmin",
- "removeAdmin",
- "addSessionKey",
- "removeSessionKey",
- "getAccountsOfSigner",
- "getAllActiveSigners",
- "getPermissionsForSigner",
- "createUnsignedUserOp",
- "signUserOp",
- "bundleUserOp",
- "waitForUserOpReceipt",
- ].map((name) => ({
- name,
- href: `${slug}/${name}`,
- icon: ,
- })),
+ {
+ name: "Getting Started",
+ href: `${slug}/account-abstraction/get-started`,
+ icon: ,
+ },
+ {
+ name: "Admins & Session Keys",
+ href: `${slug}/account-abstraction/permissions`,
+ icon: ,
+ },
+ {
+ name: "Batching Transactions",
+ href: `${slug}/account-abstraction/batching-transactions`,
+ icon: ,
+ },
+ ...[
+ "smartWallet",
+ "signUserOp",
+ "bundleUserOp",
+ "waitForUserOpReceipt",
+ ].map((name) => ({
+ name,
+ href: `${slug}/${name}`,
+ icon: ,
+ })),
+ ...[
+ "addAdmin",
+ "removeAdmin",
+ "addSessionKey",
+ "removeSessionKey",
+ "getAccountsOfSigner",
+ "getAllActiveSigners",
+ "getPermissionsForSigner",
+ "createUnsignedUserOp",
+ ].map((name) => ({
+ name,
+ href: `${slug}/erc4337/${name}`,
+ icon: ,
+ })),
+ ],
},
{
name: "Auth (SIWE)",