Skip to content

DO-015: Ensure CI cargo commands use --locked - #4

Open
ZainabJanee wants to merge 104 commits into
mainfrom
issue-70-do-015
Open

DO-015: Ensure CI cargo commands use --locked#4
ZainabJanee wants to merge 104 commits into
mainfrom
issue-70-do-015

Conversation

@ZainabJanee

Copy link
Copy Markdown
Owner

Closes devEunicee#70

Confirmed CI cargo commands that support --locked already use it; is committed.

jhayniffy and others added 30 commits May 31, 2026 15:36
Cache keys now embed the rustc --version output alongside Cargo.lock hash,
so a toolchain upgrade (e.g. stable patch release or MSRV bump) correctly
invalidates the cache even when Cargo.lock is unchanged.

Applied to: test matrix, build-wasm, and release jobs.
- Add sign_order_xdr helper that signs the full XDR-serialised order,
  matching the payload the contract actually verifies
- Add test_real_ed25519_valid_signature_succeeds: registers a merchant
  with a real ed25519 public key, signs the correct XDR payload, and
  asserts the payment completes successfully
- Add test_real_ed25519_tampered_signature_fails: tampers one byte of a
  valid signature and asserts the contract rejects it
- Both tests do not rely on signature bypass (non-zero merchant key
  stored on-chain forces the ed25519_verify path)

Closes T-001
Documents how an off-chain API wrapper must expose the contract's
cursor-based pagination to consumers:
- cursor and limit query parameters
- Response shape with next_cursor and total fields
- Pagination examples (first page, subsequent pages, last page, filters)
- Implementation notes and error responses
- Check WASM size immediately after the release build step
- Fail CI if binary exceeds 100 KB (Soroban deployment limit is ~128 KB;
  100 KB gives a safety margin)
- Emit a warning when size crosses 80 KB so regressions are visible early
- Report exact byte count and KB size in the GitHub Actions step summary
  so every run has a visible size record

Closes DO-003
- Add ContractPaused = 60 error variant to PaymentError
- Add Paused key to DataKey enum in types.rs
- Add is_paused/set_paused helpers in storage.rs
- Add pause(env, admins) and unpause(env, admins) functions (admin-only)
  that emit contract_paused / contract_unpaused events
- Add is_paused(env) read-only query (always accessible, even when paused)
- Guard all state-mutating functions with a paused check that returns
  ContractPaused immediately:
    register_merchant, set_whitelist_mode, approve_merchant_registration,
    deactivate_merchant, process_payment_with_signature,
    archive_payment_record, cleanup_expired_payments,
    set_payment_cleanup_period, set_default_multisig_expiry,
    initiate_refund, approve_refund, reject_refund, execute_refund,
    initiate_multisig_payment, sign_multisig_payment,
    execute_multisig_payment
- Read-only functions (get_merchant, get_payment_by_id,
  get_merchant_payment_history, get_payer_payment_history,
  get_global_payment_stats, get_refund_status, get_version)
  remain accessible while paused

Closes SEC-010
- Dockerfile.dev: Rust 1.79 + Stellar CLI + wasm32 target + cargo-audit
- docker-compose.yml: stellar/quickstart local network + dev container
- README: Docker Compose quickstart section (Option A) alongside native setup
- Create CHANGELOG.md following Keep a Changelog format
  (https://keepachangelog.com/en/1.1.0/)
- Document the full 0.1.0 feature set: admin management, merchant
  management, payment processing with ed25519 signatures, payment
  queries with pagination/filtering/sorting, refund workflow,
  multi-signature payments, global statistics, storage TTL, events,
  error codes, and CI pipeline
- Add [Unreleased] section capturing recent improvements (SEC-010,
  DO-003, T-001, re-entrancy hardening, admin validation)
- Add .github/pull_request_template.md with a CHANGELOG update reminder
  in the contributor checklist so every PR is prompted to keep the log
  current

Closes DOC-001
…ith_signature

- test_payment_zero_amount_fails: amount = 0 returns InvalidAmount
- test_payment_negative_amount_fails: amount = -1 returns InvalidAmount

Closes #T-010
- Add TokenNotAllowed error (code 60) to PaymentError
- Add TokenAllowlistEnabled and AllowedToken(Address) DataKey variants
- Add storage functions: is_token_allowlist_enabled, set_token_allowlist_enabled,
  is_token_allowed, set_token_allowed
- Add contract methods: set_token_allowlist_mode, set_token_allowed, is_token_allowed
- Enforce allowlist check in process_payment_with_signature and
  initiate_multisig_payment when allowlist mode is enabled
- Allowlist is off by default; integrators who do not enable it should
  review the trust model documented in SECURITY.md

Closes #SEC-009
- Add scripts/setup.sh that installs Rust, wasm32-unknown-unknown target,
  and Stellar CLI automatically
- Script is idempotent: checks for existing installs before acting
- Supports Ubuntu 20.04+ and macOS 12+
- README Setup section updated to reference the script with usage instructions
- Add 'coverage' job using cargo-llvm-cov 0.6.13 with llvm-tools-preview
- Generate LCOV report and upload as 'coverage-report' artifact (30-day retention)
- Check minimum 80% line coverage with a warning (not a hard fail) to avoid
  blocking PRs while coverage is being built up
- Add docs/security-audit.md with full audit scope, recommended auditors,
  pre-audit checklist, process steps, and deployment gate criteria
- Update SECURITY.md to reference the audit requirement and link to the doc
- Mainnet deployment is blocked until a final audit report with no unresolved
  Critical/High findings is published in the repository
- Add .pre-commit-config.yaml with two local hooks:
  - cargo-fmt: runs cargo fmt --all -- --check on Rust files
  - cargo-clippy: runs cargo clippy --all-targets --all-features -- -D warnings
- Document hook installation steps in CONTRIBUTING.md under new
  'Pre-commit Hooks' section, including pip/brew install, pre-commit install,
  and rustup component add rustfmt clippy

Closes #DO-013
…ract

- Add monitoring/ directory with a Node.js Horizon event stream listener
- src/config.js: all thresholds and endpoints configurable via env vars
- src/metrics.js: in-memory rolling-window metric store tracking
  payment_volume, refund_rate, and error_rate
- src/alerts.js: alert dispatcher — stdout + optional webhook (Slack/PagerDuty)
- src/monitor.js: main polling loop; subscribes to Horizon contract events,
  dispatches payment_processed / refund_initiated events, checks anomalies
  after every poll cycle

Alert conditions:
  - refund_rate > 20% in 1-hour rolling window (REFUND_RATE_THRESHOLD)
  - single payment > 1 000 XLM (LARGE_PAYMENT_THRESHOLD)
  - poll error_rate > 5% in rolling window (ERROR_RATE_THRESHOLD)

- monitoring/README.md: full setup, configuration, deployment, and
  extension guide

Closes #DO-012
Add config/ directory with local.toml, testnet.toml, and mainnet.toml.
Each file documents public values (RPC URL, contract ID, admin public key,
token address) and clearly marks which values are secrets that must be
supplied via environment variables (ADMIN_SECRET_KEY) and never committed.

Also update .gitignore to exclude .env and .env.* secret files.

Closes: No environment-specific configuration management
Add storage::bump_instance_ttl() which calls extend_ttl on instance
storage with the same TTL_LEDGERS/TTL_THRESHOLD constants used for
persistent storage (~1 year, refresh at ~6 months).

Call bump_instance_ttl at the top of every public contract function so
Admin, GlobalStats, CleanupPeriod, and DefaultMultisigExpiry never expire
while the contract is in active use.

Also expose a public bump_instance_ttl(env: Env) contract function
callable by anyone, allowing external keepers to refresh the TTL even
when the contract is dormant.

Closes: Instance storage TTL not extended
All public functions in lib.rs now have /// doc comments covering:
- Purpose / summary line
- Parameters (# Parameters section)
- Return value where applicable (# Returns section)
- All error variants that can be returned (# Errors section)

Previously only set_admin and process_payment_with_signature had doc
comments. This brings the contract up to the standard expected by
cargo doc --no-deps.

Closes: No inline rustdoc on public functions
- Document semver policy in CHANGELOG.md:
  MAJOR = breaking ABI change, MINOR = new backwards-compatible
  functionality, PATCH = bug fixes / docs / internal refactors.
- Add initial [0.1.0] changelog entry covering all features shipped
  in the first release.
- Add .github/workflows/release.yml: on every push to main, detect
  whether the version in Cargo.toml has a corresponding git tag; if
  not, extract the matching CHANGELOG section and create a GitHub
  Release + tag automatically.

Closes: No semantic versioning or release tagging process
- Document that category additions require contract upgrade
- Add ADR-0004 explaining merchant category management strategy
- Create CATEGORY_MIGRATION_GUIDE.md with step-by-step instructions
- Update README with category information and migration references
- Include backward compatibility notes and rollback procedures

Addresses issue devEunicee#101 MISC-006 acceptance criteria:
 Document that category additions require a contract upgrade
 Add a migration guide template for category additions
 Consider string-based category approach (documented in ADR-0004 Phase 2)

The current enum-based approach provides type safety while the migration
guide enables admins to add new categories through contract upgrades.
Future versions may implement dynamic string-based categories with
admin-managed allowlist for greater flexibility.
- Add MerchantStats type with payment and refund metrics
- Implement get_merchant_stats(merchant, date_start, date_end) function
- Support cached stats (O(1)) and filtered stats (O(n)) query modes
- Add merchant stats storage and increment functions
- Update payment/refund processing to track merchant stats
- Add comprehensive merchant stats tests
- Create ADR-0005 documenting on-chain vs off-chain analytics strategy
- Create ANALYTICS_GUIDE.md with usage examples and best practices
- Update README with analytics section and get_merchant_stats documentation

Addresses issue devEunicee#102 MISC-007 acceptance criteria:
 Add get_merchant_stats(env, merchant, date_start, date_end) returning per-merchant totals
 Document the on-chain vs. off-chain analytics split (ADR-0005)
 Provide roadmap for off-chain indexer (BE-001) for richer analytics

Per-merchant stats are cached for performance and support optional date-range
filtering for historical analysis. Access control ensures merchants can query
their own stats and admins can query any merchant.
- Add // SPDX-License-Identifier: MIT to all .rs files
- Create scripts/check-license-headers.sh for CI enforcement
- Add CI check to verify license headers on all Rust files
- Create docs/LICENSE_HEADERS.md with guidelines and examples
- Update CONTRIBUTING.md to document license header requirement

Addresses issue devEunicee#104 MISC-009 acceptance criteria:
 Add // SPDX-License-Identifier: MIT to the top of every .rs file
 Add a CI check (bash script) that enforces headers on new files

All 7 Rust source files now have proper SPDX license identifiers:
- contracts/payment-processing-contract/src/lib.rs
- contracts/payment-processing-contract/src/types.rs
- contracts/payment-processing-contract/src/storage.rs
- contracts/payment-processing-contract/src/error.rs
- contracts/payment-processing-contract/src/helper.rs
- contracts/payment-processing-contract/src/test.rs
- contracts/payment-processing-contract/src/repro_tests.rs

The CI check runs on every pull request to ensure new files include
the required license header, maintaining compliance with open-source
standards and tools like REUSE and SPDX.
- Create scripts/seed.sh for automated test environment setup
- Register 3 merchants with different categories
- Process 10 sample payments between payer and merchants
- Initiate 2 refunds for testing refund workflow
- Add config/local.toml and config/testnet.toml for configuration
- Create docs/SEEDING_GUIDE.md with comprehensive usage instructions
- Create docs/DEVELOPMENT.md with development workflow guide
- Update README with environment seeding section

Addresses issue devEunicee#103 MISC-008 acceptance criteria:
 Add scripts/seed.sh that registers 3 merchants, processes 10 payments, initiates 2 refunds
 Script uses Stellar CLI and reads config from config/local.toml
 README documents how to run the seed script

The seeding script enables developers to:
- Quickly populate test environments with sample data
- Test contract functionality without manual setup
- Verify analytics and reporting features
- Demonstrate contract capabilities

Configuration is flexible and supports:
- Multiple networks (local, testnet, public)
- Customizable merchant count and categories
- Adjustable payment amounts and counts
- Configurable refund scenarios
…-005)

Implements native subscription/recurring payment support as described in
issue devEunicee#100. Soroban contracts cannot self-schedule, so an off-chain
scheduler is required to trigger process_subscription_payment at each
interval boundary — this constraint is documented in code and README.

New types (types.rs):
- SubscriptionPlan: interval (seconds), amount, token
- SubscriptionStatus: Active | Cancelled
- SubscriptionState: full subscription record with payer, merchant,
  plan, status, created_at, last_charged_at
- DataKey::Subscription(Bytes) storage key

New error codes (error.rs):
- SubscriptionNotFound (60)
- SubscriptionAlreadyExists (61)
- SubscriptionNotActive (62)
- SubscriptionIntervalNotElapsed (63)

New storage helpers (storage.rs):
- get_subscription / save_subscription with TTL extension

New contract functions (lib.rs):
- create_subscription: payer creates a subscription for a merchant;
  validates interval > 0, amount > 0, merchant active, no duplicate ID
- cancel_subscription: payer cancels their own active subscription
- process_subscription_payment: off-chain scheduler calls this at each
  interval; enforces interval guard (SubscriptionIntervalNotElapsed)
  to prevent double-charging; first charge skips the guard
  (last_charged_at == 0)
- get_subscription: read-only accessor

New helper functions (helper.rs):
- require_multi_admin: multi-admin support used across admin-gated calls
- in_date_range: date filter utility for global stats queries

Refactored (lib.rs, test.rs):
- set_admin now accepts Vec<Address> + threshold for multi-admin config
- All admin-gated functions updated to use require_multi_admin
- test.rs fully rewritten with focused unit tests covering all new and
  existing paths; repro_tests.rs updated to match new API

Tests added (test.rs):
- test_create_subscription_success
- test_create_subscription_duplicate_fails
- test_create_subscription_zero_interval_fails
- test_create_subscription_inactive_merchant_fails
- test_cancel_subscription_success
- test_cancel_subscription_wrong_payer_fails
- test_cancel_already_cancelled_fails
- test_process_subscription_payment_first_charge
- test_process_subscription_payment_after_interval
- test_process_subscription_payment_before_interval_fails
- test_process_subscription_payment_cancelled_fails
- test_get_subscription_not_found_fails

Closes devEunicee#100
- types.rs: rename token: Option<Address> to tokens: Option<Vec<Address>>
- helper.rs: matches_filter checks record.token is in tokens list;
  None and empty vec both match all tokens
- test.rs: update 4 existing PaymentFilter usages; add 8 new tests
  covering single, multi, empty, none, combined, and merchant history
- lib.rs: update_merchant(merchant_address, name, description, contact_info)
  requires merchant auth, validates fields, preserves immutable attributes
  (address, registered_at, category, active, signing_public_key),
  saves atomically, emits merchant_updated event
- test.rs: 8 tests covering success, immutable field preservation,
  unauthorized caller, not-found, field validation, event emission
DEVEUNICE and others added 30 commits June 2, 2026 17:59
…-update

feat(merchant): mutable profile updates via update_merchant (MISC-002)
…ifecycle

feat(refunds): add on-chain dispute resolution lifecycle (MISC-004)
…iption-support

feat(subscriptions): native recurring/subscription payment support (MISC-005)
…seed-script

feat: MISC-008 add environment seeding script for testing
…icense-headers

fix: MISC-009 add SPDX license headers to all source files
…merchant-stats

feat: MISC-007 add per-merchant analytics and reporting
…ant-category-validation

docs: MISC-006 merchant category validation and migration guide
…-ttl-docs-versioning

Fix/issues config ttl docs versioning
…T-015-SEC-001-DOC-009

Fix/issues do 009 t 015 sec 001 doc 009
…-T-010-SEC-009

Fix/do 012 do 013 t 010 sec 009
…11-do-010

Fix/do 018 be 008 t 011 do 010
…3-SEC010-DOC001

Fix/issues t001 do003 sec010 doc001
- Add Contributor Covenant v2.1
- Link from README and CONTRIBUTING
- Designate contact email
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.