Skip to content

chore(release): 0.4.3 - #245

Open
Sednaoui wants to merge 8 commits into
mainfrom
dev
Open

Sednaoui wants to merge 8 commits into
mainfrom
dev

Conversation

@Sednaoui

@Sednaoui Sednaoui commented Oct 2, 2026 •

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features
    • Added offline token-quote decoding for supported Candide and Pimlico paymaster operations, including token cost and validity details when available.
    • Added Safe account decoding of paymaster-directed token approvals, including approvals within recognized MultiSend transactions.
  • Bug Fixes
    • Corrected the default module address used by Safe v0.9 EIP-712 helpers.
    • Standardized token-cost calculations across paymaster types.
  • API Changes
    • Removed deprecated or unused public declarations.

* feat(paymaster): public Erc7677Paymaster.fetchTokenQuote and shared token cost helper

Expose fetchTokenQuote(tokenAddress, entrypoint) on Erc7677Paymaster for the
Candide and Pimlico providers, and add calculateUserOperationErc20TokenCost so
the token cost math and its min-of-one floor live in one place, used by both
paymaster classes.

* fix(paymaster): wrap fetchTokenQuote transport and RPC failures as PAYMASTER_ERROR

* feat(utils): accept v0.8 and v0.9 UserOperations in calculateUserOperationErc20TokenCost

* refactor(utils): keep calculateUserOperationErc20TokenCost internal

The shared helper still backs every token cost computation, but it is no longer
part of the public API. Co-signers will read a finished operation's cost through
a dedicated decoder instead.

* fix(paymaster): fetchTokenQuote wraps non-PAYMASTER_ERROR AbstractionKitErrors

Only rethrow AbstractionKitErrors already coded PAYMASTER_ERROR; anything else,
such as an error from a custom transport, is wrapped so fetchTokenQuote keeps
its documented PAYMASTER_ERROR contract.

* refactor(paymaster): drop the public fetchTokenQuote

createPaymasterUserOperation already returns the tokenQuote before signing, and
decodeTokenQuote covers co-signers, so a standalone rate lookup adds public API
without a use case. Keeps the shared token cost helper.
* feat(safe): decodeTokenPaymasterApprovals to read the paymaster approval from a UserOperation

Returns every ERC-20 approve in a Safe UserOperation's batch whose spender is
the operation's own paymaster, so signers who did not build the operation can
see the token cap they are signing without the original TokenQuote.

* fix(safe): only decode approvals from a delegatecall to the expected MultiSend

A delegatecall runs the target's code in the Safe's context, so a MultiSend-shaped
payload sent to any other contract could report approvals that never execute.
decodeTokenPaymasterApprovals now throws BAD_DATA unless the delegatecall target is
the MultiSend contract (overridable via overrides.multisendContractAddress).

* refactor(safe): expose decodeTokenPaymasterApprovals as an account hook

Mirror the prepend convention: decodeTokenPaymasterApprovalsStatic holds the
logic and the instance method decodeTokenPaymasterApprovals implements the new
DecodeTokenPaymasterApprovalsAccount interface, so paymaster-side code can read
approvals from any account that supports it.

* fix(safe): accept every official Safe MultiSend deployment when decoding approvals

Operations built by other SDKs delegatecall MultiSendCallOnly (v1.3.0, v1.4.1,
v1.5.0) rather than the SDK's default MultiSend, and were rejected. Accept the
official deployments listed in safe-global/safe-deployments; the override now
adds a custom deployment instead of replacing the default.

* docs(safe): state that decoded approvals are matched by selector, not verified ERC-20

* fix(safe): reject batches with inner delegatecalls when decoding approvals

An inner delegatecall runs arbitrary code in the Safe's context and could
overwrite the paymaster allowance after a reported approve. Also let the
DecodeTokenPaymasterApprovalsAccount hook take the MultiSend override.

* fix(safe): report malformed approve calldata as BAD_DATA

A batch entry with the approve selector but truncated arguments threw a raw
ABI decode error. Wrap it in AbstractionKitError BAD_DATA with the original
error as cause and the call's target as context.

* feat(paymaster): decodeTokenQuote reads a finished operation's token payment offline

Co-signers who did not build an operation can recover what it commits to pay:
the paymaster's signed exchange rate and validity window from its paymaster
data, and the allowance from the ERC-20 approval in callData, with no RPC.
Supports Candide's (EntryPoint v0.6 to v0.9) and Pimlico's (v0.6 to v0.8)
token paymasters, identified by their deployed addresses. maxTokenCost bounds
what each paymaster contract can charge, including its post-operation overhead.

Tests run against 24 real token-paid operations from mainnet and Sepolia, each
checked against the amount the paymaster actually charged.

* docs(paymaster): note that Candide's decoded token comes from the unverified approval

* fix(paymaster): reject ambiguous Candide token approvals and pass the MultiSend override

Candide's paymaster data names the token by slot, so approvals of more than one
token to the paymaster leave the paid token undetermined offline; throw instead
of picking the last. Forward overrides.multisendContractAddress to the account's
approval decoder.

* refactor(safe): keep decodeTokenPaymasterApprovals as the instance hook only

Drop decodeTokenPaymasterApprovalsStatic and move its logic into the instance
method that decodeTokenQuote calls, documenting it as the low-level account
hook behind decodeTokenQuote.

* refactor(paymaster): expose decodeTokenQuote as a static on the paymaster classes

Erc7677Paymaster.decodeTokenQuote and CandidePaymaster.decodeTokenQuote replace
the root-level function, next to createPaymasterUserOperation where developers
look for token payment features. Static because decoding needs no paymaster
URL or state, and it works on operations built by either class.

* docs(paymaster): explain why the multi-token approval check covers both providers
CALIBUR_CANDIDE_V0_1_0_SINGLETON_ADDRESS pointed at an unofficial, unaudited
Calibur deployment. Calibur7702Account defaults to Uniswap's official
singleton and never used it.
#241)

getUserOperationEip712Data_V9 fell back to 0xee8005d7..., and the JSDoc on
both V9 helpers named old addresses. Neither has code outside Sepolia, so
callers relying on the default hashed against the wrong verifying contract
and failed with AA24. Default to 0x22939E83... instead, the address
SafeMultiChainSigAccountV1 uses.

Fixes #239
…ASH code (#243)

The PaymasterMetadataV6/V7/V8 and SupportedERC20TokensAndMetadata* version
aliases were never exported from the package entry point and have no
internal users. BundlerErrorCode.INVALID_USEROPERATION_HASH has not been
produced since #219 remapped -32601 to METHOD_NOT_FOUND.

Also fix the Calibur paymasterFields JSDoc link, which named the old
ExperimentalAllowAllPaymaster class.
@coderabbitai

coderabbitai Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Essentials

Run ID: ce575e2b-5cb2-4b5a-ad8c-b948353849c9

📥 Commits

Reviewing files that changed from the base of the PR and between abd8b59 and 8d88f14.

📒 Files selected for processing (2)
  • src/account/Safe/SafeAccount.ts
  • test/safe/decodeTokenPaymasterApprovals.test.js

Included review availability: This review used your included allowance. 1 included review remains after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.


📝 Walkthrough

Walkthrough

Version 0.4.3 adds offline token-quote decoding for supported Candide and Pimlico UserOperations. It adds Safe approval extraction, shares token-cost calculation across paymaster classes, changes the v0.9 Safe module default, and removes several API declarations.

Changes

Token Quote Decoding

Layer / File(s) Summary
Safe paymaster approval extraction
src/types.ts, src/paymaster/types.ts, src/account/Safe/*, test/safe/*
Adds a Safe method to extract paymaster-matching approvals from direct calls and supported MultiSend batches. Tests cover ordering, delegatecall restrictions, custom MultiSend addresses, and malformed data.
Offline quote decoding and paymaster APIs
src/paymaster/decodeTokenQuote.ts, src/paymaster/CandidePaymaster.ts, src/paymaster/Erc7677Paymaster.ts, src/abstractionkit.ts, test/paymaster/*
Adds offline quote decoding for supported Candide and Pimlico paymasters. The result includes quote fields such as token, approval amount, exchange rate, maximum token cost, and validity window. Tests and fixtures cover supported layouts, modes, overrides, and errors.
Shared token-cost calculation
src/utils.ts, src/paymaster/CandidePaymaster.ts, src/paymaster/Erc7677Paymaster.ts, CHANGELOG.md
Adds a shared helper to calculate token cost from maximum gas cost and exchange rate. Both paymaster classes use it.
API, defaults, and release updates
src/account/Safe/SafeAccount.ts, src/constants.ts, src/errors.ts, src/types.ts, src/abstractionkit.ts, src/account/Calibur/types.ts, test/signer/signer.test.js, package.json, SECURITY.md, CHANGELOG.md
Changes the v0.9 Safe module default and its test. Removes the listed deprecated or unused declarations, updates release metadata to 0.4.3, and corrects a Calibur documentation example.

Priority: ⬇️ Low

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant CandidePaymaster
  participant decodeTokenQuote
  participant SafeAccount
  Client->>CandidePaymaster: Call decodeTokenQuote with account and operation
  CandidePaymaster->>decodeTokenQuote: Forward operation and overrides
  decodeTokenQuote->>SafeAccount: Decode paymaster-directed approvals
  SafeAccount-->>decodeTokenQuote: Return matching approvals
  decodeTokenQuote-->>CandidePaymaster: Return quote or null
  CandidePaymaster-->>Client: Return quote or null
Loading

Suggested reviewers: sherifahmed990

Merge Risk: ⚪ Minimal · up to 8d88f

The reviewed Safe approval-decoding changes have no identified merge-blocking issue. Normal checks remain appropriate before merging.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request has no description. It does not include the required Summary, Test, or Risk / Compatibility sections. Add a description with the required headings: Summary, Test, and Risk / Compatibility. Complete each section with the release changes, validation performed, and compatibility or risk information.
Docstring Coverage ⚠️ Warning Docstring coverage is 56.25% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 16 functions across 13 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately identifies this changeset as the 0.4.3 release. It is concise and related to the package version, changelog, and release metadata updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
  • Fix all pre-merge checks with AI
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


A rabbit reads the quote in flight,
Through Safe calls parsed just right.
Candide, Pimlico share the page,
Token costs align by gauge.
Release notes turn a gentle green,
The bunny hops through code pristine.

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: abd8b599bf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/account/Safe/SafeAccount.ts Outdated
decodeTokenPaymasterApprovals let a raw ABI decode error escape when a known
MultiSend was delegatecalled with a truncated or malformed bytes argument. Wrap
it in AbstractionKitError BAD_DATA with the original error as cause and the
MultiSend target as context, as documented.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant