Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 43 additions & 16 deletions docs/base-account/improve-ux/sub-accounts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,32 @@ bun add @base-org/account
```
</CodeGroup>

## Quickstart

The fastest way to adopt Sub Accounts is to set `creation` to `on-connect` and `defaultAccount` to `sub` in the SDK configuration.

```tsx
const sdk = createBaseAccountSDK({
// ...
subAccounts: {
creation: 'on-connect',
defaultAccount: 'sub',
}
});
```

This will automatically create a Sub Account for the user when they connect their Base Account and transactions will automatically be sent from the Sub Account unless you specify the `from` parameter in your transaction request to be the universal account address. Spend Permissions will also be automatically requested for the Sub Account as your app needs them.

This is what the user will see when they connect their Base Account and automatic Sub Accounts are enabled:

<div style={{ display: 'flex', justifyContent: 'center'}}>
<img src="/images/base-account/SubAccountCreationConnect.png" alt="Sub Account Creation Flow" style={{ width: '300px', height: 'auto' }} />
</div>

<Tip>
We recommend using a [Paymaster](/base-account/improve-ux/sponsor-gas/paymasters) to sponsor gas to ensure the best user experience when integrating Sub Accounts. You can set a paymaster to be used for all transactions by configuring the `paymasterUrls` parameter in the SDK configuration. See the [createBaseAccount](/base-account/reference/core/createBaseAccount#param-paymaster-urls) reference for more information.
</Tip>

## Using Sub Accounts

### Initialize the SDK
Expand Down Expand Up @@ -270,22 +296,7 @@ Ensure you do not lose your app's Sub Account signer keys when using the SDK on

Auto Spend Permissions allows Sub Accounts to access funds from their parent Base Account when transaction balances are insufficient. This feature can also establish ongoing spend permissions, enabling future transactions to execute without user approval prompts, reducing friction in your app's transaction flow.

### Configuration

Auto Spend Permissions is only available in SDK version `2.1.0` or later. This feature is **enabled by default** when using Sub Accounts.

To disable Auto Spend Permissions when using Sub Accounts, set `unstable_enableAutoSpendPermissions` to `false` in your SDK configuration:

```tsx
const sdk = createBaseAccountSDK({
appName: 'Base Account SDK Demo',
appLogoUrl: 'https://base.org/logo.png',
appChainIds: [base.id],
subAccounts: {
unstable_enableAutoSpendPermissions: false, // Disable auto spend permissions
}
});
```
This feature is **enabled by default** when using Sub Accounts.

### How it works

Expand All @@ -307,6 +318,22 @@ Spend permission requests are limited to the first token when multiple transfers
</Warning>


### Configuration

If your users' Sub Accounts will be funded manually, you can disable Auto Spend Permissions by setting `funding` to `manual` in your SDK configuration:

```tsx
const sdk = createBaseAccountSDK({
appName: 'Base Account SDK Demo',
appLogoUrl: 'https://base.org/logo.png',
appChainIds: [base.id],
subAccounts: {
funding: 'manual', // Disable auto spend permissions
}
});
```


## Technical Details

Base Account's self-custodial design requires a user passkey prompt for each wallet interaction, such as transactions or message signing. While this ensures user awareness and approval of every wallet interaction, it can impact user experience in applications requiring frequent wallet interactions.
Expand Down
103 changes: 95 additions & 8 deletions docs/base-account/reference/core/createBaseAccount.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,31 @@ Whether to enable functional telemetry. Defaults to `true`.
</Expandable>
</ParamField>

<ParamField body="subAccounts" type="Omit<SubAccountOptions, 'enableAutoSubAccounts'>">
<ParamField body="subAccounts" type="SubAccountOptions">
Sub-account configuration options.

<Expandable title="SubAccountOptions properties">
<ParamField body="creation" type="'on-connect' | 'manual'">
Controls when sub-accounts are created. Defaults to `'manual'`.

- `'on-connect'`: Automatically creates a sub-account when connecting to the wallet (automatically injects `addSubAccount` capability to `wallet_connect`)
- `'manual'`: Requires explicit `wallet_addSubAccount` call to create a sub-account
</ParamField>

<ParamField body="defaultAccount" type="'sub' | 'universal'">
Controls which account is used by default when no account is specified. Defaults to `'universal'`.

- `'sub'`: Sub-account is the default account (first in accounts array)
- `'universal'`: Universal account is the default account (first in accounts array)
</ParamField>

<ParamField body="funding" type="'spend-permissions' | 'manual'">
Controls how sub-accounts are funded. Defaults to `'spend-permissions'`.

- `'spend-permissions'`: Routes through universal account if no spend permissions exist, handles insufficient balance errors automatically. Learn more in [Auto Spend Permissions](/base-account/improve-ux/sub-accounts#auto-spend-permissions)
- `'manual'`: Direct execution from sub-account without automatic fallbacks
</ParamField>

<ParamField body="toOwnerAccount" type="ToOwnerAccountFn">
Function that returns the owner account for signing sub-account transactions.

Expand All @@ -72,9 +93,6 @@ Where `OwnerAccount` is a union type of:
- `WebAuthnAccount` (from viem) - A WebAuthn-based account for passkey authentication
</Expandable>
</ParamField>
<ParamField body="unstable_enableAutoSpendPermissions" type="boolean">
When <code>true</code> (default), enables Auto Spend Permissions for sub-accounts. This allows automatic transfers from the user's Base Account to the sub-account when funds are missing and attempts background transactions using existing spend permissions. Set to <code>false</code> to disable this behavior. Learn more in [Auto Spend Permissions](/base-account/improve-ux/sub-accounts#auto-spend-permissions).
</ParamField>
</Expandable>
</ParamField>

Expand Down Expand Up @@ -147,6 +165,9 @@ const sdk = createBaseAccountSDK({
telemetry: true
},
subAccounts: {
creation: 'on-connect', // Auto-create sub-account on connection
defaultAccount: 'sub', // Use sub-account by default
funding: 'spend-permissions', // Auto-handle funding
toOwnerAccount: async () => ({
account: cryptoAccount?.account || null
})
Expand All @@ -158,13 +179,16 @@ const sdk = createBaseAccountSDK({
});
```

```typescript With Sub-Accounts
```typescript With Sub-Accounts (Manual Creation)
import { createBaseAccountSDK } from '@base-org/account';

const sdk = createBaseAccountSDK({
appName: 'Sub-Account App',
appChainIds: [8453],
subAccounts: {
creation: 'manual', // Explicitly create sub-accounts when needed
defaultAccount: 'universal', // Universal account is default
funding: 'spend-permissions', // Auto-handle insufficient balance
toOwnerAccount: async () => {
// Return the owner account that will sign sub-account transactions
// mainAccount should be a LocalAccount or WebAuthnAccount from viem
Expand All @@ -173,17 +197,38 @@ const sdk = createBaseAccountSDK({
}
});

// Create a sub-account
// Manually create a sub-account when needed
const subAccount = await sdk.subAccount.create({
type: 'create',
keys: [{
type: 'p256',
publicKey: '0x...'
}]
});
```

```typescript With Auto-Created Sub-Accounts
import { createBaseAccountSDK } from '@base-org/account';

const sdk = createBaseAccountSDK({
appName: 'Auto Sub-Account App',
appChainIds: [8453],
subAccounts: {
creation: 'on-connect', // Auto-create on wallet connection
defaultAccount: 'sub', // Sub-account is default
funding: 'spend-permissions', // Auto-handle insufficient balance
toOwnerAccount: async () => {
return { account: mainAccount || null };
}
}
});

// Get existing sub-account
const existingSubAccount = await sdk.subAccount.get();
// Sub-account is automatically created on connection
const provider = sdk.getProvider();
await provider.request({ method: 'eth_requestAccounts' });

// Sub-account is automatically available
const subAccount = await sdk.subAccount.get();
```
</RequestExample>

Expand Down Expand Up @@ -233,6 +278,48 @@ const config = createConfig({

## Configuration Options

### Sub-Account Configuration

Configure sub-account behavior with three independent options:

```typescript
const sdk = createBaseAccountSDK({
appName: 'My App',
appChainIds: [8453],
subAccounts: {
creation: 'on-connect' | 'manual', // When to create
defaultAccount: 'sub' | 'universal', // Which is default
funding: 'spend-permissions' | 'manual', // How to fund transactions
toOwnerAccount: async () => ({ account }) // Owner for signing
}
});
```

**Common Configurations:**

```typescript
// Most seamless UX: Auto-create, use sub-account by default, auto-fund
subAccounts: {
creation: 'on-connect',
defaultAccount: 'sub',
funding: 'spend-permissions'
}

// Manual control: Create when needed, universal default, auto-fund
subAccounts: {
creation: 'manual',
defaultAccount: 'universal',
funding: 'spend-permissions'
}

// Full manual: Complete developer control
subAccounts: {
creation: 'manual',
defaultAccount: 'universal',
funding: 'manual'
}
```

### Attribution

Configure transaction attribution for analytics and tracking:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ interface ProviderInterface {

type CreateProviderOptions = Partial<AppMetadata> & {
preference?: Preference;
subAccounts?: Omit<SubAccountOptions, 'enableAutoSubAccounts'>;
subAccounts?: SubAccountOptions;
paymasterUrls?: Record<number, string>;
};

Expand Down