abstractionkit 0.3.1 → 0.3.3
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 +130 -0
- package/README.md +17 -14
- package/dist/index.cjs +4010 -3466
- package/dist/index.d.cts +711 -579
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +711 -579
- package/dist/index.d.mts.map +1 -1
- package/dist/index.iife.js +4010 -3466
- package/dist/index.mjs +4008 -3468
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,135 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.3
|
|
4
|
+
|
|
5
|
+
### New Features
|
|
6
|
+
|
|
7
|
+
- **`TokenQuote` type** exported from the package root: `{ token: string; exchangeRate: bigint; tokenCost: bigint }`. Surfaces the exchange rate and maximum token cost the paymaster applied when paying gas with an ERC-20 token, so consumers can display the cost to users or log/meter it without a second RPC round-trip.
|
|
8
|
+
- **`CandidePaymaster.createTokenPaymasterUserOperation` and `Erc7677Paymaster.createPaymasterUserOperation` now return `tokenQuote`** alongside the UserOperation. Populated on the token-payment flow; absent on sponsored flows and on Candide's `signingPhase: "finalize"` path (no gas estimation → no cost computation).
|
|
9
|
+
- **`skipGasEstimation` flag on `createUserOperation` overrides** for `SafeAccount`, `Calibur7702Account`, and `Simple7702Account`. When set, the UserOperation is returned with a dummy signature and zero (or override-provided) gas limits, skipping the bundler's `eth_estimateUserOperationGas` roundtrip. Useful when gas estimation is run separately, for example by a paymaster sponsorship call that returns its own gas limits.
|
|
10
|
+
- **`SponsorInfo` type** exported from the package root. Represents the raw `{ name, icon? }` shape returned by paymasters per ERC-7677; `CandidePaymaster` normalizes it into the public `SponsorMetadata` shape.
|
|
11
|
+
|
|
12
|
+
### Breaking Changes
|
|
13
|
+
|
|
14
|
+
- **Three paymaster methods changed return shape** from a raw UserOperation / tuple to a named-field object. All now return `{ userOperation, tokenQuote? | sponsorMetadata? }`:
|
|
15
|
+
- `CandidePaymaster.createTokenPaymasterUserOperation` — returns `{ userOperation, tokenQuote? }` (was `SameUserOp<T>`).
|
|
16
|
+
- `CandidePaymaster.createSponsorPaymasterUserOperation` — returns `{ userOperation, sponsorMetadata? }` (was `[SameUserOp<T>, SponsorMetadata | undefined]`).
|
|
17
|
+
- `Erc7677Paymaster.createPaymasterUserOperation` — returns `{ userOperation, tokenQuote? }` (was `SameUserOp<T>`).
|
|
18
|
+
|
|
19
|
+
Migration:
|
|
20
|
+
```ts
|
|
21
|
+
// Before
|
|
22
|
+
const [sponsoredOp, sponsorMetadata] = await paymaster.createSponsorPaymasterUserOperation(...);
|
|
23
|
+
const tokenOp = await paymaster.createTokenPaymasterUserOperation(...);
|
|
24
|
+
const userOp = await erc7677.createPaymasterUserOperation(...);
|
|
25
|
+
|
|
26
|
+
// After
|
|
27
|
+
const { userOperation: sponsoredOp, sponsorMetadata } = await paymaster.createSponsorPaymasterUserOperation(...);
|
|
28
|
+
const { userOperation: tokenOp, tokenQuote } = await paymaster.createTokenPaymasterUserOperation(...);
|
|
29
|
+
const { userOperation, tokenQuote } = await erc7677.createPaymasterUserOperation(...);
|
|
30
|
+
```
|
|
31
|
+
- **`CandidePaymasterContext` moved back to a dedicated parameter** on `CandidePaymaster.createSponsorPaymasterUserOperation` and `createTokenPaymasterUserOperation`. The `context` field was removed from `GasPaymasterUserOperationOverrides`, and `context` is now the second-to-last argument (optional) on both methods, with `overrides` as the last argument. Migration:
|
|
32
|
+
```ts
|
|
33
|
+
// Before (0.3.2): context nested inside overrides
|
|
34
|
+
await paymaster.createSponsorPaymasterUserOperation(
|
|
35
|
+
smartAccount, userOp, bundlerRpc, sponsorshipPolicyId,
|
|
36
|
+
{ context: { signingPhase: "commit" }, maxFeePerGasMultiplier: 110n },
|
|
37
|
+
);
|
|
38
|
+
await paymaster.createTokenPaymasterUserOperation(
|
|
39
|
+
smartAccount, userOp, tokenAddress, bundlerRpc,
|
|
40
|
+
{ context: { signingPhase: "commit" }, maxFeePerGasMultiplier: 110n },
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// After (0.3.3): context is a dedicated argument
|
|
44
|
+
await paymaster.createSponsorPaymasterUserOperation(
|
|
45
|
+
smartAccount, userOp, bundlerRpc, sponsorshipPolicyId,
|
|
46
|
+
{ signingPhase: "commit" },
|
|
47
|
+
{ maxFeePerGasMultiplier: 110n },
|
|
48
|
+
);
|
|
49
|
+
// For createTokenPaymasterUserOperation, `context` is optional: the method
|
|
50
|
+
// always derives `context.token` from the `tokenAddress` argument, so pass
|
|
51
|
+
// `undefined` unless you need other context fields (e.g. `signingPhase`).
|
|
52
|
+
await paymaster.createTokenPaymasterUserOperation(
|
|
53
|
+
smartAccount, userOp, tokenAddress, bundlerRpc,
|
|
54
|
+
undefined,
|
|
55
|
+
{ maxFeePerGasMultiplier: 110n },
|
|
56
|
+
);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Bug Fixes
|
|
60
|
+
|
|
61
|
+
- **`CandidePaymaster` now parses sponsor info per ERC-7677.** Paymasters return sponsor info under `sponsor: { name, icon? }` (singular `icon`); the previous code read a non-standard `sponsorMetadata` key and therefore always returned `undefined`. The raw response is now normalized into the public `SponsorMetadata` shape (`{ name, description, url, icons[] }`).
|
|
62
|
+
|
|
63
|
+
## 0.3.2
|
|
64
|
+
|
|
65
|
+
### New Features
|
|
66
|
+
|
|
67
|
+
- **`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:
|
|
68
|
+
- Safe accounts (multi-signer): `signUserOperationWithSigners(op, signers[], chainId)` — plural.
|
|
69
|
+
- Simple7702 / Calibur (single signer): `signUserOperationWithSigner(op, signer, chainId)` — singular.
|
|
70
|
+
|
|
71
|
+
Call-site is one line:
|
|
72
|
+
```ts
|
|
73
|
+
import { fromViem } from "abstractionkit"
|
|
74
|
+
userOp.signature = await safe.signUserOperationWithSigners(
|
|
75
|
+
userOp, [fromViem(account)], chainId,
|
|
76
|
+
)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
- **`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.
|
|
80
|
+
- **`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.
|
|
81
|
+
- **`SignHashFn` / `SignTypedDataFn` / `TypedData` / `SigningScheme` / `SignContext` / `MultiOpSignContext` types** exported from the package root for implementers of custom signers.
|
|
82
|
+
- **`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`.
|
|
83
|
+
- **`SafeMultiChainSigAccountV1.signUserOperationsWithSigners`**: new async multi-op variant that signs a Merkle-rooted bundle of UserOperations with a single signature across chains, using `ExternalSigner[]`.
|
|
84
|
+
|
|
85
|
+
### Breaking Changes
|
|
86
|
+
|
|
87
|
+
> **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.
|
|
88
|
+
|
|
89
|
+
- **`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:
|
|
90
|
+
```ts
|
|
91
|
+
// Before:
|
|
92
|
+
const sig = SafeAccount.baseSignSingleUserOperation(
|
|
93
|
+
op, [pk], chainId,
|
|
94
|
+
SafeAccountV0_3_0.DEFAULT_ENTRYPOINT_ADDRESS,
|
|
95
|
+
SafeAccountV0_3_0.DEFAULT_SAFE_4337_MODULE_ADDRESS,
|
|
96
|
+
);
|
|
97
|
+
// After:
|
|
98
|
+
const sig = safeV3.signUserOperation(op, [pk], chainId);
|
|
99
|
+
```
|
|
100
|
+
`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.
|
|
101
|
+
- **`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.).
|
|
102
|
+
- **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:
|
|
103
|
+
```ts
|
|
104
|
+
// Before:
|
|
105
|
+
const signer = async ({ userOpHash }) => ({
|
|
106
|
+
signature: wallet.signingKey.sign(userOpHash).serialized,
|
|
107
|
+
});
|
|
108
|
+
userOp.signature = await account.signUserOperationWithSigner(userOp, signer, chainId);
|
|
109
|
+
|
|
110
|
+
// After — Simple7702 / Calibur (single signer):
|
|
111
|
+
import { fromEthersWallet } from "abstractionkit";
|
|
112
|
+
userOp.signature = await account.signUserOperationWithSigner(
|
|
113
|
+
userOp, fromEthersWallet(wallet), chainId,
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
// After — Safe accounts (multi-signer, plural method name):
|
|
117
|
+
userOp.signature = await safe.signUserOperationWithSigners(
|
|
118
|
+
userOp, [fromEthersWallet(wallet)], chainId,
|
|
119
|
+
);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Migration: Signing with a raw private key
|
|
123
|
+
|
|
124
|
+
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:
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
import { fromPrivateKey } from "abstractionkit";
|
|
128
|
+
userOp.signature = await safe.signUserOperationWithSigners(
|
|
129
|
+
userOp, [fromPrivateKey(pk)], chainId,
|
|
130
|
+
);
|
|
131
|
+
```
|
|
132
|
+
|
|
3
133
|
## 0.3.1
|
|
4
134
|
|
|
5
135
|
### New Features
|
package/README.md
CHANGED
|
@@ -38,10 +38,10 @@ npm install abstractionkit
|
|
|
38
38
|
|
|
39
39
|
### Upgrading to v0.3.0
|
|
40
40
|
|
|
41
|
-
v0.3.0 is a major release.
|
|
41
|
+
v0.3.0 is a major release. The following API changes are likely to break existing paymaster code:
|
|
42
42
|
|
|
43
|
-
- `CandidePaymaster.createSponsorPaymasterUserOperation(...)` now takes `smartAccount` as the **first** argument: `(smartAccount, userOp, bundlerRpc, sponsorshipPolicyId?, overrides?)`.
|
|
44
|
-
- `
|
|
43
|
+
- `CandidePaymaster.createSponsorPaymasterUserOperation(...)` now takes `smartAccount` as the **first** argument: `(smartAccount, userOp, bundlerRpc, sponsorshipPolicyId?, context?, overrides?)`.
|
|
44
|
+
- `CandidePaymaster.createTokenPaymasterUserOperation(...)` adds a dedicated `context?` argument before `overrides?`: `(smartAccount, userOp, tokenAddress, bundlerRpc, context?, overrides?)`. Callers that previously passed `overrides` positionally at argument 5 must insert `undefined` (or an explicit context) so `overrides` shifts to argument 6.
|
|
45
45
|
|
|
46
46
|
See [CHANGELOG.md](./CHANGELOG.md) for the full list of new features, renames, type export changes, and fixes.
|
|
47
47
|
|
|
@@ -143,12 +143,13 @@ const userOp = await smartAccount.createUserOperation(
|
|
|
143
143
|
|
|
144
144
|
// Sponsor it. Sets paymaster fields and re-estimates gas.
|
|
145
145
|
// Note: as of v0.3.0, smartAccount is the first argument.
|
|
146
|
-
const
|
|
146
|
+
const { userOperation: sponsoredOp, sponsorMetadata } = await paymaster.createSponsorPaymasterUserOperation(
|
|
147
147
|
smartAccount,
|
|
148
148
|
userOp,
|
|
149
149
|
bundlerRpc,
|
|
150
150
|
sponsorshipPolicyId,
|
|
151
|
-
//
|
|
151
|
+
// context (optional — e.g. { signingPhase: "commit" } for EP v0.9 parallel signing)
|
|
152
|
+
// overrides (optional — gas limits and multipliers)
|
|
152
153
|
);
|
|
153
154
|
|
|
154
155
|
// Sign and send as usual
|
|
@@ -173,12 +174,14 @@ const userOp = await smartAccount.createUserOperation(
|
|
|
173
174
|
// Automatically prepends token approval + sets paymaster fields.
|
|
174
175
|
// For tokens like USDT that require resetting allowance to 0 first, pass
|
|
175
176
|
// { resetApproval: true } in the overrides.
|
|
176
|
-
|
|
177
|
+
// `tokenQuote` carries the exchange rate and max token cost used for the approval.
|
|
178
|
+
const { userOperation: tokenOp, tokenQuote } = await paymaster.createTokenPaymasterUserOperation(
|
|
177
179
|
smartAccount,
|
|
178
180
|
userOp,
|
|
179
181
|
gasTokenAddress,
|
|
180
182
|
bundlerRpc,
|
|
181
|
-
//
|
|
183
|
+
// context (optional)
|
|
184
|
+
// overrides (optional — gas limits, multipliers, resetApproval)
|
|
182
185
|
);
|
|
183
186
|
|
|
184
187
|
tokenOp.signature = smartAccount.signUserOperation(tokenOp, [ownerPrivateKey], chainId);
|
|
@@ -187,20 +190,20 @@ const response = await smartAccount.sendUserOperation(tokenOp, bundlerRpc);
|
|
|
187
190
|
|
|
188
191
|
### Pass paymaster context (sponsorship policy, parallel signing)
|
|
189
192
|
|
|
190
|
-
|
|
193
|
+
`CandidePaymasterContext` is passed as its own argument, separate from gas overrides.
|
|
191
194
|
|
|
192
195
|
```typescript
|
|
193
|
-
const
|
|
196
|
+
const { userOperation: sponsoredOp } = await paymaster.createSponsorPaymasterUserOperation(
|
|
194
197
|
smartAccount,
|
|
195
198
|
userOp,
|
|
196
199
|
bundlerRpc,
|
|
197
200
|
sponsorshipPolicyId,
|
|
198
201
|
{
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
// gas overrides
|
|
202
|
+
// For EntryPoint v0.9 parallel signing flows:
|
|
203
|
+
// signingPhase: "commit" | "finalize",
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
// gas overrides:
|
|
204
207
|
callGasLimitPercentageMultiplier: 110,
|
|
205
208
|
},
|
|
206
209
|
);
|