> ## Documentation Index
> Fetch the complete documentation index at: https://base-a060aa97-fix-dead-service-links.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# createBaseAccountSDK

> Create a Base Account SDK instance with EIP-1193 compliant provider

export const Button = ({children, disabled, variant = "primary", size = "medium", iconName, roundedFull = false, className = '', fullWidth = false, onClick = undefined}) => {
  const variantStyles = {
    primary: 'bg-blue text-black border border-blue hover:bg-blue-80 active:bg-[#06318E] dark:text-white',
    secondary: 'bg-white border border-white text-palette-foreground hover:bg-zinc-15 active:bg-zinc-30',
    outlined: 'bg-transparent text-white border border-white hover:bg-white hover:text-black active:bg-[#E3E7E9]'
  };
  const sizeStyles = {
    medium: 'text-md px-4 py-2 gap-3',
    large: 'text-lg px-6 py-4 gap-5'
  };
  const sizeIconRatio = {
    medium: '0.75rem',
    large: '1rem'
  };
  const classes = ['text-md px-4 py-2 whitespace-nowrap', 'flex items-center justify-center', 'disabled:opacity-40 disabled:pointer-events-none', 'transition-all', variantStyles[variant], sizeStyles[size], roundedFull ? 'rounded-full' : 'rounded-lg', fullWidth ? 'w-full' : 'w-auto', className];
  const buttonClasses = classes.filter(Boolean).join(' ');
  const iconSize = sizeIconRatio[size];
  return <button type="button" disabled={disabled} className={buttonClasses} onClick={onClick}>
      <span>{children}</span>
      {iconName && <Icon name={iconName} width={iconSize} height={iconSize} color="currentColor" />}
    </button>;
};

export const BaseBanner = ({content = null, id, dismissable = true}) => {
  const LOCAL_STORAGE_KEY_PREFIX = 'cb-docs-banner';
  const [isVisible, setIsVisible] = useState(false);
  const onDismiss = () => {
    localStorage.setItem(`${LOCAL_STORAGE_KEY_PREFIX}-${id}`, 'false');
    setIsVisible(false);
  };
  useEffect(() => {
    const storedValue = localStorage.getItem(`${LOCAL_STORAGE_KEY_PREFIX}-${id}`);
    setIsVisible(storedValue !== 'false');
  }, []);
  if (!isVisible) {
    return null;
  }
  return <div className="fixed bottom-0 left-0 right-0 bg-white py-8 px-4 lg:px-12 z-50 text-black dark:bg-black dark:text-white border-t dark:border-gray-95">
      <div className="flex items-center max-w-8xl mx-auto">
        {typeof content === 'function' ? content({
    onDismiss
  }) : content}
        {dismissable && <button onClick={onDismiss} className="flex-shrink-0 text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors" aria-label="Dismiss banner">
          ✕
        </button>}
      </div>
    </div>;
};

Defined in the [Base Account SDK](https://github.com/base/account-sdk)

<Info>
  Creates a Base Account SDK instance that provides an EIP-1193 compliant Ethereum provider and additional account management functionality. This is the primary entry point for integrating Base Account into your application.
</Info>

## Parameters

<ParamField body="params" type="CreateProviderOptions" required>
  Configuration options for creating the SDK instance.

  <Expandable title="CreateProviderOptions properties">
    <ParamField body="appName" type="string">
      The name of your application. Defaults to "App" if not provided.
    </ParamField>

    <ParamField body="appLogoUrl" type="string">
      URL to your application's logo image. Used in wallet UI. Defaults to empty string if not provided.
    </ParamField>

    <ParamField body="appChainIds" type="number[]">
      Array of chain IDs that your application supports. Defaults to empty array if not provided.
    </ParamField>

    <ParamField body="preference" type="Preference">
      Optional preferences for SDK behavior.

      <Expandable title="Preference properties">
        <ParamField body="walletUrl" type="string">
          Custom wallet URL override. Only use when overriding the default wallet URL with a custom environment.
        </ParamField>

        <ParamField body="attribution" type="Attribution">
          Attribution configuration for Smart Wallet transactions.

          <Expandable title="Attribution properties">
            <ParamField body="auto" type="boolean">
              When true, Smart Wallet will generate a 16 byte hex string from the app's origin.
            </ParamField>

            <ParamField body="dataSuffix" type="`0x${string}`">
              Custom 16 byte hex string appended to initCode and executeBatch calldata. Cannot be used with `auto: true`.
            </ParamField>
          </Expandable>
        </ParamField>

        <ParamField body="telemetry" type="boolean">
          Whether to enable functional telemetry. Defaults to `true`.
        </ParamField>
      </Expandable>
    </ParamField>

    <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.

          <Expandable title="ToOwnerAccountFn signature">
            ```typescript theme={null}
            type ToOwnerAccountFn = () => Promise<{ account: OwnerAccount | null; }>
            ```

            Where `OwnerAccount` is a union type of:

            * `LocalAccount` (from viem) - A local account with private key
            * `WebAuthnAccount` (from viem) - A WebAuthn-based account for passkey authentication
          </Expandable>
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="paymasterUrls" type="Record<number, string>">
      Mapping of chain IDs to paymaster URLs for gasless transactions.
    </ParamField>
  </Expandable>
</ParamField>

## Returns

<ResponseField name="sdk" type="BaseAccountSDK">
  SDK instance with provider and sub-account management capabilities.

  <Expandable title="BaseAccountSDK properties">
    <ResponseField name="getProvider" type="() => ProviderInterface">
      Returns an EIP-1193 compliant Ethereum provider that can be used with web3 libraries like Viem, Wagmi, and Web3.js.
    </ResponseField>

    <ResponseField name="subAccount" type="SubAccountManager">
      Sub-account management methods.

      <Expandable title="SubAccountManager properties">
        <ResponseField name="create" type="(account: AddSubAccountAccount) => Promise<SubAccount>">
          Creates a new sub-account.
        </ResponseField>

        <ResponseField name="get" type="() => Promise<SubAccount | null>">
          Retrieves the current sub-account information.
        </ResponseField>

        <ResponseField name="addOwner" type="(params: AddOwnerParams) => Promise<string>">
          Adds an owner to the sub-account.
        </ResponseField>

        <ResponseField name="setToOwnerAccount" type="(fn: ToOwnerAccountFn) => void">
          Sets the function for determining the owner account. The function should return a Promise resolving to an object with an `account` property that is either a `LocalAccount`, `WebAuthnAccount`, or `null`.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```typescript Basic Setup theme={null}
  import { createBaseAccountSDK } from '@base-org/account';
  import { base } from 'viem/chains';

  const sdk = createBaseAccountSDK({
    appName: 'My DApp',
    appLogoUrl: 'https://mydapp.com/logo.png',
    appChainIds: [base.id],
  });

  const provider = sdk.getProvider();
  ```

  ```typescript Advanced Configuration theme={null}
  import { createBaseAccountSDK } from '@base-org/account';
  import { base, baseSepolia } from 'viem/chains';

  const sdk = createBaseAccountSDK({
    appName: 'My Advanced DApp',
    appLogoUrl: 'https://mydapp.com/logo.png',
    appChainIds: [base.id, baseSepolia.id],
    preference: {
      attribution: {
        auto: true
      },
      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 
      })
    },
    paymasterUrls: {
      [base.id]: 'https://paymaster.base.org',
      [baseSepolia.id]: 'https://paymaster.base-sepolia.org'
    }
  });
  ```

  ```typescript With Sub-Accounts (Manual Creation) theme={null}
  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
        return { account: mainAccount || null };
      }
    }
  });

  // 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 theme={null}
  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 };
      }
    }
  });

  // 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>

## Integration Examples

### With Viem

```typescript theme={null}
import { createWalletClient, custom } from 'viem';
import { base } from 'viem/chains';
import { createBaseAccountSDK } from '@base-org/account';

const sdk = createBaseAccountSDK({
  appName: 'Viem Integration',
  appChainIds: [base.id]
});

const provider = sdk.getProvider();

const client = createWalletClient({
  chain: base,
  transport: custom(provider)
});
```

### With Wagmi

```typescript theme={null}
import { createConfig, custom } from 'wagmi';
import { base } from 'wagmi/chains';
import { createBaseAccountSDK } from '@base-org/account';

const sdk = createBaseAccountSDK({
  appName: 'Wagmi Integration',
  appChainIds: [base.id]
});

const provider = sdk.getProvider();

const config = createConfig({
  chains: [base],
  transports: {
    [base.id]: custom(provider),
  },
});
```

## Configuration Options

### Sub-Account Configuration

Configure sub-account behavior with three independent options:

```typescript theme={null}
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 theme={null}
// 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:

```typescript theme={null}
// Auto-generate attribution from app origin
const sdk = createBaseAccountSDK({
  appName: 'My App',
  preference: {
    attribution: { auto: true }
  }
});

// Custom attribution data
const sdk = createBaseAccountSDK({
  appName: 'My App',
  preference: {
    attribution: { dataSuffix: '0x1234567890123456789012345678901234567890' }
  }
});
```

### Paymaster Integration

Enable gasless transactions with paymaster URLs:

```typescript theme={null}
const sdk = createBaseAccountSDK({
  appName: 'Gasless App',
  appChainIds: [8453, 84532],
  paymasterUrls: {
    8453: 'https://paymaster.base.org/api/v1/sponsor',
    84532: 'https://paymaster.base-sepolia.org/api/v1/sponsor'
  }
});
```

## Error Handling

The SDK initialization is synchronous and will validate preferences during creation:

```typescript theme={null}
try {
  const sdk = createBaseAccountSDK({
    appName: 'My App',
    appChainIds: [8453],
    subAccounts: {
      toOwnerAccount: invalidFunction // Will throw validation error
    }
  });
} catch (error) {
  console.error('SDK initialization failed:', error);
}
```

## TypeScript Support

The SDK is fully typed for TypeScript development:

```typescript theme={null}
import type { 
  CreateProviderOptions, 
  BaseAccountSDK,
  ProviderInterface,
  ToOwnerAccountFn 
} from '@base-org/account';
import { LocalAccount } from 'viem';

const toOwnerAccount: ToOwnerAccountFn = async () => {
  // Your logic to get the owner account
  const ownerAccount: LocalAccount | null = getOwnerAccount();
  return { account: ownerAccount };
};

const options: CreateProviderOptions = {
  appName: 'Typed App',
  appChainIds: [8453],
  subAccounts: {
    toOwnerAccount
  }
};

const sdk: BaseAccountSDK = createBaseAccountSDK(options);
const provider: ProviderInterface = sdk.getProvider();
```

<Warning>
  The SDK automatically manages Cross-Origin-Opener-Policy validation and telemetry initialization. Make sure your application's headers allow popup windows if using the default wallet interface.
</Warning>

<Info>
  The `createBaseAccountSDK` function is the primary entry point for Base Account integration. It provides both a standard EIP-1193 provider and advanced features like sub-account management and gasless transactions.
</Info>

<BaseBanner
  id="privacy-policy"
  dismissable={false}
  content={({ onDismiss }) => (
<div className="flex items-center">
  <div className="mr-2">
    We're updating the Base Privacy Policy, effective July 25, 2025, to reflect an expansion of Base services. Please review the updated policy here:{" "}
    <a
      href="https://docs.base.org/privacy-policy-2025"
      target="_blank"
      className="whitespace-nowrap"
    >
      Base Privacy Policy
    </a>. By continuing to use Base services, you confirm that you have read and understand the updated policy.
  </div>
  <Button onClick={onDismiss}>I Acknowledge</Button>
</div>
)}
/>
