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 +177 -71
- package/README.md +158 -73
- package/dist/index.cjs +848 -39
- package/dist/index.d.cts +231 -60
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +231 -60
- package/dist/index.d.mts.map +1 -1
- package/dist/index.iife.js +848 -39
- package/dist/index.mjs +844 -40
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,113 +1,219 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.3.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
####
|
|
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
|
-
|
|
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`,
|
|
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
|
-
####
|
|
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
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
- **`
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
|
|
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
|
-
|
|
168
|
+
- **`CALIBUR_UNISWAP_V1_0_0_SINGLETON_ADDRESS`** and **`CALIBUR_CANDIDE_V0_1_0_SINGLETON_ADDRESS`** exported as constants.
|
|
67
169
|
|
|
68
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
-
|
|
91
|
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
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
|
-
-
|
|
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
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
64
|
-
|
|
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
|
-
|
|
48
|
+
## Quickstart
|
|
73
49
|
|
|
74
|
-
|
|
75
|
-
```typescript
|
|
76
|
-
import { Bundler } from "abstractionkit";
|
|
50
|
+
### Which account class to use?
|
|
77
51
|
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
82
|
-
// const bundlerRpc = "https://api.candide.dev/public/v3/11155111";
|
|
62
|
+
### Endpoints
|
|
83
63
|
|
|
84
|
-
|
|
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
|
|
68
|
+
const rpc = "https://api.candide.dev/api/v3/11155111/YOUR_API_KEY";
|
|
99
69
|
|
|
100
70
|
// Or public (no key required)
|
|
101
|
-
// const
|
|
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
|
|
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://
|
|
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://
|
|
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
|
|
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://
|
|
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
|
|
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
|
+
|