Skip to content

feat: add SEP-24 fiat on-ramp deposit flow - #160

Merged
tech-adrian merged 3 commits into
Dshield-xyz:devfrom
LeoRicch:feat/sep24-fiat-onramp-146
Aug 30, 2026
Merged

feat: add SEP-24 fiat on-ramp deposit flow#160
tech-adrian merged 3 commits into
Dshield-xyz:devfrom
LeoRicch:feat/sep24-fiat-onramp-146

Conversation

@LeoRicch

Copy link
Copy Markdown
Contributor

Closes #146

@LeoRicch
LeoRicch requested a review from tech-adrian as a code owner August 29, 2026 07:49
@LeoRicch

Copy link
Copy Markdown
Contributor Author

Hi maintainers — this PR implements issue #146: SEP-24 fiat on-ramp support in the deposit flow.
It adds a “Buy & shield” path that discovers a configured Stellar anchor via SEP-1, opens its SEP-24 interactive fiat/KYC flow, polls the resulting transaction, and then hands off to DShield’s existing user-signed shielding flow once funds arrive in the connected wallet.
The PR also includes friendly anchor failure states, optional callback validation, configuration documentation, mocked SEP-24 client tests, and explicit documentation that the anchor is a separate trust boundary from the privacy pool.
I’d appreciate a review when convenient. Thank you!

@LeoRicch

Copy link
Copy Markdown
Contributor Author

Hi maintainers — I’d appreciate a review of this PR for issue #146.
It adds a SEP-24 “Buy & shield” onboarding flow: users can complete a fiat payment/KYC flow with a configured Stellar anchor, receive USDC in their connected wallet, and then continue into DShield’s existing user-signed shielding flow.
The implementation includes SEP-1 anchor discovery, SEP-24 interactive deposit sessions and status polling, friendly anchor failure states, optional callback validation, configuration docs, mocked client tests, and clear documentation of the anchor as a separate trust boundary from the privacy pool.
Thank you for your time and review.

@tech-adrian
tech-adrian merged commit e53570c into Dshield-xyz:dev Aug 30, 2026
tech-adrian added a commit that referenced this pull request Sep 3, 2026
CI on dev has been red since PR #167 (bridge withdrawal), #151
(recurring withdrawals x2), and #169 (relayer fee) landed with severe
merge damage: duplicated blocks, truncated functions, colliding error
discriminants, and stale field offsets. Root causes, by job:

Contracts (contracts/pool, contracts/compliance):
- #151's second merge (fb15893) re-applied a diff already present from
  its first merge (2f22036), duplicating every recurring-withdrawal
  definition; removed the duplicate.
- Multiple truncated braces/functions from bad merges (AdminUpdatedEvent,
  key_commitment_version_prefix, key_bridge_verifier, a test function, a
  stray premature `mod tests` close) that made lib.rs fail to parse.
- PoolError had five different features each claiming discriminants
  18-23; deduplicated and renumbered sequentially.
- shielded_pool's circuit gained a 7th public input (relayer_fee) that
  the contract's WithdrawInputs/parse_public_inputs/PUBLIC_INPUT_BYTES
  never picked up; fixed the layout and gave bridge_withdrawal (5
  fields) its own constant instead of sharing the withdrawal one.
- withdraw_batch never bound each proof to its stated asset (a proof
  for asset A could pay out asset B) and paid from a single leftover
  token address; made it multi-asset aware like withdraw.
- compliance's ComplianceError had TimelockNotSet and ViewVkNotSet both
  claiming discriminant 14; renumbered.
- compliance's setup_pool/setup_with_pool test helpers had conflicting
  duplicate bindings from a merge; fixed arity throughout.
- ~40 pool tests fixed for the current multi-asset/relayer-fee/timelock
  constructor and withdraw(_batch) signatures; three tests whose bodies
  had been spliced with an unrelated fee test were reconstructed from
  their names and the surviving assertions.
- bridge_tests.rs and the compliance ASP-root tests exercise contract
  methods that were never implemented (#167, #161 respectively) -
  gated with NOTE comments rather than inventing an API.

Circuits:
- circuits/shielded_pool/Prover.toml never got a relayer_fee entry for
  the circuit's 7th argument.
- scripts/verify-circuits.mjs's formal spec and self-test mutations
  still encoded the pre-fee conservation rule; updated to
  payout + fee <= amount and change = amount - payout - fee.

packages/core (@dshield/core, used by the frontend, CLI and indexer):
- notes.test.ts/poseidon2.test.ts/prover.test.ts/prover.ts/poseidon2.ts
  used extensionless relative imports and un-attributed JSON imports,
  both invalid under this package's "module": "nodenext".
- package.json was missing @aztec/bb.js and @noir-lang/noir_js as
  dependencies (present in pnpm-lock.yaml, absent from package.json)
  and had no exports map entries beyond ".", so every deep import
  (@dshield/core/format, /report, /notes, /poseidon2, /prover,
  /prover-core) failed to resolve for bundlers that respect "exports".

Frontend:
- tone.ts, Toast.tsx, and recurring/page.tsx had merge-corrupted syntax
  (mangled params, an unterminated string, `}>` instead of `=>`, several
  dropped JSX closing braces, an unescaped quote) that failed to parse.
- deposit/page.tsx's handleDeposit referenced two undeclared identifiers
  (depositStroops, skipTopUp) left over from the SEP-24 on-ramp flow
  (#160) calling it with args it never accepted; gave it the
  overrideAmount/skipTopUp parameters that call site always expected.
- recurring/page.tsx's buildChangeNote, withdraw/page.tsx's batch
  buildChangeNote call, and both pages' relay calls weren't threading
  the note's asset through after multi-asset support landed.
- recurring/page.tsx called a computeAuthCommitment that was never
  added to poseidon2.ts; implemented it to match circuits/recurring's
  hash_auth exactly.
- report.ts's buildComplianceReport referenced an uncomputed
  `integrityOk` and an unused, stale (pre-multi-asset) core import.
- lib/bridge.ts is unused dead scaffolding from #167 with no working
  "./poseidon" counterpart; excluded from tsc/eslint rather than
  guessing at an unshipped API.
- prover.test.ts mocked "@dshield/core/prover-core" while prover.ts
  actually imports the local "./prover-core"; the mock silently never
  applied. Fixed the mock path and the stale VALID_INPUTS/assertions
  for the relayer_fee field.
- recurring/page.tsx's Date.now() call tripped react-hooks/purity;
  extracted a module-scope helper, matching this file's own
  buildChangeNote and withdraw/page.tsx's established convention.

tests/e2e.sh: pool and compliance contract deploys were missing the
--timelock argument their constructors have required since timelock
governance (#163) landed.

Verified locally: cargo test --workspace (210 passed), cargo audit,
all 6 circuits compile/execute (shielded_pool proves + verifies with
the corrected 224-byte/7-field public inputs), pnpm lint/test/build in
frontend (193 tests) and packages/core (45 tests) and the indexer (4
tests), and a full tests/e2e.sh run against a local Stellar network (29
checks passed) covering contract deploy, deposit, compliance, and the
ZK proof cycle end-to-end.

Does not touch the ASP root sync workflow's "Provision sync signer"
failure: it requires the COMPLIANCE_CONTRACT_ID and STELLAR_ADMIN_SECRET
repo secrets, which are unset and outside what a code change can fix.
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.

feature: SEP-24 fiat on-ramp integrated into the deposit flow

2 participants