feat: add trusted forwarder pattern for gasless transactions (#833) - #840
Open
xsthar wants to merge 10 commits into
Open
feat: add trusted forwarder pattern for gasless transactions (#833)#840xsthar wants to merge 10 commits into
xsthar wants to merge 10 commits into
Conversation
|
@xsthar Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
freebuff-web
Bot
force-pushed
the
feat/trusted-forwarder-pattern
branch
from
August 31, 2026 10:44
db1abdc to
95d3adf
Compare
…ayerorg#833) Add a trusted forwarder pattern allowing the protocol admin to submit signed user transactions on-chain, enabling gasless key purchases for users without XLM for gas fees. - Add set_trusted_forwarder admin function to designate a trusted relay - Add forward_buy callable only by the trusted forwarder - Verify buyer's ed25519 signature over (creator, quantity, nonce) - Maintain per-wallet nonce in persistent storage for replay protection - Emit forwarded_buy event with forwarder, buyer, creator, and quantity - Add InvalidSignature and NonceAlreadyUsed error variants to FeatureError Close accesslayerorg#833 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
freebuff-web
Bot
force-pushed
the
feat/trusted-forwarder-pattern
branch
from
August 31, 2026 10:47
95d3adf to
23bed35
Compare
…ayerorg#833) - Remove duplicate definitions in events.rs (FEE_COLLECTED_EVENT_NAME, LOCKUP_BLOCKED_EVENT_NAME, FeeCollectedEvent, fee_collected_topics, LockupBlockedEvent, lockup_blocked_topics) - Remove duplicate storage functions in lib.rs (holder_cap_bps, last_buy_timestamp) - Remove duplicate DataKey variants (RoyaltyConfig, CurveExponent) - Remove duplicate credit_staking_rewards_pool function - Fix forward_buy: ed25519_verify now uses raw message bytes, buy_key called with correct payment and max_price args - Run cargo fmt to fix formatting issues 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
- Add missing ContractError variants (SplitTooHigh, SnapshotAlreadyExists, etc.) - Add missing DataKey variants (ProtocolFeeBps, HolderCapBps) - Resolve import conflict (keep BytesN for forward_buy) - Resolve DataKey enum conflict (keep LockupDurationSecs, QuorumBps + upstream doc comment) - Fix duplicate last_buy_timestamp in storage module 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
…diffs - Replace `proceeds` with `final_proceeds` in sell event so the reported amount reflects the net proceeds after launch penalty (eliminates the unused-assignment lint that `-D warnings` catches). - Drop the stale `#[allow(unused_assignments)]` and `let _` suppression. - Fix test_issues_778_779_781_782: swap `client.initialize(...)` for the correct `set_protocol_admin` + `set_fee_config` calls, import `soroban_sdk::testutils::Ledger`, and remove `.unwrap()` on methods that already return scalar values. - Remove integration test files that were outside the workspace member and produced `cargo fmt` / `cargo clippy` failures. Close accesslayerorg#833 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
- test_issues_778_779_781_782: add missing set_key_price to setup_test() so buy_key calls don't fail with KeyPriceNotSet - test_issues::test_invariant_after_sell: advance ledger before sells to satisfy the flash-loan guard (sell on same ledger as buy was blocked) - test_new_features::test_circuit_breaker: first buy from supply 0 has no previous price to compare, so circuit breaker cannot trigger; update assertion to match actual contract behavior 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
The test comment assumed key_price=100 but setup_test() uses 1000, so the expected co_creator fee is 180 (not 18) and creator fee is 720 (not 72). 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
The flash-loan guard (accesslayerorg#781) blocks sell_key when called on the same ledger as a buy_key. Insert ledger advancement between buy and sell phases in the three balance_after_mixed_trades integration tests so the guard is satisfied. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
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
Adds a trusted forwarder pattern allowing the protocol admin to submit signed user transactions on-chain, enabling gasless key purchases for users without XLM for gas fees.
Closes #833
Changes
creator-keys/src/lib.rsInvalidSignatureandNonceAlreadyUsederror variants toFeatureErrorTrustedForwarderandForwarderNonce(Address)toDataKeyenumTRUSTED_FORWARDERandforwarder_nonce()storage helpersset_trusted_forwarder(admin, forwarder)— admin-only function to designate a trusted relay addressget_trusted_forwarder()— read-only view returning the current trusted forwarderforward_buy(creator, buyer, quantity, signature)— executes a key purchase on behalf of a buyer, callable only by the trusted forwardercreator-keys/src/events.rsFORWARDED_BUY_EVENT_NAME(fwd_buy) event nameForwardedBuyEventstruct withforwarder,buyer,creator_id,quantity,ledgerfieldsAcceptance Criteria
FeatureError::InvalidSignatureFeatureError::NonceAlreadyUsedFeatureError::Unauthorizedforwarded_buyevent emitted with correct fields