refactor(web3): migrate gas sponsorship from Pimlico to Turnkey (KEEP-464)#1221
Draft
joelorzet wants to merge 8 commits into
Draft
refactor(web3): migrate gas sponsorship from Pimlico to Turnkey (KEEP-464)#1221joelorzet wants to merge 8 commits into
joelorzet wants to merge 8 commits into
Conversation
…(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.
🧹 PR Environment Cleaned UpThe PR environment has been successfully deleted. Deleted Resources:
All resources have been cleaned up and will no longer incur costs. |
ℹ️ No PR Environment to Clean UpNo PR environment was found for this PR. This is expected if:
|
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ethSendTransactionwithsponsor: true). Turnkey signs and sponsors the underlying EVM transaction in one activity, so the whole UserOperation / EntryPoint 0.8 /permissionlessstack is gone on the sponsored path.gasUsed * effectiveGasPricefrom the broadcast receipt, same gas-credits ledger as before.Open flags (need confirmation before merge)
eip155:1 / 8453 / 137(+ their testnets) forethSendTransaction. Arbitrum is included in the allowlist with a runtime cast through that enum; Turnkey's API will either accept or reject it. Drop fromSUPPORTED_SPONSORSHIP_CHAINSif rejected once enterprise credentials are live.Files changed
New
lib/web3/turnkey-sponsorship-config.tschain allowlist + CAIP-2 mappinglib/web3/turnkey-sponsored-tx.tsethSendTransaction(sponsor: true)wrapper, pollsgetSendTransactionStatusfor the broadcasttxHashRewritten
lib/web3/sponsored-client.tsthin preflight, resolves the org's TurnkeysubOrgId+walletAddresslib/web3/sponsored-transaction-manager.tscalls the Turnkey wrapper, keepswaitForTransactionReceipt+ gas-credits meteringtests/unit/sponsored-client.test.ts,tests/unit/sponsored-transaction-manager.test.tscomponents/billing/billing-status.tsx,components/billing/pricing-table/index.tsxnetwork info UIDeleted
lib/web3/pimlico-config.tslib/web3/sponsored-fee-clamp.ts(KEEP-394 fee-inversion clamp is dead, Turnkey fills gas itself)lib/web3/eip7702-delegation.ts(no inline 4337 delegation any more)lib/para/viem-account-adapter.ts(sponsored-client was the last caller)tests/unit/sponsored-fee-clamp.test.ts,tests/integration/eip7702-spike.test.tsModified plugin steps
plugins/web3/steps/{transfer-funds,transfer-token,approve-token,write-contract}-core.tsimport path swap frompimlico-configtoturnkey-sponsorship-config, comment refreshFollow-up
permissionlessis now a dead dependency inpackage.json. It was kept in this PR because the repo'sminimumReleaseAgepnpm constraint blocked a clean lockfile regeneration; remove it in a separate PR once the constraint is sorted.gasSponsorshipDelegationstable is no longer written to. Leaving the table for historical audit data; can be dropped via migration in a follow-up if desired.🤖 Generated with Claude Code