From abe55a3f312d6f5b18db64f096d3de461a68633c Mon Sep 17 00:00:00 2001 From: Stephan Cilliers Date: Tue, 7 Oct 2025 17:03:52 +0200 Subject: [PATCH 1/2] feat: sub accounts quickstart --- docs/base-account/improve-ux/sub-accounts.mdx | 59 ++++++++++++++----- 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/docs/base-account/improve-ux/sub-accounts.mdx b/docs/base-account/improve-ux/sub-accounts.mdx index cc2de9c8..7c50b6b0 100644 --- a/docs/base-account/improve-ux/sub-accounts.mdx +++ b/docs/base-account/improve-ux/sub-accounts.mdx @@ -51,6 +51,32 @@ bun add @base-org/account ``` +## 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: + +
+ Sub Account Creation Flow +
+ + +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. + + ## Using Sub Accounts ### Initialize the SDK @@ -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 @@ -307,6 +318,22 @@ Spend permission requests are limited to the first token when multiple transfers +### 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. From cd21a4c24c3d4bea8a85eeb16abc43f6987aea56 Mon Sep 17 00:00:00 2001 From: Stephan Cilliers Date: Tue, 7 Oct 2025 17:08:48 +0200 Subject: [PATCH 2/2] feat: new sub account config --- .../reference/core/createBaseAccount.mdx | 103 ++++++++++++++++-- .../provider-rpc-methods/request-overview.mdx | 2 +- 2 files changed, 96 insertions(+), 9 deletions(-) diff --git a/docs/base-account/reference/core/createBaseAccount.mdx b/docs/base-account/reference/core/createBaseAccount.mdx index 4aa2c86d..1a80c8a9 100644 --- a/docs/base-account/reference/core/createBaseAccount.mdx +++ b/docs/base-account/reference/core/createBaseAccount.mdx @@ -55,10 +55,31 @@ Whether to enable functional telemetry. Defaults to `true`. - + Sub-account configuration options. + +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 + + + +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) + + + +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 + + Function that returns the owner account for signing sub-account transactions. @@ -72,9 +93,6 @@ Where `OwnerAccount` is a union type of: - `WebAuthnAccount` (from viem) - A WebAuthn-based account for passkey authentication - -When true (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 false to disable this behavior. Learn more in [Auto Spend Permissions](/base-account/improve-ux/sub-accounts#auto-spend-permissions). - @@ -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 }) @@ -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 @@ -173,7 +197,7 @@ const sdk = createBaseAccountSDK({ } }); -// Create a sub-account +// Manually create a sub-account when needed const subAccount = await sdk.subAccount.create({ type: 'create', keys: [{ @@ -181,9 +205,30 @@ const subAccount = await sdk.subAccount.create({ 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(); ``` @@ -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: diff --git a/docs/base-account/reference/core/provider-rpc-methods/request-overview.mdx b/docs/base-account/reference/core/provider-rpc-methods/request-overview.mdx index 0c572228..01263f22 100644 --- a/docs/base-account/reference/core/provider-rpc-methods/request-overview.mdx +++ b/docs/base-account/reference/core/provider-rpc-methods/request-overview.mdx @@ -32,7 +32,7 @@ interface ProviderInterface { type CreateProviderOptions = Partial & { preference?: Preference; - subAccounts?: Omit; + subAccounts?: SubAccountOptions; paymasterUrls?: Record; };