Add CPI inner instruction scanning to charge scheme for smart wallet support#151
Open
0xultravioleta wants to merge 1 commit into
Open
Conversation
Smart wallets (Squads, Crossmint, SWIG) route SPL token transfers through cross-program invocations. The TransferChecked instruction lives inside an inner instruction, not at the top level. The x-solana-settlement scheme already handles this pattern in its isValidTransferTransaction and extractTransferData functions. This commit brings the same capability to the charge scheme: - fetchConfirmedTransaction now returns innerInstructions and staticAccountKeys from the on-chain transaction meta - verifyChargeTransaction falls back to scanning inner instructions when no top-level TransferChecked matches - Same security checks apply: mint, destination ATA, amount must match; authority must not be the fee payer; exactly one matching transfer allowed Backward compatible: existing top-level transfers still match first. The inner instruction path only activates as a fallback. Ref: faremeter#150
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
Smart wallets on Solana (Squads, Crossmint, SWIG) route SPL token transfers through cross-program invocations (CPI). The actual
TransferCheckedinstruction lives inside an inner instruction, not at the top level of the transaction.The
@faremeter/x-solana-settlementscheme already handles this pattern — itsisValidTransferTransaction,extractTransferData, andisValidMemofunctions all scantransaction.meta.innerInstructionswhen top-level matching fails. This PR brings the same capability to thechargescheme inpackages/payment-solana.Changes
packages/payment-solana/src/charge/server.tsfetchConfirmedTransaction()now returnsinnerInstructionsandstaticAccountKeysfrom the on-chain transaction meta alongside the decompiled messageverifyChargeTransactionpackages/payment-solana/src/charge/verify.tsVerifyChargeTransactionArgsaccepts optionalinnerInstructionsandstaticAccountKeysfindTransferInInnerInstructions()function scans CPI inner instructions forTransferCheckedas a fallback when no top-level match is foundspl_tokenandspl_token_2022programsBackward compatibility
Existing top-level transfers still match first. The inner instruction path only activates as a fallback when the existing top-level scan returns no match. All existing
exact/verify.test.tstests pass unchanged (36/36).Context