Skip to content

feat(contract): add anonymous donation flow (#461) - #678

Merged
Idrhas merged 1 commit into
Farm-credit:mainfrom
Peolite001:feat/ROADMAP-122-anonymous-donation-flow
Jul 29, 2026
Merged

feat(contract): add anonymous donation flow (#461)#678
Idrhas merged 1 commit into
Farm-credit:mainfrom
Peolite001:feat/ROADMAP-122-anonymous-donation-flow

Conversation

@Peolite001

Copy link
Copy Markdown
Contributor

Closes #461
Relates to ROADMAP-122

Summary

Adds an anonymous donation flow allowing sponsors to pay for tree planting without creating an account. Funds are held in escrow, trees are auto-assigned to available planters by region, and tree IDs are minted with a null sponsor address. Anonymous donations are excluded from sponsor dashboard tracking.

Related Issue

Closes #461

What Was Implemented

  • donate_anonymous(amount, token, species, region) — no-account one-time payment function in escrow contract
  • Species cost validation table (teak, moringa, eucalyptus, mangrove, acacia, bamboo)
  • Auto-assignment to available planters by region via get_avail(region)
  • Planter workload tracking (inc_work / dec_work) with capacity limits
  • Anonymous tree minting via mint_anon(species, region, planter) in tree registry
  • Tree IDs linked to null sponsor address (sponsor: None)
  • Anonymous trees excluded from get_sponsor_trees() dashboard queries
  • Anonymous donations emit AnonDep and anon_minted events
  • Anonymous escrows cannot be refunded (no sponsor address to refund to)
  • Planter workload decremented on release for anonymous trees
  • initialize_registries() to link escrow → tree_registry + planter_registry
  • Full test coverage: success path, insufficient funds, no planters, invalid species, species costs, anonymous release, anonymous refund rejection

Implementation Details

  • Escrow contract (contracts/escrow/src/lib.rs):

    • Extended EscrowRecord with sponsor: Option<Address>, species, region, is_anonymous fields
    • Added donate_anonymous() that bypasses sponsor auth, validates species cost, transfers tokens, mints tree, creates escrow with sponsor: None
    • release() checks is_anonymous flag to call dec_work() on planter registry
    • refund() rejects anonymous donations by requiring sponsor: Some(...)
    • Cross-contract calls to planter_registry.get_avail(), inc_work(), dec_work() and tree_registry.mint_anon()
  • Planter registry (contracts/planter_registry/src/lib.rs):

    • Extended PlanterRecord with capacity, workload, active, total_trees_planted
    • Added set_escrow() for escrow-only auth on workload changes
    • get_avail(region) filters by active && workload < capacity
    • inc_work() / dec_work() are escrow-authenticated with capacity and zero-check guards
    • set_active() and set_capacity() for admin management
    • Region index for O(1) region lookups
  • Tree registry (contracts/tree_registry/src/lib.rs):

    • New contract with mint_anon() that creates trees with sponsor: None
    • Tracks TotalAnonymousTrees separately from total trees
    • CO2 offset lookup per species (FAO/IPCC Tier 1 estimates)
  • No breaking changes: All existing deposit(), release(), refund(), register_planter(), increment_score(), slash_score() flows remain unchanged.

Screenshots / Recordings

N/A — smart contract changes only, no UI modifications.

How to Test

  1. Build contracts:

    cd contracts
    cargo build --target wasm32-unknown-unknown --release
  2. Run tests:

    cargo test

    Expected: 28 tests pass (10 existing escrow + 10 existing planter + 8 new anonymous flow tests)

  3. Test anonymous donation flow manually:

    # Deploy contracts
    stellar contract deploy --wasm target/wasm32-unknown-unknown/release/tree_registry.wasm --network testnet
    stellar contract deploy --wasm target/wasm32-unknown-unknown/release/planter_registry.wasm --network testnet
    stellar contract deploy --wasm target/wasm32-unknown-unknown/release/escrow.wasm --network testnet
    
    # Initialize
    stellar contract invoke --id <escrow-id> -- initialize --verifier <verifier-address>
    stellar contract invoke --id <escrow-id> -- initialize_registries --tree_registry <tree-id> --planter_registry <planter-id>
    stellar contract invoke --id <planter-id> -- initialize --admin <admin-address>
    stellar contract invoke --id <planter-id> -- set_escrow --escrow <escrow-id>
    
    # Register a planter
    stellar contract invoke --id <planter-id> -- register_planter --wallet <planter-addr> --name_hash <hash> --region "kenya"
    
    # Make anonymous donation
    stellar contract invoke --id <escrow-id> -- donate_anonymous --amount 500000000 --token <usdc-id> --species "teak" --region "kenya"
  4. Verify:

    • Escrow record shows sponsor: null, is_anonymous: true
    • Planter workload incremented by 1
    • Tree registry shows total_anonymous_trees: 1
    • get_sponsor_trees(sponsor_addr) does NOT include the anonymous tree

Checklist

  • My code follows the atomic commit convention
  • Each commit message follows Conventional Commits (feat:, fix:, etc.)
  • I have performed a self-review of my code
  • My changes build successfully (cargo build --target wasm32-unknown-unknown --release)
  • My changes pass linting (cargo fmt && cargo clippy --all-targets --all-features)
  • I have added/updated relevant documentation (inline rustdocs + README example)
  • New components follow the atomic design pattern (atoms → molecules → organisms)
  • UI changes are responsive and tested on mobile viewports
  • I have added screenshots/recordings for UI changes

- donate_anonymous(): no-account one-time payment
- Auto-assigns to available planter by region with workload tracking
- Mints tree with null sponsor (anonymous)
- Preserves all existing escrow deposit/release/refund behavior
- Adds planter capacity/workload management
- Anonymous trees excluded from sponsor dashboard

Closes Farm-credit#461
Relates to ROADMAP-122
@drips-wave

drips-wave Bot commented Jun 28, 2026

Copy link
Copy Markdown

@Peolite001 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! 🚀

Learn more about application limits

@Idrhas

Idrhas commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

fix your conflicts and dont forget to offramp with fundable on: https://stellar.fundable.finance/offramp

4 similar comments
@Idrhas

Idrhas commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

fix your conflicts and dont forget to offramp with fundable on: https://stellar.fundable.finance/offramp

@Idrhas

Idrhas commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

fix your conflicts and dont forget to offramp with fundable on: https://stellar.fundable.finance/offramp

@Idrhas

Idrhas commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

fix your conflicts and dont forget to offramp with fundable on: https://stellar.fundable.finance/offramp

@Idrhas

Idrhas commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

fix your conflicts and dont forget to offramp with fundable on: https://stellar.fundable.finance/offramp

@Idrhas
Idrhas merged commit 068215b into Farm-credit:main Jul 29, 2026
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.

feat(contract): Anonymous donation flow - no-account one-time payment

2 participants