Skip to content

Commit aecce95

Browse files
committed
added wallet functionality
1 parent 65747bc commit aecce95

File tree

1 file changed

+106
-122
lines changed

1 file changed

+106
-122
lines changed

docs/mini-apps/features/wallet-actions.mdx

Lines changed: 106 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,30 @@ title: "Wallet"
33
description: "Learn the fundamental differences between Externally Owned Accounts (EOAs) and Smart Wallets, and how these differences affect your application development."
44
---
55

6-
> **What youll learn**
7-
> By the end of this guide, youll understand:
6+
> **What you'll learn**
7+
> By the end of this guide, you'll understand:
88
> - How Smart Wallet signatures work differently from EOA signatures.
99
> - When and why certain operations fail with Smart Wallets.
1010
> - How to implement universal signature verification.
11-
> - What changes are needed in your smart contracts and applications
11+
> - What changes are needed in your smart contracts and applications
1212
1313
## Authentication Differences
1414

15-
<Tabs>
16-
<Tab title="EOA Authentication">
15+
### EOA Authentication
1716
```javascript
1817
// EOA: Direct private key signing
1918
const signature = await wallet.signMessage("Hello World");
2019
// signature is always 65 bytes (130 hex chars + 0x prefix)
2120
```
22-
</Tab>
2321

24-
<Tab title="Smart Wallet Authentication">
22+
### Smart Wallet Authentication
2523
```javascript
2624
// Smart Wallet: Contract-based validation
2725
const signature = await smartWallet.signMessage("Hello World");
2826
// signature format varies, validated via EIP-1271
2927
```
30-
</Tab>
31-
</Tabs>
3228

33-
<Note>
34-
EOAs use private keys directly. Smart Wallets use passkeys that are validated by the wallet contract through the `isValidSignature` function.
35-
</Note>
29+
**Key Difference**: EOAs use private keys directly. Smart Wallets use passkeys validated by the wallet contract through `isValidSignature`.
3630

3731
## Signature Verification
3832

@@ -119,56 +113,54 @@ Smart Wallets can batch multiple operations into a single transaction, reducing
119113
## Smart Contract Incompatibilities
120114

121115
### Self-Calls Will Fail
122-
Smart Wallets have restrictions on certain operations to maintain security and compliance with the ERC-4337 standard.
116+
117+
Smart Wallets block calls back to themselves for security and ERC-4337 compliance.
123118

124119
```solidity
125120
// This will fail with Smart Wallets
126121
function badExample() external {
127122
// msg.sender is the Smart Wallet contract
123+
// This call back to the wallet will be blocked
128124
IWallet(msg.sender).transfer(amount);
129125
}
130126
131127
// Pass data as parameters instead
132128
function goodExample(address recipient, uint256 amount) external {
133-
// Process parameters directly
129+
// Process parameters directly without calling back to msg.sender
134130
_transfer(recipient, amount);
135131
}
136132
```
137133

138134
### CREATE Opcode Not Supported
139135

140-
Smart Wallets cannot use the CREATE opcode to deploy new contracts directly. This is a limitation of the ERC-4337 standard and smart accounts, as confirmed by the Base Account documentation.
136+
ERC-4337 doesn't support CREATE opcode. Use CREATE2 with factory patterns instead.
141137

142138
```solidity
143139
// Smart Wallets cannot use CREATE
144140
function badDeploy() external {
145-
new MyContract(); // Will fail
141+
// This will fail - CREATE opcode not supported in ERC-4337
142+
new MyContract();
146143
}
147144
148145
// Use CREATE2 factory pattern
149146
function goodDeploy(bytes32 salt) external {
147+
// CREATE2 is supported and creates deterministic addresses
150148
new MyContract{salt: salt}();
151149
}
152150
```
153151

154152
### Transfer vs Call
155153

156-
The Solidity `.transfer()` method forwards exactly **2300 gas** to the recipient. However, Smart Wallets often require more gas than this limit to execute their `receive` or `fallback` functions, which may include:
157-
158-
- Updating internal balances or state
159-
- Emitting events for transaction tracking
160-
- Executing additional logic in their receive functions
161-
- Handling complex fallback scenarios
162-
163-
Because Smart Wallets are contracts, these operations can easily exceed the 2300 gas limit imposed by `.transfer()`, causing transfers to fail.
154+
`.transfer()` forwards only 2300 gas, which is insufficient for Smart Wallet operations that may need more gas for state updates and event emissions.
164155

165156
```solidity
166-
// .transfer() can fail with Smart Wallets
157+
// .transfer() forwards only 2300 gas - may fail with Smart Wallets
167158
payable(user).transfer(amount);
168159
169-
// Use .call() with explicit gas
160+
// Use .call() with adequate gas allowance
170161
(bool success, ) = payable(user).call{value: amount, gas: 10000}("");
171162
require(success, "Transfer failed");
163+
// Provides enough gas for Smart Wallet operations
172164
```
173165

174166
<Warning>
@@ -177,136 +169,128 @@ Always use `.call()` instead of `.transfer()` when sending ETH to avoid failures
177169

178170
## Gas Payment Differences
179171

180-
<Tabs>
181-
<Tab title="EOAs Must Hold ETH">
172+
**EOAs**: Must hold ETH for gas fees
182173
```javascript
183-
// EOA: Must have ETH balance
184174
const balance = await provider.getBalance(eoaAddress);
185-
if (balance.eq(0)) {
186-
throw new Error("Need ETH for gas");
187-
}
175+
if (balance.eq(0)) throw new Error("Need ETH for gas");
188176
```
189-
</Tab>
190177

191-
<Tab title="Smart Wallets Can Use Sponsored Gas">
178+
**Smart Wallets**: Can use sponsored gas via paymasters
192179
```javascript
193-
// Smart Wallet: Can use paymasters for sponsored transactions
180+
// Check paymaster support
194181
const capabilities = await wallet.request({
195-
method: 'wallet_getCapabilities'
182+
method: 'wallet_getCapabilities',
183+
params: [address]
196184
});
197185

198-
if (capabilities.paymasterService) {
199-
// Transaction can be sponsored
200-
await sponsoredTransaction();
186+
if (capabilities[chainId]?.paymasterService?.supported) {
187+
// Use sponsored transactions
188+
await wallet.request({
189+
method: 'wallet_sendCalls',
190+
params: [{ /* transaction with paymaster capabilities */ }]
191+
});
201192
}
202193
```
203-
</Tab>
204-
</Tabs>
205194
206195
## Deployment Differences
207196
208-
| Aspect | EOA | Smart Wallet |
209-
|--------|-----|-------------|
210-
| **Deployment** | No deployment needed | Contract must be deployed |
211-
| **Address Generation** | Derived from public key | Deterministic before deployment |
212-
| **Availability** | Immediately usable | Can use lazy deployment |
213-
| **Pre-deployment Signing** | Not applicable | Supported via ERC-6492 |
197+
**EOAs**: No deployment needed, immediately usable, address derived from public key
198+
199+
**Smart Wallets**: Contract deployment required (can be lazy), deterministic addresses, supports pre-deployment signing via ERC-6492
214200
215201
## Implementation Checklist
216202
217203
### For Applications Supporting Both Wallet Types
218204
219-
<AccordionGroup>
220-
<Accordion title="Signature Verification">
221-
- Implement universal signature verification
205+
<Steps>
206+
<Step title="Signature Verification">
207+
Implement universal signature verification that supports both ECDSA (EOA) and EIP-1271 (Smart Wallet).
208+
222209
- Support ERC-6492 for undeployed Smart Wallets
210+
- Reference the [Sign and Verify Typed Data guide](https://docs.base.org/base-account/guides/sign-and-verify-typed-data)
223211
- Test with both wallet types
224-
</Accordion>
225212
226-
<Accordion title="Transaction Handling">
227-
- Support both direct transactions and UserOperations
228-
- Implement batching where beneficial
229-
- Handle sponsored gas scenarios
230-
</Accordion>
213+
<Check>
214+
Verify your signature verification works with both deployed and undeployed Smart Wallets.
215+
</Check>
216+
</Step>
231217
232-
<Accordion title="Gas Assumptions">
233-
- Do not assume users hold ETH
234-
- Check for paymaster capabilities
218+
<Step title="Capability Detection">
219+
Use `wallet_getCapabilities` to detect supported features.
220+
221+
- Check the [Base Account Capabilities documentation](https://docs.base.org/base-account/reference/core/capabilities/overview) for available capabilities
222+
- Implement capability-specific features using `wallet_sendCalls` or `wallet_connect` as appropriate
223+
</Step>
224+
225+
<Step title="Transaction Handling">
226+
Support both direct transactions (EOA) and UserOperations (Smart Wallet).
227+
228+
- Implement batching with `wallet_sendCalls` or Wagmi's `useWriteContracts` where beneficial
229+
- Handle sponsored gas scenarios using paymaster capabilities
230+
</Step>
231+
232+
<Step title="Gas Assumptions">
233+
Do not assume users hold ETH.
234+
235+
- Check for paymaster capabilities before requiring ETH balance
235236
- Provide fallbacks for non-sponsored transactions
236-
</Accordion>
237-
</AccordionGroup>
237+
238+
<Check>
239+
Test your application with Smart Wallets that have zero ETH balance.
240+
</Check>
241+
</Step>
242+
</Steps>
238243
239244
### For Smart Contracts
240245
241-
<AccordionGroup>
242-
<Accordion title="Compatibility Audit">
243-
- Remove all self-calls to `msg.sender`
244-
- Replace CREATE with CREATE2 patterns
245-
- Replace `.transfer()` with `.call()`
246-
- Test with Smart Wallet accounts
247-
</Accordion>
248-
</AccordionGroup>
246+
<Steps>
247+
<Step title="Compatibility Audit">
248+
Remove all self-calls to `msg.sender`.
249249
250-
## Testing Your Implementation
250+
<Warning>
251+
Self-calls to `msg.sender` will fail with Smart Wallets.
252+
</Warning>
253+
</Step>
251254
252-
```javascript
253-
describe('Universal Wallet Support', () => {
254-
it('verifies EOA signatures', async () => {
255-
const message = "Test message";
256-
const signature = await eoaWallet.signMessage(message);
257-
const isValid = await verifyUniversalSignature(
258-
message,
259-
signature,
260-
eoaAddress,
261-
provider
262-
);
263-
expect(isValid).toBe(true);
264-
});
265-
266-
it('verifies Smart Wallet signatures', async () => {
267-
const message = "Test message";
268-
const signature = await smartWallet.signMessage(message);
269-
const isValid = await verifyUniversalSignature(
270-
message,
271-
signature,
272-
smartWalletAddress,
273-
provider
274-
);
275-
expect(isValid).toBe(true);
276-
});
277-
278-
it('handles batched transactions', async () => {
279-
const operations = [
280-
{ to: contract1.address, data: calldata1 },
281-
{ to: contract2.address, data: calldata2 }
282-
];
283-
284-
const result = await smartWallet.executeBatch(operations);
285-
expect(result.success).toBe(true);
286-
});
287-
});
288-
```
255+
<Step title="Replace CREATE with CREATE2">
256+
Replace CREATE with CREATE2 patterns for deterministic addresses.
257+
</Step>
289258
290-
## Common Mistakes to Avoid
259+
<Step title="Update Transfer Patterns">
260+
Replace `.transfer()` with `.call()` for adequate gas forwarding.
261+
</Step>
291262
292-
<AccordionGroup>
293-
<Accordion title="Signature Assumptions">
294-
**Assuming 65-byte signatures**: Smart Wallet signatures have variable length
263+
<Step title="Test with Smart Wallets">
264+
Test with Smart Wallet accounts to ensure compatibility.
265+
266+
<Check>
267+
Run comprehensive tests with both EOA and Smart Wallet accounts.
268+
</Check>
269+
</Step>
270+
</Steps>
271+
272+
## Common Mistakes to Avoid
295273
296-
**Hardcoding ECDSA recovery**: Use universal verification instead
297-
</Accordion>
274+
1. **Assuming 65-byte signatures**: Smart Wallet signatures have variable length
275+
2. **Requiring ETH balance**: Smart Wallets may use sponsored gas
276+
3. **Using self-calls in contracts**: These will fail with Smart Wallets
277+
4. **Hardcoding ECDSA recovery**: Use universal verification instead
278+
5. **Using CREATE opcode**: Smart Wallets cannot use CREATE, only CREATE2
298279
299-
<Accordion title="Gas and Contract Patterns">
300-
**Requiring ETH balance**: Smart Wallets may use sponsored gas
280+
## Next Steps
301281
302-
**Using self-calls in contracts**: These will fail with Smart Wallets
282+
<CardGroup cols={2}>
283+
<Card title="Base Account Documentation" href="https://docs.base.org/base-account/reference/core/capabilities/overview">
284+
Complete Smart Wallet integration, capabilities, and implementation guides
285+
</Card>
303286
304-
**Using CREATE opcode**: Smart Wallets cannot use CREATE, only CREATE2
305-
</Accordion>
306-
</AccordionGroup>
287+
<Card title="Signature Verification Guide" href="https://docs.base.org/base-account/guides/sign-and-verify-typed-data">
288+
EIP-712 structured data signing and verification examples
289+
</Card>
290+
</CardGroup>
307291
308292
## Technical References
309293
310-
- [**EIP-1271**: Standard Signature Validation Method for Contracts](https://eips.ethereum.org/EIPS/eip-1271)
311-
- [**ERC-4337**: Account Abstraction Using Alt Mempool](https://eips.ethereum.org/EIPS/eip-4337)
312-
- [**ERC-6492**: Signature Validation for Predeploy Contracts](https://eips.ethereum.org/EIPS/eip-6492)
294+
- [EIP-1271: Standard Signature Validation Method for Contracts](https://eips.ethereum.org/EIPS/eip-1271)
295+
- [ERC-4337: Account Abstraction Using Alt Mempool](https://eips.ethereum.org/EIPS/eip-4337)
296+
- [ERC-6492: Signature Validation for Predeploy Contracts](https://eips.ethereum.org/EIPS/eip-6492)

0 commit comments

Comments
 (0)