Skip to content

release: to prod#1465

Merged
suisuss merged 21 commits into
prodfrom
staging
Jun 5, 2026
Merged

release: to prod#1465
suisuss merged 21 commits into
prodfrom
staging

Conversation

@eskp

@eskp eskp commented Jun 5, 2026

Copy link
Copy Markdown

Summary

Promote the following merged PRs from staging to prod:

Risk callouts

  • Database migrations: none
  • Deploy values / secrets: deploy/keeperhub/prod/values.yaml, deploy/keeperhub/staging/values.yaml -- removes the Pimlico gas-sponsorship env vars (PIMLICO_API_KEY, PIMLICO_BASE_URL, SIMPLE_ACCOUNT_7702_ADDRESS) as part of the Turnkey migration (refactor(web3): migrate gas sponsorship from Pimlico to Turnkey (KEEP-464) #1221). Confirm the Turnkey-side config/secrets are provisioned in prod before rollout.
  • Dependency changes: none

Post-deploy verification

joelorzet and others added 21 commits May 11, 2026 19:39
…(KEEP-464)

Switch the gas sponsorship pipeline from ERC-4337 + Pimlico to Turnkey's
native Transaction Management (Gas Station). Turnkey signs and sponsors
the underlying EVM transaction in a single ethSendTransaction activity,
so the whole UserOperation pipeline goes away on the sponsored path.

Adds turnkey-sponsorship-config (chain allowlist: ETH, Base, Polygon
mainnet + their testnets, Arbitrum probed at runtime; drops Optimism)
and turnkey-sponsored-tx (wraps ethSendTransaction + polls
getSendTransactionStatus for the broadcast txHash). sponsored-client
becomes a thin Turnkey-wallet preflight; sponsored-transaction-manager
calls the wrapper and continues to meter on-chain gasUsed against
gas-credit balances.

Deletes pimlico-config, sponsored-fee-clamp (Turnkey fills gas itself,
no KEEP-394 fee-inversion clamp needed), eip7702-delegation (no inline
4337 delegation), and the Para viem-account adapter (the sponsored path
was its only remaining caller; Para wallets fall through to direct
signing via the existing wallet-helpers guard).
Update the four web3 step files that gate sponsorship on chain support
to import isSponsorshipSupported from turnkey-sponsorship-config instead
of the deleted pimlico-config. Refresh inline comments to describe
Turnkey Gas Station rather than ERC-4337 / Pimlico bundler mechanics.
The KEEP-137 private-mempool exclusion still applies because Turnkey
broadcasts via its own infrastructure, not through Flashbots.
Add a one-line note under the gas-sponsorship credits bar listing the
networks Turnkey Gas Station covers today: Ethereum, Base, Polygon,
Arbitrum (plus Sepolia, Base Sepolia, and Polygon Amoy testnets). Lets
users see at a glance which chains are eligible for sponsorship and
which fall back to wallet-paid gas.
Rewrite sponsored-client and sponsored-transaction-manager unit tests
to mock the Turnkey config and ethSendTransaction wrapper instead of
the Pimlico client and Para viem adapter. Update approve-token to point
at turnkey-sponsorship-config. Delete sponsored-fee-clamp tests (the
fee-clamp module is gone) and the eip7702-spike integration test, which
exercised the Pimlico ERC-4337 path that no longer exists.
… table

Gas-credits card on the billing status page gets a dedicated
"Sponsored networks" section under the usage bar, with mainnet badges
(Ethereum, Base, Polygon, Arbitrum) always visible and an Info-icon
tooltip listing testnets and the off-list fallback behavior.

Plan comparison table gains a "Sponsored gas" row right after
"Triggers". The Info-icon tooltip beside the label lists the Turnkey
mainnets and testnets; cell values show the per-plan monthly USD cap
(resolved from the live gasCreditCaps env overrides, falling back to
PLANS defaults), so the comparison table and the per-plan cards stay
in sync.
Turnkey support confirmed Ethereum, Base, Polygon, and Arbitrum on
mainnet for sponsored EVM transactions. Drop the speculative hedging
from the chain-allowlist comment and from the runtime cast at the
ethSendTransaction call site. The cast itself stays in place because
the @turnkey/sdk-server v5.2.0 CAIP-2 enum has not been regenerated to
include eip155:42161; once it does, the cast can be removed.
Use the structured revert info Turnkey returns on getSendTransactionStatus
to give users the real revert reason and stop falling back to direct
signing when the underlying call has already failed on-chain.

A new SponsoredTxRevertError carries the txHash, sendTransactionStatusId,
and the v1RevertChainEntry list from Turnkey. The polling wrapper raises
this error only when a txHash is present (the call is already mined);
pre-broadcast failures (policy denial, gas-cap exhaustion, simulation
errors) still yield null so callers fall through to direct signing as
before.

formatRevertChain walks the chain outermost-to-innermost and prefers
decoded custom error names plus their JSON params, then native Solidity
messages, then the raw 4-byte selector, with "execution reverted" as
the last-resort fallback.

The four web3 plugin steps that try sponsorship log the revert with
txHash, sendTransactionStatusId, and revert_chain_depth as metadata,
then short-circuit with the formatted revert message instead of
falling back. Users do not pay gas twice on a call that is guaranteed
to revert again, and operators still see every sponsored revert in
Sentry / log search.
Resolve conflicts between the Pimlico -> Turnkey gas sponsorship migration
and staging's Safe signer-routing and billing reworks:

- sponsored-client: keep the Turnkey preflight; drop the removed `provider`
  column and gate sponsorship on the Turnkey sub-org id alone (Para wallets
  are gone in staging)
- web3 steps: keep the Turnkey sponsorship path while preserving staging's
  `signerMode.kind === "eoa"` guard so Safe-routed writes skip sponsorship
- sponsorship chains: make the runtime allowlist derive from the shared
  sponsorship-chains-meta and reconcile it to Turnkey's actual Gas Station
  coverage (Ethereum, Base, Polygon, Arbitrum + their testnets); drop
  Optimism and BNB, add Arbitrum Sepolia
- billing pricing table: keep per-plan gas credit caps and the Turnkey
  tooltip, sourcing the chain names from the shared metadata
…nants

Replace the bare "eoa" / "safe" / "safe-role" string literals with a single
SIGNER_MODE constant (and SignerModeKind type) exported from the signer
resolver. The signer-mode type, its constructors, the web3Connection parser,
the metrics recorder, and the four web3 write steps now all reference one
source instead of repeating the literals.
Complete the Pimlico -> Turnkey gas sponsorship migration by clearing the
ERC-4337 remnants the staging merge carried back in:

- delete the orphaned turnkey-viem-account helper (the permissionless.js
  smart-account bridge, no longer imported by anything)
- drop the unused PIMLICO_API_KEY / PIMLICO_BASE_URL / SIMPLE_ACCOUNT_7702_ADDRESS
  env wiring from .env.example and the executor/keeperhub deploy values
- refresh stale comments that still pointed at the Pimlico sponsorship path

The eip7702_delegations table is left in place; it no longer has any writer
and should be dropped in a dedicated migration. The unused `permissionless`
package is also still in package.json -- removing it needs a lockfile
re-resolve that the release-age policy currently blocks.
Sponsored transactions silently fell back to direct signing (and failed with
INSUFFICIENT_FUNDS on unfunded wallets). Two bugs:

- The wallet address was sent to Turnkey lowercase (as stored in the DB), but
  Turnkey matches signing resources on the EIP-55 checksummed address. It
  rejected with "Could not find any resource to sign with". Checksum the
  `from` address at the Turnkey boundary.
- The status poller compared against TRANSACTION_STATUS_* enum values that the
  SDK never returns (real values are INCLUDED/BROADCASTED/FAILED/...), so it
  never recognized success and timed out. Match the real terminal statuses;
  failure detection (and SponsoredTxRevertError) is preserved.

Also externalize ioredis in next.config so the Redis-backed proxy middleware
bundles instead of failing to resolve.

Add unit coverage for the sponsorship path (checksum, success, post-broadcast
revert, pre-broadcast failure) and the per-org gas-credit override.
Add a Gas Sponsorship section to the gas management page covering what
sponsorship pays for (the transaction fee only, not the assets being sent),
when a transaction is sponsored (supported chains, direct wallet sender,
public mempool, credits available), why Safe-routed writes are not sponsored,
and how the monthly gas credit cap is metered (mainnet only).
Add an info tooltip to the Monthly executions label explaining the
value is the current calendar-month quota usage (billable executions
since the 1st, UTC, resets on the 1st), which is why it differs from
the Analytics page that counts all executions over the selected range.
…ranches

A node could be both the not-taken target of one condition and the taken
(executed) target of another, e.g. several checks routing their failure branch
into one shared alert node. collectAllSkippedTargets listed it as skipped, so
computeFinalSuccess ignored its failure and the run was marked success even
though the node ran and failed.

Track each decision's taken-handle targets and remove them from the skipped set
before final-success evaluation, so an executed node's failure always counts.
On a hard refresh the session loader is pending and `session` is
undefined, so isAnonymousUser is true for everyone including signed-in
users. The pending branch fell through to the Sign In button until the
session resolved, flashing it for authenticated users.

Render an avatar-shaped skeleton while the loader is pending instead.
Keep falling through (AuthDialog mounted) only for an existing anonymous
session being refetched after a credential submit, so the post-credential
totp view is not dropped.
…ns-tooltip

feat(billing): clarify monthly executions with a tooltip
…uccess-masking

fix(workflow): count failures of executed nodes shared with skipped branches
…oading-user

fix(auth): show avatar skeleton instead of Sign In flash on refresh
…nsorship

refactor(web3): migrate gas sponsorship from Pimlico to Turnkey (KEEP-464)
@suisuss suisuss added the metrics-db-reviewed Reviewer sign-off: metrics aggregate queries optimised + tables indexed (KEEP-680) label Jun 5, 2026
@suisuss suisuss merged commit fa49550 into prod Jun 5, 2026
38 of 39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

metrics-db-reviewed Reviewer sign-off: metrics aggregate queries optimised + tables indexed (KEEP-680)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants