Blacksmith
Your Ethereum or Base wallet already has one. Connect to see it. If you used Blacksmith V1, it is still this account. Blacksmith never had the keys.
Same address on Ethereum and Base. Each chain is its own setup. People can pay it now. You create it once when you need to send.
If you used Blacksmith V1, connect that wallet. Same funds. Closing a website does not touch the account.
This page can be stored on Ethereum and Base. Right now you are looking at a file. Save it. When the page lives in a contract, this block will show that address and how to open it again.
cast call HOST "html()(string)" --rpc-url https://ethereum-rpc.publicnode.com > v1.html
A contract wallet you control with the personal wallet you connect. Get paid at the smart-account address, not the one you connect with.
Yes, if you connect the same wallet. Same address, same funds. If you lose that wallet, this page cannot recover it.
You see the smart-account address for this wallet on this chain. If this chain has no contract yet, create it once. Your wallet pays gas. If it is already there, you continue.
A send is a normal transaction from the connected wallet. A little ETH there pays that gas. The smart account can still hold assets.
This page lists tokens and sends. Copy the smart-account address into any other app for the rest.
No activity yet. Sends, token transfers, and ETH this account received show up here.
Connect a wallet to fill the owner and smart-account lines. Until then the skill keeps placeholders.
--- name: blacksmith-v1-wallet description: 'Create or operate a Kernel 0.2.4 account with EOA EntryPoint.handleOps. Reusable operator manual for a contract-hosted wallet. Use when sending from this smart account, reconnecting ECDSA-sudo, creating the index-0 Kernel, or submitting UserOps without a bundler or project ID. Kernel v3 and EntryPoint 0.7 miss this account.' --- # Blacksmith V1 wallet This file is the operator manual. A human or an agent can create, reconnect, and send from this Kernel with only a wallet and the chain — no hosted app. It is inlined into the page so a copy fetched from Ethereum still teaches the same path. Resolve this Kernel from the owner EOA (index 0). Reconnect this Kernel if it already has code. If it has no code, the EOA calls factory `createAccount`. Then send with empty `initCode`. Do not add a bundler, a paymaster, or a hosted Kernel SDK. Do not deploy Kernel v3 or EntryPoint 0.7. If `kernel.mjs` is beside this file, use it for encoding. Humans: open this wallet, connect the owner EOA, create if this chain has no account yet, copy the V1 address to receive, pick assets, **Send**. ## Account - Owner EOA (must sign): YOUR_EOA_ADDRESS - Smart account: YOUR_SMART_ACCOUNT_ADDRESS - Chains: Ethereum (1) and/or Base (8453). Same address, separate state per chain. Create once per chain. - EntryPoint v0.6: `0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789` - Kernel 0.2.4 factory: `0x5de4839a76cf55d0c90e2061ef4386d962E15ae3` - Implementation: `0xd3082872F8B06073A021b4602e022d5A070d7cfC` - ECDSA validator: `0xd9AB5096a832b9ce79914329DAEE236f8Eea0390` Blacksmith never held keys. Recovery is reconnect this EOA. UserOps: empty `initCode`, empty `paymasterAndData`. Create is a separate EOA tx to the factory, not a UserOp. **Done when:** factory `getAccountAddress` for this EOA equals the smart account, that address has code (reconnect or create), and a send is an EOA tx to EntryPoint — not v3, not 0.7. ## Send 1. Resolve the account from the factory (`initialize(ECDSA validator, owner)`, index `0`). If `getCode` is empty, the EOA sends `createAccount(implementation, initialize(ECDSA, owner), 0)` to the factory, then re-reads code. Abort on address mismatch. 2. Read balances: Kernel ETH, ERC-20 `balanceOf(account)`, EntryPoint deposit (`balanceOf(account)` on EntryPoint). 3. Build a UserOp v0.6. `callData` is Kernel `execute` / `executeBatch` (selector `0x51945447` / `0x34fcd5be`, operation `0`). Token out is ERC-20 `transfer`. Native ETH is `execute(dest, value, 0x)`. Deposit out is `execute(EntryPoint, 0, withdrawTo(dest, amount))`. 4. Use the amounts entered. Several assets → one `executeBatch` UserOp; one asset → `execute`. 5. Prefund: `(callGas + verificationGas + preVerificationGas) * maxFeePerGas`. Native value cannot exceed Kernel ETH − prefund − buffer (10% of prefund or 0.0001 ETH). Deposit amount cannot exceed deposit − prefund. Never send the full Kernel ETH or full deposit. Deposit does not pay `execute` value. 6. `userOpHash` from EntryPoint. Sign with the EOA (`personal_sign`; on AA23 retry `eth_sign`). Signature = `0x00000000` ‖ 65-byte ECDSA. 7. EOA sends `handleOps([op], beneficiary=EOA)` to EntryPoint. The EOA needs ETH for that tx even if the Kernel is rich. Kernel ETH covers missing UserOp prefund (`missingAccountFunds`). Activity: EntryPoint `UserOperationEvent` (sender = Kernel), ERC-20 `Transfer` to/from the Kernel, EntryPoint `Withdrawn`, Kernel `Received` (plain ETH in). Newest first, cap 256. ETH out and ETH in with calldata have no log. ## RPC If no user RPC is set, use a public snapshot. Dated snapshots: Ethereum `https://ethereum-rpc.publicnode.com`, Base `https://base-rpc.publicnode.com`. If the user pastes an RPC, use only that URL — do not fall through to a public node (a dead local fork must not land on live L1). If that URL fails, they paste another or you may recommend a few reputable public options from `https://chainlist.org/rpcs.json`. ## Selectors `execute` `51945447` · `executeBatch` `34fcd5be` · `transfer` `a9059cbb` · `withdrawTo` `205c2878` · `getNonce` `35567e1a` · `balanceOf` `70a08231` · `initialize` `d1f57894` · `getAccountAddress` `4d6cb700` · `createAccount` `296601cd` · `getUserOpHash` `a6193531` · `handleOps` `1fad948c`