Skip to content

Commit 3dd2a13

Browse files
authored
Merge pull request #67 from base/add-auto-sub-accounts
Add auto sub accounts demo
2 parents a152cd6 + a1783ca commit 3dd2a13

File tree

8 files changed

+3124
-0
lines changed

8 files changed

+3124
-0
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Sub Accounts Example
2+
3+
A simple Next.js app demonstrating Base Account SDK Sub Accounts integration with automatic sub account creation and USDC transfers on Base Sepolia.
4+
5+
## Features
6+
7+
- **Automatic Sub Account Creation**: Sub account is created automatically when users connect their wallet
8+
- **USDC Transfer**: Send USDC to a specified address on Base Sepolia
9+
- **Auto Spend Permissions**: Sub accounts can access Universal Account balance when needed
10+
- **Modern UI**: Clean and responsive interface
11+
12+
## Getting Started
13+
14+
### Prerequisites
15+
16+
- Node.js 18+ installed
17+
- A Base Account (create one at [account.base.app](https://account.base.app))
18+
- USDC on Base Sepolia testnet
19+
20+
### Installation
21+
22+
1. Install dependencies:
23+
24+
```bash
25+
npm install
26+
```
27+
28+
2. Run the development server:
29+
30+
```bash
31+
npm run dev
32+
```
33+
34+
3. Open [http://localhost:3000](http://localhost:3000) in your browser
35+
36+
## How It Works
37+
38+
This app uses the **quickstart configuration** from the Base Account SDK:
39+
40+
```tsx
41+
const sdk = createBaseAccountSDK({
42+
subAccounts: {
43+
creation: 'on-connect', // Auto-create sub account on connect
44+
defaultAccount: 'sub', // Use sub account for transactions by default
45+
}
46+
});
47+
```
48+
49+
### Key Benefits
50+
51+
- **No repeated prompts**: Transactions are sent from the sub account without repeated approval
52+
- **Seamless funding**: Auto Spend Permissions allow the sub account to access Universal Account balance
53+
- **Better UX**: Perfect for apps requiring frequent transactions
54+
55+
## Usage
56+
57+
1. **Connect Wallet**: Click "Connect Wallet" and approve the connection in your Base Account
58+
2. **Sub Account Created**: A sub account is automatically created for this app
59+
3. **Send USDC**: Enter an amount and click "Send USDC" to transfer to the recipient address
60+
61+
## Configuration
62+
63+
### Recipient Address
64+
65+
The USDC recipient address is set in `app/page.tsx`:
66+
67+
```tsx
68+
const RECIPIENT_ADDRESS = "0xd8da6bf26964af9d7eed9e03e53415d37aa96045";
69+
```
70+
71+
### USDC Contract
72+
73+
The app uses the USDC contract on Base Sepolia:
74+
75+
```tsx
76+
const USDC_ADDRESS = "0x036CbD53842c5426634e7929541eC2318f3dCF7e";
77+
```
78+
79+
## Learn More
80+
81+
- [Base Account Documentation](https://docs.base.org/base-account)
82+
- [Sub Accounts Guide](https://docs.base.org/base-account/improve-ux/sub-accounts)
83+
- [Base Account SDK](https://github.com/base/account-sdk)
84+
85+
## License
86+
87+
MIT
88+
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
* {
2+
box-sizing: border-box;
3+
padding: 0;
4+
margin: 0;
5+
}
6+
7+
html,
8+
body {
9+
max-width: 100vw;
10+
overflow-x: hidden;
11+
}
12+
13+
body {
14+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
15+
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
16+
sans-serif;
17+
-webkit-font-smoothing: antialiased;
18+
-moz-osx-font-smoothing: grayscale;
19+
background: linear-gradient(to bottom, #0052ff 0%, #001a66 100%);
20+
min-height: 100vh;
21+
color: white;
22+
}
23+
24+
.container {
25+
max-width: 800px;
26+
margin: 0 auto;
27+
padding: 40px 20px;
28+
}
29+
30+
.card {
31+
background: rgba(255, 255, 255, 0.1);
32+
backdrop-filter: blur(10px);
33+
border-radius: 16px;
34+
padding: 32px;
35+
margin-bottom: 24px;
36+
border: 1px solid rgba(255, 255, 255, 0.2);
37+
}
38+
39+
.title {
40+
font-size: 2.5rem;
41+
font-weight: bold;
42+
margin-bottom: 8px;
43+
text-align: center;
44+
}
45+
46+
.subtitle {
47+
font-size: 1.1rem;
48+
opacity: 0.9;
49+
text-align: center;
50+
margin-bottom: 32px;
51+
}
52+
53+
.section-title {
54+
font-size: 1.5rem;
55+
font-weight: 600;
56+
margin-bottom: 16px;
57+
}
58+
59+
.info-row {
60+
display: flex;
61+
flex-direction: column;
62+
gap: 8px;
63+
margin-bottom: 16px;
64+
padding: 16px;
65+
background: rgba(0, 0, 0, 0.2);
66+
border-radius: 8px;
67+
}
68+
69+
.info-label {
70+
font-size: 0.875rem;
71+
opacity: 0.8;
72+
font-weight: 500;
73+
}
74+
75+
.info-value {
76+
font-family: 'Monaco', 'Courier New', monospace;
77+
font-size: 0.9rem;
78+
word-break: break-all;
79+
}
80+
81+
.button {
82+
background: white;
83+
color: #0052ff;
84+
border: none;
85+
padding: 14px 28px;
86+
border-radius: 8px;
87+
font-size: 16px;
88+
font-weight: 600;
89+
cursor: pointer;
90+
transition: all 0.2s;
91+
width: 100%;
92+
margin-bottom: 12px;
93+
}
94+
95+
.button:hover:not(:disabled) {
96+
transform: translateY(-2px);
97+
box-shadow: 0 4px 12px rgba(255, 255, 255, 0.3);
98+
}
99+
100+
.button:disabled {
101+
opacity: 0.5;
102+
cursor: not-allowed;
103+
}
104+
105+
.button-secondary {
106+
background: transparent;
107+
color: white;
108+
border: 2px solid white;
109+
}
110+
111+
.button-secondary:hover:not(:disabled) {
112+
background: rgba(255, 255, 255, 0.1);
113+
}
114+
115+
.status-message {
116+
padding: 12px 16px;
117+
background: rgba(0, 0, 0, 0.3);
118+
border-radius: 8px;
119+
margin-bottom: 16px;
120+
font-size: 0.9rem;
121+
}
122+
123+
.button-group {
124+
display: flex;
125+
flex-direction: column;
126+
gap: 12px;
127+
}
128+
129+
.input-group {
130+
margin-bottom: 16px;
131+
}
132+
133+
.input-label {
134+
display: block;
135+
margin-bottom: 8px;
136+
font-size: 0.9rem;
137+
font-weight: 500;
138+
}
139+
140+
.input {
141+
width: 100%;
142+
padding: 12px 16px;
143+
border-radius: 8px;
144+
border: 1px solid rgba(255, 255, 255, 0.3);
145+
background: rgba(0, 0, 0, 0.2);
146+
color: white;
147+
font-size: 1rem;
148+
font-family: 'Monaco', 'Courier New', monospace;
149+
}
150+
151+
.input::placeholder {
152+
color: rgba(255, 255, 255, 0.5);
153+
}
154+
155+
.input:focus {
156+
outline: none;
157+
border-color: white;
158+
}
159+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import type { Metadata } from "next";
2+
import "./globals.css";
3+
4+
export const metadata: Metadata = {
5+
title: "Sub Accounts Example",
6+
description: "Demo app showing Base Account Sub Accounts integration",
7+
};
8+
9+
export default function RootLayout({
10+
children,
11+
}: Readonly<{
12+
children: React.ReactNode;
13+
}>) {
14+
return (
15+
<html lang="en">
16+
<body>{children}</body>
17+
</html>
18+
);
19+
}
20+

0 commit comments

Comments
 (0)