abstractionkit 0.3.4 → 0.3.5

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,5 +1,78 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.5
4
+
5
+ ### New Features
6
+
7
+ - **EIP-712 typed-data signing for `Simple7702Account` / `Simple7702AccountV09`**: `signUserOperationWithSigner` now accepts `signTypedData`-only signers (JSON-RPC wallets, viem `WalletClient`) in addition to existing `signHash` signers. The v0.8/v0.9 `userOpHash` IS the EIP-712 digest of `PackedUserOperation` under the EntryPoint's domain, so both schemes produce signatures that validate against the same hash. Throws on EntryPoint v0.7 (different signing scheme). Adds `getUserOperationEip712TypedData(userOp, chainId)` on `BaseSimple7702Account` as the lower-level escape hatch for integrators driving `signTypedData` with their own primitive (HSM, MPC, custom wallet abstraction).
8
+ ```ts
9
+ // Path A: signTypedData-only signer
10
+ const signer = {
11
+ address: eoaAddress,
12
+ signTypedData: async (td) => walletClient.signTypedData(td),
13
+ };
14
+ userOp.signature = await account.signUserOperationWithSigner(userOp, signer, chainId);
15
+
16
+ // Path B: drive signTypedData yourself
17
+ const td = account.getUserOperationEip712TypedData(userOp, chainId);
18
+ userOp.signature = await wallet.signTypedData(td.domain, td.types, td.message);
19
+ ```
20
+ - **WebAuthn pubkey JSON helpers + assertion normalizer** (3 new exports from package root):
21
+ - `pubkeyCoordinatesToJson(pubkey)` / `pubkeyCoordinatesFromJson(input)`: bigint-safe JSON round-trip for `{ x, y }` coordinates. Hex on the wire, canonical `{ x: bigint, y: bigint }` after parse. `fromJson` accepts a JSON string or a pre-parsed object, and either hex or decimal string coords.
22
+ - `webauthnSignatureFromAssertion(response)`: turns a structural assertion shape (browser `AuthenticatorAssertionResponse`, `ox/WebAuthnP256` sign output, or `@simplewebauthn/browser`) into the `WebauthnSignatureData` that `fromSafeWebauthn` and `createWebAuthnSignature` already accept. Replaces the ~13-line parser pipeline every Safe-passkeys consumer was writing in their `getAssertion` callback.
23
+ - **`fromSafeWebauthn` adapter**: package-root factory that produces an `ExternalSigner` from a WebAuthn credential, ready to pass into `safe.signUserOperationWithSigners(op, [signer], chainId)`. Hides three Safe-specific concerns: address routing (the WebAuthn shared signer for the deployment UserOp, the deterministic verifier-proxy address derived from `(x, y)` afterward), the `type: "contract"` tag, and the Safe-specific signature encoding. Required `accountClass` parameter (the same Safe subclass used at `initializeNewAccount`) sources the Passkey module defaults — `SafeAccountV0_2_0` / `SafeAccountV0_3_0` for v0.2.0 (FCL P256), `SafeMultiChainSigAccountV1` for v0.2.1 (Daimo P256 + RIP-7951). Picking the wrong class would derive an address that isn't an on-chain owner and the bundler would reject with a generic "Invalid UserOp signature" (`GS026` on-chain), so the param is required to surface this choice at compile time. Caller supplies a `getAssertion(challenge: Uint8Array) => Promise<WebauthnSignatureData>` callback that runs `navigator.credentials.get(...)` (browser) or an equivalent native bridge — the SDK doesn't import `navigator` itself, so the adapter stays environment-agnostic. Pass `expectedSigners: [{ x, y }]` to `createUserOperation` so the bundler estimates verification gas against the WebAuthn dummy signature (~400 bytes) instead of the EOA dummy (~65 bytes); without it, the real signed UserOp is rejected at submit. The `FromSafeWebauthnParams` and `WebauthnAssertionFetcher` types are also exported from the package root.
24
+ ```ts
25
+ import { fromSafeWebauthn, SafeAccountV0_3_0 } from "abstractionkit";
26
+
27
+ let userOperation = await safe.createUserOperation(
28
+ transactions, nodeUrl, bundlerUrl,
29
+ { expectedSigners: [{ x, y }] },
30
+ );
31
+ const signer = fromSafeWebauthn({
32
+ publicKey: { x, y },
33
+ isInit: userOperation.nonce === 0n,
34
+ accountClass: SafeAccountV0_3_0, // SafeMultiChainSigAccountV1 for multi-chain
35
+ getAssertion: async (challenge) => {
36
+ const assertion = await navigator.credentials.get({
37
+ publicKey: { challenge, rpId, allowCredentials, userVerification },
38
+ });
39
+ return {
40
+ authenticatorData: assertion.response.authenticatorData,
41
+ clientDataFields: extractClientDataFields(assertion.response),
42
+ rs: extractSignature(assertion.response),
43
+ };
44
+ },
45
+ });
46
+ userOperation.signature = await safe.signUserOperationWithSigners(
47
+ userOperation, [signer], chainId,
48
+ );
49
+ ```
50
+ - **`ExternalSigner.type` field** (`"ecdsa" | "contract"`, optional, defaults to `"ecdsa"`). When `"contract"`, the signer's signature is encoded as a dynamic-length EIP-1271 contract-signature segment instead of a raw 65-byte ECDSA blob. Lets a single `signUserOperationWithSigners([...])` call mix ECDSA owners and contract-signature owners (WebAuthn, smart-contract owners) in the same Safe multisig batch. Account-agnostic: ignored by non-Safe accounts that don't model contract signatures. `fromSafeWebauthn` sets this internally.
51
+
52
+ ### Breaking Changes
53
+
54
+ - **`UserOperationToSignWithOverrides.overrides` is split into `options` and `webAuthnSignatureOverrides`.** The previous kitchen-sink `overrides` field carried both per-call signing options (timing, multi-chain, module address) and WebAuthn-specific encoding overrides (verifier addresses, init flag); these now live on dedicated fields. Affects callers of `SafeMultiChainSigAccountV1.signUserOperations` and `signUserOperationsWithSigners`. Migration:
55
+ ```ts
56
+ // Before
57
+ await safe.signUserOperations(
58
+ [{
59
+ userOperation, chainId, validAfter, validUntil,
60
+ overrides: { isInit: true, webAuthnSharedSigner, safe4337ModuleAddress },
61
+ }],
62
+ [pk],
63
+ );
64
+
65
+ // After
66
+ await safe.signUserOperations(
67
+ [{
68
+ userOperation, chainId, validAfter, validUntil,
69
+ options: { safe4337ModuleAddress },
70
+ webAuthnSignatureOverrides: { isInit: true, webAuthnSharedSigner },
71
+ }],
72
+ [pk],
73
+ );
74
+ ```
75
+
3
76
  ## 0.3.4
4
77
 
5
78
  ### New Features