abstractionkit 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,113 +1,219 @@
1
1
  # Changelog
2
2
 
3
- ## 0.3.0
3
+ ## 0.3.2
4
+
5
+ ### New Features
6
+
7
+ - **`signUserOperationWithSigner(s)` + `ExternalSigner` (capability-oriented signing API)**: new async method on every account class for integrating viem, ethers Signers, hardware wallets, HSMs, MPC, WebAuthn, or Uint8Array-only signers without passing raw private keys. Each account declares its accepted schemes via a static `ACCEPTED_SIGNING_SCHEMES: ReadonlyArray<"hash" | "typedData">`, and incompatible signers fail offline with an actionable error. The method naming mirrors the parameter arity:
8
+ - Safe accounts (multi-signer): `signUserOperationWithSigners(op, signers[], chainId)` — plural.
9
+ - Simple7702 / Calibur (single signer): `signUserOperationWithSigner(op, signer, chainId)` — singular.
10
+
11
+ Call-site is one line:
12
+ ```ts
13
+ import { fromViem } from "abstractionkit"
14
+ userOp.signature = await safe.signUserOperationWithSigners(
15
+ userOp, [fromViem(account)], chainId,
16
+ )
17
+ ```
18
+
19
+ - **`ExternalSigner` interface**: `{ address, signHash?, signTypedData? }` discriminated union that enforces at least one of the two methods at compile time. Accepts any signer that matches the shape (viem local account, viem WalletClient, ethers Wallet, hardware wallet, MPC, WebAuthn, Uint8Array-held keys). The library has zero runtime dependency on viem or ethers for this surface.
20
+ - **`fromPrivateKey(pk)` / `fromViem(account)` / `fromEthersWallet(wallet)` / `fromViemWalletClient(client)` adapters**: one-line factories returning an `ExternalSigner`. Structural types only. `fromViem` / `fromViemWalletClient` require viem ≥ 2.0; `fromEthersWallet` requires ethers ≥ 6.0.
21
+ - **`SignHashFn` / `SignTypedDataFn` / `TypedData` / `SigningScheme` / `SignContext` / `MultiOpSignContext` types** exported from the package root for implementers of custom signers.
22
+ - **`SignContext` forwarded to signers, narrowly typed per signing path**: signers receive a context as the second arg of `signHash` / `signTypedData` so custom validator implementations can inspect the userOp. `Signer<C>` is generic over context (default `C = SignContext` for single-op `{userOperation, chainId, entryPoint}`; opt into `ExternalSigner<MultiOpSignContext>` for `signUserOperationsWithSigners`'s `{userOperations[], entryPoint}`). Built-in adapters return `Signer<unknown>` and work everywhere. See `src/signer/types.ts`.
23
+ - **`SafeMultiChainSigAccountV1.signUserOperationsWithSigners`**: new async multi-op variant that signs a Merkle-rooted bundle of UserOperations with a single signature across chains, using `ExternalSigner[]`.
4
24
 
5
25
  ### Breaking Changes
6
26
 
7
- #### Build & Runtime
27
+ > **Note on versioning.** The callback-API removal below is a breaking change for callers of `signUserOperationWithSigner`'s prior callback shape on `Calibur7702Account`. Calibur is not yet in use in any production environment; we're communicating directly with the developers currently building against it to coordinate the migration.
28
+
29
+ - **`SafeAccount.baseSignSingleUserOperation` is now `protected static`.** Previously `public static`, which leaked an internal helper into the package surface. All callers should use the version-specific subclass methods that wrap it (`SafeAccountV0_2_0#signUserOperation`, `SafeAccountV0_3_0#signUserOperation`, etc.) — they auto-inject the correct entrypoint and 4337 module addresses. Migration:
30
+ ```ts
31
+ // Before:
32
+ const sig = SafeAccount.baseSignSingleUserOperation(
33
+ op, [pk], chainId,
34
+ SafeAccountV0_3_0.DEFAULT_ENTRYPOINT_ADDRESS,
35
+ SafeAccountV0_3_0.DEFAULT_SAFE_4337_MODULE_ADDRESS,
36
+ );
37
+ // After:
38
+ const sig = safeV3.signUserOperation(op, [pk], chainId);
39
+ ```
40
+ `baseSignUserOperationWithSigners` (introduced earlier in this Unreleased window) is also `protected static` for the same reason; no migration needed since it was never on a released `latest` tag.
41
+ - **`ViemLocalAccountLike` / `ViemWalletClientLike` / `EthersWalletLike` are no longer exported.** They're internal structural shapes the adapters match against; pass concrete viem / ethers instances directly to `fromViem` / `fromViemWalletClient` / `fromEthersWallet`. If you need to type a wrapper, use `Parameters<typeof fromViem>[0]` (etc.).
42
+ - **Callback signing API removed.** `signUserOperationWithSigner(op, callback, chainId)` as introduced in the original signer PR is gone, along with the `SignerFunction`, `AddressedSignerFunction`, `SignerInput`, `SignerResult`, and `SignerTypedData` types. The callback method name is now reused for the new capability-oriented API on single-signer accounts (Simple7702, Calibur) with a different parameter shape. Migration:
43
+ ```ts
44
+ // Before:
45
+ const signer = async ({ userOpHash }) => ({
46
+ signature: wallet.signingKey.sign(userOpHash).serialized,
47
+ });
48
+ userOp.signature = await account.signUserOperationWithSigner(userOp, signer, chainId);
49
+
50
+ // After — Simple7702 / Calibur (single signer):
51
+ import { fromEthersWallet } from "abstractionkit";
52
+ userOp.signature = await account.signUserOperationWithSigner(
53
+ userOp, fromEthersWallet(wallet), chainId,
54
+ );
55
+
56
+ // After — Safe accounts (multi-signer, plural method name):
57
+ userOp.signature = await safe.signUserOperationWithSigners(
58
+ userOp, [fromEthersWallet(wallet)], chainId,
59
+ );
60
+ ```
61
+
62
+ ### Migration: Signing with a raw private key
63
+
64
+ The existing sync `signUserOperation(op, pk[] | pk, chainId): string` method on every account **is untouched**. If your code passes a hex private-key string directly, no change needed. The new `signUserOperationWithSigner(s)` methods are Signers-only — they do NOT accept bare pk strings. To sign with a pk string via the new API, wrap explicitly:
65
+
66
+ ```ts
67
+ import { fromPrivateKey } from "abstractionkit";
68
+ userOp.signature = await safe.signUserOperationWithSigners(
69
+ userOp, [fromPrivateKey(pk)], chainId,
70
+ );
71
+ ```
72
+
73
+ ## 0.3.1
8
74
 
9
- - **Node.js >= 18 required** — native `fetch` is now used; `isomorphic-unfetch` has been removed as a dependency.
10
- - **Build system switched from microbundle to tsdown** — dist output paths have changed:
11
- - `dist/index.js` → `dist/index.cjs`
12
- - `dist/index.m.js` → `dist/index.mjs`
13
- - `dist/index.umd.js` → `dist/index.iife.js`
14
- - `dist/index.d.ts` → `dist/index.d.cts`
15
- - Proper `exports` map added to `package.json` for ESM/CJS resolution.
75
+ ### New Features
16
76
 
17
- #### API Changes
77
+ - **`Erc7677Paymaster`**: provider-agnostic [ERC-7677](https://eips.ethereum.org/EIPS/eip-7677) paymaster client. Works with any compliant provider (Candide, Pimlico, Alchemy, ...). Auto-detects Candide/Pimlico from the URL and runs the full stub, estimate, and final pipeline in one call. Passing `{ token }` in context triggers the ERC-20 gas flow automatically.
78
+ - `Bundler.estimateUserOperationGas` now forwards `paymasterVerificationGasLimit` and `paymasterPostOpGasLimit` when returned by the bundler.
18
79
 
19
- - **`signUserOperation` now only accepts a private key.** Use the new `signUserOperationWithSigner` method for external/custom signers.
20
- - **`createPaymasterUserOperation` removed.** Use `CandidePaymaster` methods directly.
21
- - **CandidePaymaster migrated to `pm_getPaymasterData` RPC** — paymaster types have been unified and restructured.
22
- - **`PaymasterInitValues` renamed to `ParallelPaymasterInitValues`.**
80
+ ### Breaking Changes
23
81
 
24
- #### Renames
82
+ - **`SafeMultiChainSigAccountV1.formatSignaturesToUseroperationsSignatures`**: the third `overrides` argument has been removed. Overrides are now per-operation via a new optional `overrides` field on each `UserOperationToSignWithOverrides` element of the first argument. Migration: `ops.map(op => ({ ...op, overrides: {...} }))` and drop the third argument.
25
83
 
26
- | Before | After |
27
- |--------|-------|
28
- | `ExperimentalSafeMultiChainSigAccount` | `SafeMultiChainSigAccountV1` |
29
- | `ExperimentalAllowAllPaymaster` | `ExperimentalAllowAllParallelPaymaster` |
30
- | `EIP712_MULTI_SAFE_OPERATIONS_TYPE` | `EIP712_MULTI_CHAIN_OPERATIONS_TYPE` |
31
- | `listKeys` (Calibur) | `getKeys` |
84
+ ### Other
85
+
86
+ - Minor type tightening across Calibur, Simple7702, and Tenderly helpers.
87
+
88
+ ## 0.3.0
89
+
90
+ **This is a major release. The canonical upgrade path is from 0.2.30 (previous stable) to 0.3.0 (current stable).** Versions 0.2.31 through 0.2.41 were experimental pre-releases and are not on the `latest` dist-tag.
91
+
92
+ ### Breaking Changes
32
93
 
33
- #### TypeScript Export Changes
94
+ #### Build & Runtime
95
+
96
+ - **Node.js >= 18 required.** Native `fetch` is now used; `isomorphic-unfetch` has been removed as a dependency.
97
+ - **Build system switched from microbundle to tsdown.** Dist output paths have changed. If you import from a subpath, update your references:
98
+ - `dist/index.js` -> `dist/index.cjs`
99
+ - `dist/index.m.js` -> `dist/index.mjs`
100
+ - `dist/index.umd.js` -> `dist/index.iife.js`
101
+ - `dist/index.d.ts` -> `dist/index.d.cts`
102
+ - A proper `exports` map has been added to `package.json` for ESM/CJS resolution, so normal `import { X } from "abstractionkit"` consumers are unaffected.
103
+
104
+ #### Paymaster API
105
+
106
+ - **`CandidePaymaster.createSponsorPaymasterUserOperation(...)` signature changed.** The method now takes `smartAccount` as the **first** argument. Migration:
107
+ ```ts
108
+ // Before (0.2.30):
109
+ await paymaster.createSponsorPaymasterUserOperation(userOp, bundlerRpc, sponsorshipPolicyId, overrides);
110
+
111
+ // After (0.3.0):
112
+ await paymaster.createSponsorPaymasterUserOperation(smartAccount, userOp, bundlerRpc, sponsorshipPolicyId, overrides);
113
+ ```
114
+ The `overrides` parameter type is also richer: it now accepts a `context?: CandidePaymasterContext` field for passing `sponsorshipPolicyId` and the new parallel-signing `signingPhase` option through overrides.
115
+ - **`createPaymasterUserOperation` has been removed.** Use `createSponsorPaymasterUserOperation` or `createTokenPaymasterUserOperation` directly.
116
+ - **CandidePaymaster now uses the `pm_getPaymasterData` JSON-RPC method** internally. Paymaster types have been unified and restructured.
117
+ - **`PaymasterInitValues` renamed to `ParallelPaymasterInitValues`.**
34
118
 
35
- Several interfaces and types are now exported as `export type` instead of `export` for `isolatedModules` compatibility. This is only breaking if you re-export them with `export { X } from "abstractionkit"` — change to `export type { X }`:
119
+ #### TypeScript Export Changes (`isolatedModules` compatibility)
120
+
121
+ Many interfaces and types are now exported with `export type` instead of `export`. This is only breaking if you re-export them yourself with `export { X } from "abstractionkit"`, in which case change to `export type { X }`. Affected identifiers include:
36
122
 
37
123
  - `RecoveryRequest`, `RecoverySignaturePair`, `RecoveryRequestTypedDataDomain`, `RecoveryRequestTypedMessageValue`
38
124
  - `Allowance`
39
125
  - `DepositInfo`
40
126
  - `Authorization7702Hex`, `Authorization7702`
41
127
  - `CandidePaymasterContext`, `PrependTokenPaymasterApproveAccount`
42
- - `UserOperationV6`, `UserOperationV7`, `UserOperationV8`, `AbiInputValue`, `JsonRpcParam`, `JsonRpcResponse`, `MetaTransaction`, `StateOverrideSet`, etc.
128
+ - `UserOperationV6`, `UserOperationV7`, `UserOperationV8`, `UserOperationV9`, `AbiInputValue`, `JsonRpcParam`, `JsonRpcResponse`, `MetaTransaction`, `StateOverrideSet`, and other non-runtime types from `./types`
129
+ - `CreateUserOperationV6Overrides`, `CreateUserOperationV7Overrides`, `CreateUserOperationV9Overrides`, `ECDSAPublicAddress`, `InitCodeOverrides`, `SafeUserOperationTypedDataDomain`, `WebauthnPublicKey`, `WebauthnSignatureData`, `SignerSignaturePair`, `Signer`
43
130
  - `SafeMessageTypedDataDomain`, `SafeMessageTypedMessageValue`
44
- - `SafeUserOperationTypedDataDomain`, `WebauthnPublicKey`, `WebauthnSignatureData`, `SignerSignaturePair`, `Signer`, etc.
45
131
 
46
- The wildcard re-export `export * from "./account/Safe/safeMessage"` has been replaced with explicit named exports.
132
+ The wildcard re-export `export * from "./account/Safe/safeMessage"` has been replaced with explicit named exports (`SAFE_MESSAGE_PRIMARY_TYPE`, `SAFE_MESSAGE_MODULE_TYPE`, `getSafeMessageEip712Data`).
47
133
 
48
134
  ### New Features
49
135
 
50
- #### EIP-7702 Support
136
+ #### New Account Classes
137
+
138
+ - **`Calibur7702Account`**: full-featured EIP-7702 smart account for EntryPoint v0.8, ported from Uniswap's Calibur. Supports secp256k1, P256, and WebAuthn P256 keys with per-key permissions and expirations. Includes key management (register, revoke, update settings via self-calls), automatic EIP-7702 delegation authoring and checking, and delegation revocation. Also exports `CaliburKeyType` and the `CaliburKey`, `CaliburKeySettings`, `CaliburKeySettingsResult`, `WebAuthnSignatureData`, `CaliburCreateUserOperationOverrides`, `CaliburSignatureOverrides`, and `SignerFunction` types.
139
+ - **`Simple7702AccountV09`**: minimal EIP-7702 account targeting EntryPoint v0.9, with parallel paymaster signing support.
140
+ - **`SafeMultiChainSigAccountV1`**: audited multi-chain signature account. Sign once, replay across chains via a merkle-proof structure. Promoted from experimental.
141
+ - **`SafeAccountV1_5_0_M_0_3_0`**: Safe contract v1.5.0 support with EIP-7951 and the Daimo P256 verifier for WebAuthn.
142
+
143
+ #### EntryPoint v0.8 and v0.9 Support
51
144
 
52
- - **`Simple7702Account`** EIP-7702 account for EntryPoint v0.8.
53
- - **`Simple7702AccountV09`** EIP-7702 account for EntryPoint v0.9, with parallel paymaster support.
54
- - **`Calibur7702Account`** full-featured EIP-7702 account with WebAuthn/passkey support, key management, delegation auto-checking, and delegation revocation.
55
- - **`getDelegatedAddress`** utility for checking EIP-7702 delegation status.
56
- - **EIP-7702 delegation helpers** on `BaseSimple7702Account` (create, sign, and revoke delegation authorizations).
57
- - **Tenderly simulation support** for EntryPoint v0.9.
145
+ - `UserOperationV9` type and `CreateUserOperationV9Overrides` added.
146
+ - `ENTRYPOINT_V6`, `ENTRYPOINT_V7`, `ENTRYPOINT_V8`, `ENTRYPOINT_V9` address constants exported.
147
+ - Bundler, CandidePaymaster, and Tenderly simulation helpers updated to handle all four EntryPoint versions.
148
+ - Entrypoint version resolution has been centralized in `CandidePaymaster`: a new private `resolveEntrypoint` helper reads the target entrypoint from the smart account instance at the top of each public method, replacing the per-method `UserOperation vX.YZ is not supported` checks from 0.2.30. The guard itself is not new, but unsupported-version errors are now surfaced earlier and more consistently.
149
+
150
+ #### Parallel Paymaster Signing (EntryPoint v0.9)
151
+
152
+ - **`ExperimentalAllowAllParallelPaymaster`**: an experimental paymaster for the parallel-signing flow.
153
+ - **`signingPhase`** added to `CandidePaymasterContext`, with values `"commit"` and `"finalize"`. Enables parallel-signing flows where owner signing and the paymaster's final signature can happen independently, via the `PAYMASTER_SIG_MAGIC` convention on `paymasterData`. Works with EntryPoint v0.9 only.
154
+ - `CandidePaymaster` supports both v0.9 parallel flows and the existing sequential flow.
58
155
 
59
156
  #### Safe Accounts
60
157
 
61
- - **`SafeAccountV1_5_0_M_0_3_0`** Safe contract v1.5.0 support with EIP-7951 and Daimo P256 verifier for WebAuthn.
62
- - **`SafeMultiChainSigAccountV1`** multi-chain signature account (audited, promoted from experimental).
63
- - `createChangeThresholdMetaTransaction`, `createApproveHashMetaTransaction`, and `getThreshold` methods.
64
- - Auto-prepend `approve(0)` for ERC-20 tokens that require allowance reset before setting a new approval.
158
+ - **`createChangeThresholdMetaTransaction`**, **`createApproveHashMetaTransaction`**, and **`getThreshold`** added to `SafeAccount`. Makes multi-sig threshold management and offchain approval flows first-class.
159
+ - **Auto-prepend `approve(0)`** before setting a new ERC-20 allowance for tokens like USDT that disallow changing a non-zero allowance directly. Opt in via `{ resetApproval: true }` on the token paymaster overrides.
160
+ - **`MerkleTree`** helper utilities added for multi-chain operations.
161
+
162
+ #### AllowanceModule v1.0.0
163
+
164
+ - Allowance module updated to v1.0.0. The legacy address is exported as **`ALLOWANCE_MODULE_V0_1_0_ADDRESS`** for migration purposes.
165
+
166
+ #### Calibur Singleton Addresses
65
167
 
66
- #### EntryPoint v0.9
168
+ - **`CALIBUR_UNISWAP_V1_0_0_SINGLETON_ADDRESS`** and **`CALIBUR_CANDIDE_V0_1_0_SINGLETON_ADDRESS`** exported as constants.
67
169
 
68
- - `UserOperationV9` type added.
69
- - Version-entrypoint compatibility guard — mismatched UserOperation versions are now caught early.
70
- - Entrypoint version is now resolved from the account instance.
170
+ #### EIP-7702 Delegation Helpers
71
171
 
72
- #### Paymaster
172
+ - **`getDelegatedAddress(eoaAddress, nodeRpc)`** utility for checking the current EIP-7702 delegation target of an EOA.
173
+ - **Calibur delegation and key revocation**: `Calibur7702Account.createRevokeKeyMetaTransaction` and `createRevokeAllKeysMetaTransactions` for revoking individual or all registered keys, plus `createRevokeDelegationRawTransaction` for revoking the EIP-7702 delegation itself. Complements automatic delegation checking during UserOperation creation.
73
174
 
74
- - **`CandidePaymaster` now supports EntryPoint v0.9 and parallel signing flows.**
75
- - **`ExperimentalAllowAllParallelPaymaster`** for parallel paymaster data flows.
76
- - **Signing phases** added to the context object, with support in paymaster flows.
77
- - Parallel paymaster support for `Simple7702AccountV09`.
175
+ #### Utilities and Constants
78
176
 
79
- #### Utilities
177
+ - **EIP-2098** compact signature support in `parseRawSignature`.
178
+ - **`EIP712_SAFE_OPERATION_PRIMARY_TYPE`** and **`EIP712_MULTI_CHAIN_OPERATIONS_PRIMARY_TYPE`** constants added alongside the existing EIP-712 type constants.
179
+ - **`EIP712_MULTI_CHAIN_OPERATIONS_TYPE`** (previously `EIP712_MULTI_SAFE_OPERATIONS_TYPE`, renamed).
180
+ - New paymaster-type exports: **`AnyUserOperation`**, **`SameUserOp`**.
80
181
 
81
- - `MerkleTree` helper functions for multi-chain operations.
82
- - EIP-2098 compact signature support in `parseRawSignature`.
83
- - `EIP712_SAFE_OPERATION_PRIMARY_TYPE` and `EIP712_MULTI_CHAIN_OPERATIONS_PRIMARY_TYPE` constants.
84
- - Entrypoint address constants: `ENTRYPOINT_V6`, `ENTRYPOINT_V7`, `ENTRYPOINT_V8`, `ENTRYPOINT_V9`.
85
- - `CALIBUR_UNISWAP_V1_0_0_SINGLETON_ADDRESS` and `CALIBUR_CANDIDE_V0_1_0_SINGLETON_ADDRESS` constants.
86
- - Legacy `ALLOWANCE_MODULE_V0_1_0_ADDRESS` constant for migration.
182
+ #### Tenderly
183
+
184
+ - Tenderly simulation helpers updated to support EntryPoint v0.9 and `IAccountExecute.executeUserOp` callData rewriting.
185
+
186
+ ### Renames
187
+
188
+ | Before | After |
189
+ |--------|-------|
190
+ | `ExperimentalSafeMultiChainSigAccount` | `SafeMultiChainSigAccountV1` |
191
+ | `ExperimentalAllowAllPaymaster` | `ExperimentalAllowAllParallelPaymaster` |
192
+ | `EIP712_MULTI_SAFE_OPERATIONS_TYPE` | `EIP712_MULTI_CHAIN_OPERATIONS_TYPE` |
193
+ | `PaymasterInitValues` | `ParallelPaymasterInitValues` |
194
+ | `listKeys` (Calibur) | `getKeys` |
195
+
196
+ These renames only apply to code built on intermediate experimental versions (0.2.31 through 0.2.41). Code on 0.2.30 does not reference these identifiers.
87
197
 
88
198
  ### Bug Fixes
89
199
 
90
- - Fix object mutation via aliasing in `SafeAccountV1_5_0_M_0_3_0` and `CandidePaymaster`.
91
- - Fix object mutation, infinite recursion, and missing module address in multi-chain leaf hashes.
92
- - Fix BigInt gas scaling, merkle proof forwarding, entrypoint dispatch, and missing override fields.
93
- - Fix `CHAIN_ID` BigInt crash.
94
- - Fix gas overrides calculations.
95
- - Fix `formatSignaturesToUseroperationsSignatures` overrides and single-op case handling.
96
- - Fix `paymasterAndData` packing and signing when `PAYMASTER_SIG_MAGIC` is appended (v0.9).
97
- - Fix fractional percentage multipliers in `applyMultiplier`.
98
- - Fix normalize `paymasterMetadata` hex fields in `fetchSupportedERC20TokensAndPaymasterMetadata`.
99
- - Fix multi-chain sig account singleton forwarding, hash overrides, and type safety.
100
- - Fix constructor forwarding, timeout tracking, and unhandled promises.
101
- - Fix reverse proof order to match onchain verification order.
102
- - Fix WebAuthn passkeys v0.2.1 compatibility for custom contract addresses.
103
- - Fix token approval prepended before existing calls in SafeAccount multisend.
104
- - Fix `IAccountExecute.executeUserOp` callData rewriting for Tenderly simulation.
105
- - Fix multi-chain defaults in `formatSignaturesToUseroperationsSignatures`.
200
+ Fixes listed here apply to APIs that already existed at 0.2.30. Bugs that were fixed within new-in-0.3.0 features during their pre-release development are not listed separately; those features are shipped in their final form as part of the "New Features" section.
201
+
202
+ - **Gas estimation**: fixed gas overrides calculations, BigInt gas scaling, and handling of fractional percentage multipliers in `applyMultiplier`.
203
+ - **SafeAccount multisend**: fixed a bug where token paymaster approvals were prepended after existing calls instead of before them.
204
+ - **WebAuthn passkeys**: fixed compatibility with the v0.2.1 shared-signer contracts when using custom contract addresses.
205
+ - **EIP-7702 utilities**: fixed `CHAIN_ID` BigInt crash in signing helpers and exposed `DEFAULT_DELEGATEE_ADDRESS` as a static property.
206
+ - **Safe v0.3.0 account**: fixed `safeAccountSingleton` forwarding and added missing `webAuthnSignerProxyCreationCode` handling.
207
+ - **CandidePaymaster**: fixed `paymasterMetadata` hex-field normalization in `fetchSupportedERC20TokensAndPaymasterMetadata`; fixed several instances of in-place mutation via aliasing on the user-passed UserOperation.
208
+ - **Constructor forwarding and lifecycle**: fixed unhandled promises, timeout tracking, and constructor argument forwarding across pre-existing classes.
209
+ - **Miscellaneous**: typo fixes in error messages, removal of unused imports and dead guards, unused `safeV06PrevModuleAddress` removed, chainId validation tightened in pre-existing helpers.
106
210
 
107
211
  ### Internal
108
212
 
109
- - Build system migrated from microbundle to tsdown.
110
- - Removed `isomorphic-unfetch` and `rimraf` dependencies.
213
+ - Build system migrated from microbundle to tsdown. Output paths updated (see Breaking Changes).
214
+ - `Simple7702Account` refactored into a `BaseSimple7702Account` pattern to enable the new `Simple7702AccountV09` subclass. No user-facing API changes on `Simple7702Account` itself.
215
+ - Removed `isomorphic-unfetch` and `rimraf` dependencies; `rimraf` replaced with a cross-platform inline Node script.
111
216
  - Added CI workflow (`.github/workflows/ci.yml`) using yarn.
112
217
  - Added `SECURITY.md` with vulnerability reporting policy.
113
218
  - Added `prepare` script for GitHub-based installs.
219
+ - Extensive JSDoc coverage added across public methods and types.
package/README.md CHANGED
@@ -16,101 +16,64 @@ AbstractionKit is agnostic of:
16
16
 
17
17
 
18
18
  ## Features
19
- ### Safe Accounts
20
- - Built on ERC-4337 account abstraction
21
- - Passkeys Authentication for secure, passwordless access
22
- - Social Recovery to regain access easily
23
- - Multisig Support
24
- - Allowance Management for controlled spending limits
25
19
 
26
- ### Gas Abstraction with Paymasters
27
- - Full Gas Sponsorship for a seamless user experience
28
- - Support for ERC-20 Tokens as gas payment options
29
-
30
- ### Bundler Support
31
- - Compatibility with standard ERC-4337 Bundler Methods
32
-
33
- ### UserOperation Utilities
34
- - A complete toolkit to construct, sign, and send UserOperations, enabling smooth integration
20
+ - **Safe Accounts** with passkey authentication, social recovery, multisig, and allowance management
21
+ - **EIP-7702** support via `Calibur7702Account` and `Simple7702Account`
22
+ - **Gas abstraction** with sponsored UserOperations and ERC-20 gas payment via `CandidePaymaster`
23
+ - **Multichain signatures** via `SafeMultiChainSigAccountV1` (sign once, replay across chains)
24
+ - **Bundler client** compatible with standard ERC-4337 methods
25
+ - **EntryPoint v0.6, v0.7, v0.8, and v0.9** support with a version-safe account/UserOp mapping
35
26
 
36
27
  ## Docs
37
28
 
38
- For full detailed documentation visit our [docs page](https://docs.candide.dev/wallet/abstractionkit/introduction).
29
+ For full detailed documentation visit our [docs page](https://docs.candide.dev/wallet/abstractionkit/introduction).
39
30
 
40
31
  ## Installation
41
32
 
33
+ Requires Node.js 18 or later.
34
+
42
35
  ```bash
43
36
  npm install abstractionkit
44
37
  ```
45
38
 
46
- ## Quickstart
47
-
48
- ### Which version to use?
49
-
50
- | Class | EntryPoint | When to use |
51
- |---|---|---|
52
- | `SafeAccountV0_3_0` | v0.7 | Recommended for new projects |
53
- | `SafeAccountV0_2_0` | v0.6 | Legacy support |
54
-
55
- ### Safe Account
56
-
57
- AbstractionKit features the Safe Account. It uses the original Safe Singleton and adds ERC-4337 functionality using a fallback handler module. The contracts have been developed by the Safe Team. It has been audited by Ackee Blockchain. To learn more about the contracts and audits, visit [safe-global/safe-modules](https://github.com/safe-global/safe-modules/tree/main/modules/4337).
58
-
39
+ ### Upgrading to v0.3.0
59
40
 
60
- ```typescript
61
- import { SafeAccountV0_3_0 as SafeAccount } from "abstractionkit";
41
+ v0.3.0 is a major release. Two API changes are likely to break existing paymaster code:
62
42
 
63
- const ownerPublicAddress = "0xBdbc5FBC9cA8C3F514D073eC3de840Ac84FC6D31";
64
- const smartAccount = SafeAccount.initializeNewAccount([ownerPublicAddress]);
43
+ - `CandidePaymaster.createSponsorPaymasterUserOperation(...)` now takes `smartAccount` as the **first** argument: `(smartAccount, userOp, bundlerRpc, sponsorshipPolicyId?, overrides?)`.
44
+ - `CandidePaymasterContext` is no longer a separate argument. Pass it via `overrides.context` on `GasPaymasterUserOperationOverrides`.
65
45
 
66
- ```
67
- Then you can consume account methods:
68
- ```typescript
69
- const safeAddress = smartAccount.accountAddress;
70
- ```
46
+ See [CHANGELOG.md](./CHANGELOG.md) for the full list of new features, renames, type export changes, and fixes.
71
47
 
72
- ### Bundler
48
+ ## Quickstart
73
49
 
74
- Initialize a Bundler with a bundler RPC url. Get an API key from the [dashboard](https://dashboard.candide.dev), or use the public endpoint (no key required).
75
- ```typescript
76
- import { Bundler } from "abstractionkit";
50
+ ### Which account class to use?
77
51
 
78
- // Authenticated (get YOUR_API_KEY from https://dashboard.candide.dev)
79
- const bundlerRpc = "https://api.candide.dev/api/v3/11155111/YOUR_API_KEY";
52
+ | Class | EntryPoint | Account Type | When to use |
53
+ |---|---|---|---|
54
+ | `SafeAccountV0_3_0` | EP v0.7 | Safe (counterfactual) | Recommended for most new projects |
55
+ | `SafeAccountV1_5_0_M_0_3_0` | EP v0.7 | Safe v1.5.0 (counterfactual) | Safe v1.5.0 with EIP-7951 / Daimo P256 verifier for WebAuthn |
56
+ | `SafeAccountV0_2_0` | EP v0.6 | Safe (counterfactual) | Legacy support for EntryPoint v0.6 |
57
+ | `SafeMultiChainSigAccountV1` | EP v0.9 | Safe multichain | Sign once, replay across chains. |
58
+ | `Calibur7702Account` | EP v0.8 | EIP-7702 (Uniswap Calibur) | Upgrade an EOA in place. Supports EOA, P256, and WebAuthn keys |
59
+ | `Simple7702Account` | EP v0.8 | EIP-7702 (minimal) | Minimal reference EIP-7702 account |
60
+ | `Simple7702AccountV09` | EP v0.9 | EIP-7702 (minimal, parallel paymaster) | EntryPoint v0.9 with parallel paymaster signing |
80
61
 
81
- // Or public (no key required)
82
- // const bundlerRpc = "https://api.candide.dev/public/v3/11155111";
62
+ ### Endpoints
83
63
 
84
- const bundler = new Bundler(bundlerRpc);
85
- ```
86
- Then you can consume Bundler methods:
64
+ Candide hosts both bundler and paymaster under the same base URL. Get an API key from the [dashboard](https://dashboard.candide.dev), or use the public endpoint (rate-limited, no key required).
87
65
 
88
66
  ```typescript
89
- const entrypointAddresses = await bundler.supportedEntryPoints();
90
- ```
91
-
92
- ### Paymaster
93
- Initialize a Candide Paymaster with your RPC url. Get an API key from the [dashboard](https://dashboard.candide.dev).
94
- ```typescript
95
- import { CandidePaymaster } from "abstractionkit";
96
-
97
67
  // Authenticated
98
- const paymasterRpc = "https://api.candide.dev/api/v3/11155111/YOUR_API_KEY";
68
+ const rpc = "https://api.candide.dev/api/v3/11155111/YOUR_API_KEY";
99
69
 
100
70
  // Or public (no key required)
101
- // const paymasterRpc = "https://api.candide.dev/public/v3/11155111";
102
-
103
- const paymaster = new CandidePaymaster(paymasterRpc);
104
- ```
105
- Then you can consume Paymaster methods:
106
-
107
- ```typescript
108
- const supportedERC20TokensAndPaymasterMetadata = await paymaster.fetchSupportedERC20TokensAndPaymasterMetadata();
71
+ // const rpc = "https://api.candide.dev/public/v3/11155111";
109
72
  ```
110
73
 
111
74
  ## Recipes
112
75
 
113
- Copy-paste patterns for common tasks. Examples use `SafeAccountV0_3_0` (EntryPoint v0.7). For EntryPoint v0.6, replace with `SafeAccountV0_2_0`.
76
+ Copy paste patterns for common tasks. Examples use `SafeAccountV0_3_0` (EntryPoint v0.7). For EntryPoint v0.6, replace with `SafeAccountV0_2_0`.
114
77
 
115
78
  ### Send ETH from a new Safe account
116
79
 
@@ -120,7 +83,7 @@ import { SafeAccountV0_3_0 } from "abstractionkit";
120
83
  const ownerPublicAddress = "0xOwner";
121
84
  const ownerPrivateKey = "0xPrivateKey";
122
85
  const nodeRpc = "https://rpc.example.com";
123
- const bundlerRpc = "https://bundler.example.com";
86
+ const bundlerRpc = "https://api.candide.dev/api/v3/11155111/YOUR_API_KEY";
124
87
  const chainId = 11155111n; // Sepolia
125
88
 
126
89
  // Initialize new account (deploys on first UserOp)
@@ -169,7 +132,7 @@ const userOp = await smartAccount.createUserOperation(
169
132
  ```typescript
170
133
  import { SafeAccountV0_3_0, CandidePaymaster } from "abstractionkit";
171
134
 
172
- const paymaster = new CandidePaymaster("https://paymaster.example.com/rpc");
135
+ const paymaster = new CandidePaymaster("https://api.candide.dev/api/v3/11155111/YOUR_API_KEY");
173
136
 
174
137
  // Create the UserOp first (without paymaster)
175
138
  const userOp = await smartAccount.createUserOperation(
@@ -178,10 +141,14 @@ const userOp = await smartAccount.createUserOperation(
178
141
  bundlerRpc,
179
142
  );
180
143
 
181
- // Sponsor it sets paymaster fields and re-estimates gas
144
+ // Sponsor it. Sets paymaster fields and re-estimates gas.
145
+ // Note: as of v0.3.0, smartAccount is the first argument.
182
146
  const [sponsoredOp] = await paymaster.createSponsorPaymasterUserOperation(
147
+ smartAccount,
183
148
  userOp,
184
149
  bundlerRpc,
150
+ sponsorshipPolicyId,
151
+ // overrides (optional, includes context for parallel signing)
185
152
  );
186
153
 
187
154
  // Sign and send as usual
@@ -194,7 +161,7 @@ const response = await smartAccount.sendUserOperation(sponsoredOp, bundlerRpc);
194
161
  ```typescript
195
162
  import { SafeAccountV0_3_0, CandidePaymaster } from "abstractionkit";
196
163
 
197
- const paymaster = new CandidePaymaster("https://paymaster.example.com/rpc");
164
+ const paymaster = new CandidePaymaster("https://api.candide.dev/api/v3/11155111/YOUR_API_KEY");
198
165
  const gasTokenAddress = "0xERC20TokenAddress"; // must be supported by paymaster
199
166
 
200
167
  const userOp = await smartAccount.createUserOperation(
@@ -203,24 +170,48 @@ const userOp = await smartAccount.createUserOperation(
203
170
  bundlerRpc,
204
171
  );
205
172
 
206
- // Automatically prepends token approval + sets paymaster fields
173
+ // Automatically prepends token approval + sets paymaster fields.
174
+ // For tokens like USDT that require resetting allowance to 0 first, pass
175
+ // { resetApproval: true } in the overrides.
207
176
  const tokenOp = await paymaster.createTokenPaymasterUserOperation(
208
177
  smartAccount,
209
178
  userOp,
210
179
  gasTokenAddress,
211
180
  bundlerRpc,
181
+ // overrides (optional)
212
182
  );
213
183
 
214
184
  tokenOp.signature = smartAccount.signUserOperation(tokenOp, [ownerPrivateKey], chainId);
215
185
  const response = await smartAccount.sendUserOperation(tokenOp, bundlerRpc);
216
186
  ```
217
187
 
188
+ ### Pass paymaster context (sponsorship policy, parallel signing)
189
+
190
+ As of v0.3.0, `CandidePaymasterContext` is passed via the `overrides.context` field on `GasPaymasterUserOperationOverrides`. Previously it was a separate top level argument.
191
+
192
+ ```typescript
193
+ const [sponsoredOp] = await paymaster.createSponsorPaymasterUserOperation(
194
+ smartAccount,
195
+ userOp,
196
+ bundlerRpc,
197
+ sponsorshipPolicyId,
198
+ {
199
+ context: {
200
+ // For EntryPoint v0.9 parallel signing flows:
201
+ // signingPhase: "commit" | "finalize",
202
+ },
203
+ // gas overrides also live here:
204
+ callGasLimitPercentageMultiplier: 110,
205
+ },
206
+ );
207
+ ```
208
+
218
209
  ### Batch multiple transactions
219
210
 
220
211
  ```typescript
221
212
  import { SafeAccountV0_3_0, MetaTransaction } from "abstractionkit";
222
213
 
223
- // Pass an array of MetaTransactions automatically encoded via MultiSend
214
+ // Pass an array of MetaTransactions. Automatically encoded via MultiSend.
224
215
  const transactions: MetaTransaction[] = [
225
216
  { to: "0xRecipientA", value: 1000000000000000n, data: "0x" },
226
217
  { to: "0xRecipientB", value: 2000000000000000n, data: "0x" },
@@ -248,6 +239,98 @@ const newAccount = SafeAccountV0_3_0.initializeNewAccount(["0xOwnerAddress"]);
248
239
  // First UserOp will deploy it automatically
249
240
  ```
250
241
 
242
+ ### Calibur 7702: delegate an EOA and send a transfer
243
+
244
+ `Calibur7702Account` is Uniswap's EIP-7702 smart account. It upgrades a regular EOA in place so the same address becomes a programmable smart account on EntryPoint v0.8.
245
+
246
+ ```typescript
247
+ import {
248
+ Calibur7702Account,
249
+ createAndSignEip7702DelegationAuthorization,
250
+ } from "abstractionkit";
251
+
252
+ const eoaAddress = "0xYourEOA";
253
+ const privateKey = "0xYourPrivateKey";
254
+ const nodeRpc = "https://rpc.example.com";
255
+ const bundlerRpc = "https://api.candide.dev/api/v3/11155111/YOUR_API_KEY";
256
+ const chainId = 11155111n;
257
+
258
+ // The EOA address becomes the smart account address after delegation.
259
+ const account = new Calibur7702Account(eoaAddress);
260
+
261
+ // Create UserOp with EIP-7702 delegation (only required the first time).
262
+ const userOp = await account.createUserOperation(
263
+ [{ to: "0xRecipient", value: 1000000000000000n, data: "0x" }],
264
+ nodeRpc,
265
+ bundlerRpc,
266
+ { eip7702Auth: { chainId } },
267
+ );
268
+
269
+ // Sign the delegation authorization.
270
+ userOp.eip7702Auth = createAndSignEip7702DelegationAuthorization(
271
+ BigInt(userOp.eip7702Auth.chainId),
272
+ userOp.eip7702Auth.address,
273
+ BigInt(userOp.eip7702Auth.nonce),
274
+ privateKey,
275
+ );
276
+
277
+ // Sign and send.
278
+ userOp.signature = account.signUserOperation(userOp, privateKey, chainId);
279
+ const response = await account.sendUserOperation(userOp, bundlerRpc);
280
+ const receipt = await response.included();
281
+ ```
282
+
283
+ After the first UserOp deploys the delegation, subsequent UserOps no longer need `eip7702Auth`. Use `getDelegatedAddress(eoaAddress, nodeRpc)` to check delegation status.
284
+
285
+ ### Calibur 7702: register a WebAuthn passkey
286
+
287
+ ```typescript
288
+ import { Calibur7702Account } from "abstractionkit";
289
+
290
+ // Build a P256 key from the WebAuthn public key coordinates.
291
+ const webAuthnKey = Calibur7702Account.createWebAuthnP256Key(pubKeyX, pubKeyY);
292
+ const keyHash = Calibur7702Account.getKeyHash(webAuthnKey);
293
+
294
+ // Register with a 1-year expiration.
295
+ const registerTxs = Calibur7702Account.createRegisterKeyMetaTransactions(
296
+ webAuthnKey,
297
+ { expiration: Math.floor(Date.now() / 1000) + 86400 * 365 },
298
+ );
299
+
300
+ const userOp = await account.createUserOperation(registerTxs, nodeRpc, bundlerRpc);
301
+ userOp.signature = account.signUserOperation(userOp, privateKey, chainId);
302
+ const response = await account.sendUserOperation(userOp, bundlerRpc);
303
+ ```
304
+
305
+ ### Calibur 7702: sign a UserOp with a registered passkey
306
+
307
+ ```typescript
308
+ import { Calibur7702Account, createUserOperationHash } from "abstractionkit";
309
+
310
+ // Use a WebAuthn dummy signature for accurate gas estimation.
311
+ const dummySig = Calibur7702Account.createDummyWebAuthnSignature(keyHash);
312
+
313
+ const userOp = await account.createUserOperation(
314
+ [{ to: "0xRecipient", value: 0n, data: "0x" }],
315
+ nodeRpc,
316
+ bundlerRpc,
317
+ { dummySignature: dummySig },
318
+ );
319
+
320
+ // Compute the hash, sign with the passkey off-chain, then format the signature.
321
+ const userOpHash = createUserOperationHash(userOp, entryPointAddress, chainId);
322
+ userOp.signature = account.formatWebAuthnSignature(keyHash, {
323
+ authenticatorData,
324
+ clientDataJSON,
325
+ challengeIndex,
326
+ typeIndex,
327
+ r,
328
+ s, // P256 signature components
329
+ });
330
+
331
+ const response = await account.sendUserOperation(userOp, bundlerRpc);
332
+ ```
333
+
251
334
  ### Common error codes and solutions
252
335
 
253
336
  | Error Code | Meaning | Fix |
@@ -286,3 +369,5 @@ MIT
286
369
 
287
370
  * <a href='https://eips.ethereum.org/EIPS/eip-4337'>EIP-4337: Account Abstraction via Entry Point Contract specification </a>
288
371
  * <a href='https://safe.global/'>Safe Accounts, Modules, and SGP</a>
372
+ * <a href='https://github.com/Uniswap/calibur'>Uniswap Calibur Account</a>
373
+