Skip to content

feat: benchmark CI, OWASP scanning, contract auth audit & multi-sig admin ops#1

Open
quartune wants to merge 576 commits into
mainfrom
feature/issues-935-936-937-253
Open

feat: benchmark CI, OWASP scanning, contract auth audit & multi-sig admin ops#1
quartune wants to merge 576 commits into
mainfrom
feature/issues-935-936-937-253

Conversation

@quartune

Copy link
Copy Markdown
Owner

Summary

Closes Haroldwonder#935, Haroldwonder#936, Haroldwonder#937, Haroldwonder#253

Haroldwonder#935 — Performance regression benchmarks in CI

  • New workflow .github/workflows/benchmark-ci.yml runs cargo bench --features benchmarks on every push/PR touching src/ or benches/
  • Criterion JSON results saved as per-SHA artifacts (30-day retention)
  • On PRs the workflow downloads the base-branch baseline and runs an inline Python script that compares mean timings; fails the build if any benchmark regresses > 20%
  • Posts a markdown summary (regressions, improvements, new benchmarks) to the GitHub step summary

Haroldwonder#936 — OWASP dependency vulnerability scanning

  • New workflow .github/workflows/security-audit.yml runs npm audit --audit-level=high for backend, frontend, api, examples; plus cargo audit for Rust deps
  • Triggers on push/PR (lock-file changes) and weekly on Monday 06:00 UTC
  • New .github/dependabot.yml configures weekly Dependabot PRs for all npm directories, the Cargo workspace, and GitHub Actions; minor/patch updates are grouped to reduce noise

Haroldwonder#937 — Smart contract authorization audit

  • Enumerated all #[contractimpl] functions and verified each state-mutating function has an explicit auth check (require_admin, require_auth, or agent registration check)
  • Added SECURITY.md with the full authorization model: role table, per-function auth table, multi-sig flow description, and defence-in-depth summary
  • No missing authorization checks found; all functions verified ✅

Haroldwonder#253 — Multi-signature admin operations

  • src/types.rs: new AdminOperationType enum (UpdateFee, WithdrawFees, Pause, Unpause) and PendingOperation struct (id, operation_type, proposer, approvers, threshold, proposed_at, ttl_seconds, fee_bps, withdraw_to)
  • src/errors.rs: four new error variants — OperationNotFound(56), AlreadyApproved(57), OperationExpired(58), InvalidMultiSigThreshold(59)
  • src/storage.rs: new keys MultiSigThreshold, MultiSigTtlSeconds, OperationCounter, PendingOp(u64) and CRUD helpers
  • src/multisig.rs: new module with set_multisig_config, propose_operation, approve_operation, expire_operation, get_operation, and internal execute_operation dispatch
  • src/events.rs: four new events — msig/proposed, msig/approved, msig/executed, msig/expired (all include SCHEMA_VERSION + ledger sequence/timestamp)
  • src/lib.rs: five new public contract entry points exposing the multi-sig API
  • Defaults: threshold=1 (single-admin, backwards-compatible), TTL=86 400 s; configure with set_multisig_config

Security analysis (Haroldwonder#253)

  • Proposer and approvers must each pass require_admin (which calls require_auth on-chain), preventing impersonation
  • Duplicate-approval protection: AlreadyApproved is returned if the same admin tries to approve twice
  • TTL expiry: operations that exceed ttl_seconds are swept out of storage on the next approve_operation or explicit expire_operation call — no dangling state accumulates
  • Threshold=1 default means the contract behaves identically to before until set_multisig_config is called

Test plan

  • Deploy a local Soroban testnet environment and call initialize then set_multisig_config(2, 3600)
  • Call propose_operation(UpdateFee, 300, None) as admin-1; verify msig/proposed + msig/approved events, pending op stored
  • Call approve_operation(op_id) as admin-2; verify msig/approved + msig/executed, fee updated, pending op removed
  • Call propose_operation and wait for TTL; call expire_operation; verify msig/expired event
  • Verify non-admin cannot call propose_operation or approve_operation (returns Unauthorized)
  • Push a PR that intentionally slows a benchmark by 30%; verify benchmark CI fails
  • Run npm audit --audit-level=high locally in each service directory; verify CI step matches

Haroldwonder and others added 30 commits June 1, 2026 16:12
…etry-utilities

fix: export withRetry and isTransientError from sdk/src/index.ts
…max-attempts-filter

fix: filter exhausted webhook deliveries in getPending
fix: add row-level locking to RemittanceRepository.upsert
fix: redact sensitive fields in StructuredLogger
fix(sdk): throw SwiftRemitError for batch size violations
fix(frontend): clamp page URL param to valid range
fix(frontend): check Freighter availability on startup
fix: Add ISO 4217 currency code validation
fix: Require 2FA confirmation for simulateUpgrade endpoint
fix: Use timing-safe comparison for API key validation
fix: Add pagination support to currencies endpoint
fix(backend): replace regex XSS detection with xss library
…vernance lifecycle, and FxRateCache outage

fix: add missing tests for webhook dead-letter queue, e2e cleanup, governance lifecycle, and FxRateCache outage
, Haroldwonder#708 — a11y tests, proptest netting, SEP-24 timeouts, RUNBOOK circuit breaker

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add agentRemittanceIds to AuthenticatedUser and decode it from JWT.
userCanAccessRemittance now grants access when the remittance is in
either the sender's remittanceIds or the agent's agentRemittanceIds.
Wrap deletion in a transaction and explicitly delete related records
from webhook_subscriptions, kyc_configurations, and sep24_transactions
before removing the anchor row to prevent orphaned records.
Add requireAdminApiKey middleware to the /corridors route.
createAnalyticsRouter now accepts an optional adminApiKey param
(falls back to ANALYTICS_ADMIN_API_KEY env var).
app.ts passes the key when mounting the analytics router.
…dpoint

Returns corridor-specific daily limit for a currency/country pair,
using the same overrides map as the existing query-param endpoint.
)

Store expiresAt as storedAt + ttl so session expiry is immune to
system clock changes. parseStoredWalletSession now compares
Date.now() against the absolute expiresAt field.
…der#639)

Wrap the DB query in a retry loop with exponential backoff (up to 5
attempts). On connection failure the notifier logs the error and
recovers automatically once the database is reachable again.
…dwonder#651)

Wrap the async callback with context.with(trace.setSpan(context.active(), span))
so child spans created inside async operations are correctly parented.
…r#665)

Add typeof window !== 'undefined' check before accessing window.crypto.subtle
so deriveProofHash does not throw a ReferenceError in SSR/SSG environments.
…n work

- Add test_governance_event_emission_all_types covering all 9 governance
  event types (proposal_created, proposal_voted, proposal_approved,
  proposal_executed, proposal_expired, governance_admin_added,
  governance_admin_removed, fee_update_proposed, agent_management_proposed)
- api: openapi generator updates, route fixes, admin-confirmation module
- backend: webhook handler dead-letter queue, SEP-24 timeouts, metrics,
  scheduler, dispatcher, and test coverage improvements
- frontend: SendMoneyFlow, TransactionHistory pagination, horizonService,
  a11y test fixes across multiple components
- sdk: client retry logic (retry.ts), event test fixes, package updates

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
JoesWalker and others added 30 commits June 28, 2026 13:06
…#866, Haroldwonder#867)

Closes Haroldwonder#866 — Background job monitoring dashboard
- Add job_runs DB table (migration up + down)
- runTracked() helper wraps all 6 scheduler jobs with DB run recording
- GET /api/admin/jobs endpoint returns per-job last run, status, 24h failure count, last 10 runs
- Prometheus metrics: swiftremit_job_last_run_timestamp and swiftremit_job_failure_total (per job_name label)

Closes Haroldwonder#867 — Multi-region FX rate provider failover
- FxRateProvider interface with PrimaryFxProvider (exchangerate-api v6) and SecondaryFxProvider (open.er-api.com)
- FailoverFxService: primary → secondary → stale cache with in-process circuit breaker (60s half-open)
- Structured fx_provider_switch alert log on provider switch
- FxRateCache.fetchFromExternalApi delegates to FailoverFxService
- FX_SECONDARY_API_URL / FX_SECONDARY_API_KEY added to .env.example

Tests: 15 new tests, all passing
…npm release automation

- Add RetryPolicy interface and RetryPolicies constants (NONE, AGGRESSIVE)
- writeRetryPolicy option on SwiftRemitClientOptions defaults writes to 0 retries;
  callers opt in per-call via submitTransaction options.retryPolicy
- Add withRetryPolicy() helper that merges policy with client defaults
- Fix pre-existing missing withTimeout private method on SwiftRemitClient
- Add estimateFee(amount, corridor, senderAddress) with 30s TTL cache;
  returns typed FeeEstimate with platformFee, protocolFee, netAmount breakdown
- Add SwiftRemitMockClient in sdk/src/testing/ exported from @swiftremit/sdk/testing;
  full in-memory state machine, chainable seed helpers, no Stellar network required
- Add changesets config at .changeset/config.json for automated npm versioning
- Add ./testing export to package.json and include it in tsup build
- Document retry behaviour, fee estimation, and mock client in SDK README
…nd multi-sig admin ops

Closes Haroldwonder#935, Haroldwonder#936, Haroldwonder#937, Haroldwonder#253

## Haroldwonder#935 — Performance regression benchmarks in CI
- Add `.github/workflows/benchmark-ci.yml` that runs `cargo bench --features benchmarks`
- Saves criterion JSON output as per-SHA artifacts for 30 days
- On PRs: downloads the base-branch artifact and runs a Python comparison script that
  fails the build if any benchmark regresses by > 20%
- Posts a markdown summary (regressions, improvements, new benchmarks) to the workflow step summary

## Haroldwonder#936 — OWASP dependency vulnerability scanning
- Add `.github/workflows/security-audit.yml` that runs `npm audit --audit-level=high`
  for backend, frontend, api, and examples; plus `cargo audit` for Rust dependencies
- Runs on push/PR to main (on relevant lock-file changes) and weekly on Monday at 06:00 UTC
- Add `.github/dependabot.yml` with weekly update schedules for all five npm directories,
  the Cargo workspace, and GitHub Actions; grouped non-breaking updates to reduce noise

## Haroldwonder#937 — Smart contract authorization audit
- Enumerate all `#[contractimpl]` functions and confirm each state-mutating function has
  an explicit authorization check (require_admin, require_auth, or is_agent_registered)
- Add `SECURITY.md` documenting the full authorization model: roles, per-function auth
  table, multi-sig flow, and defense-in-depth measures

## Haroldwonder#253 — Multi-signature admin operations
- Add `AdminOperationType` enum (UpdateFee, WithdrawFees, Pause, Unpause) to `types.rs`
- Add `PendingOperation` struct with id, operation_type, proposer, approvers Vec, threshold,
  proposed_at, ttl_seconds, fee_bps, withdraw_to fields to `types.rs`
- Add new error variants to `errors.rs`: OperationNotFound(56), AlreadyApproved(57),
  OperationExpired(58), InvalidMultiSigThreshold(59)
- Add storage keys MultiSigThreshold, MultiSigTtlSeconds, OperationCounter, PendingOp(u64)
  and corresponding CRUD helpers to `storage.rs`
- Add `src/multisig.rs` module with: set_multisig_config, propose_operation,
  approve_operation (auto-executes at threshold), expire_operation, get_operation,
  and internal execute_operation dispatch
- Emit structured events: msig/proposed, msig/approved, msig/executed, msig/expired
  (all include SCHEMA_VERSION + ledger sequence/timestamp for indexer compatibility)
- Expose five new public contract functions in `lib.rs`:
  set_multisig_config, propose_operation, approve_operation, expire_operation,
  get_pending_operation
- Defaults: threshold=1 (single-admin backwards-compatible), TTL=86 400 s
…ime FX WebSocket (Haroldwonder#942 Haroldwonder#943 Haroldwonder#944)

### Haroldwonder#942 — React Native mobile app for senders
- Initialise Expo-based React Native project under `mobile/`
- Screens: Home, Send Money (3-step wizard), Transaction History, Transaction Detail, KYC Status
- Biometric confirmation (Face ID / fingerprint) via `expo-local-authentication` before every transfer
- Push notification registration (FCM + APNs) via `expo-notifications` with deep-link tap handling
- Service layer (`services/api.ts`) for remittance, KYC, and FX calls against the backend REST API
- Secure token storage via `expo-secure-store`
- Bottom-tab + stack navigation with `@react-navigation`

### Haroldwonder#943 — Compliance reporting dashboard for regulators
- DB migration adding `compliance_thresholds`, `compliance_flagged_remittances`, and `compliance_report_audit` tables
- `GET /api/compliance/report` — filtered by date range, status, currency, corridor; returns JSON or CSV (`csv-stringify`)
- `GET/POST /api/compliance/thresholds` — configurable per-corridor reporting thresholds
- `POST /api/compliance/flag` and `PATCH /api/compliance/flag/:id` — manual flag management
- `autoFlagIfAboveThreshold()` called on every new remittance to auto-flag above-threshold transfers
- Full audit trail written to `compliance_report_audit` on every report access (actor, IP, filters, row count)

### Haroldwonder#944 — Real-time FX rate WebSocket feed
- `socket.io` namespace `/fx-rates` mounted at path `/ws` on the existing HTTP server
- `FxRateWebSocketServer` pushes updates to subscribed rooms within 1 s of cache refresh
- `subscribe` / `unsubscribe` messages support per-pair filtering (`USD/PHP`, `USD/MXN`, ...)
- Rate-replay on subscribe: last known rate sent immediately to reconnecting clients
- `FxRateCache` emits `rate_updated` events (via injected `EventEmitter`) on every background refresh and new fetch
- Graceful shutdown: WebSocket server closed before PostgreSQL pool drain
- WebSocket protocol documented in `API.md`
- Add SEP-12 business KYC flow to AgentKycService (PUT/GET /customer)
- Store sep12_customer_id; sync anchor status via syncSep12Status()
- Add agent_kyc migration with sep12_customer_id column
- Gate on-chain agent registration behind approved KYC status
- Email notifications on status changes (submitted/under_review/approved/rejected)
- Add SMTP_* and SEP12_* vars to backend/.env.example
- 23 tests covering service and all REST endpoints
…e/pr-new

feat: Real-time fee preview, dark mode persistence, PDF export, and WCAG accessibility
…t-address-book-onboarding-translations

feat: Add wallet connection error handling, onboarding, address book, and Portuguese translations
…-896-897-898-899-test-suite

test: Add comprehensive test suites for issues Haroldwonder#896-899
…-chart

feat: add Soroban contract CI pipeline and Kubernetes Helm chart (Haroldwonder#917, Haroldwonder#918)
…tend-typescript-sdk-enhancements

Feature/frontend typescript sdk enhancements
…pi-enhancements-873-874-872-875

Feat/api enhancements 873 874 872 875
…losure-policy

docs: add security disclosure policy
…-updates-20260628

chore: update backend API and fx rate cache changes
feat: add sdk governance proposal heloer
…943-944-mobile-compliance-websocket

feat: React Native mobile app, compliance reporting, real-time FX WebSocket (Haroldwonder#942 Haroldwonder#943 Haroldwonder#944)
…c-onboarding

feat: agent KYC onboarding with SEP-12 business anchor integration
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…, audit log coverage, Grafana

Manually merged after resolving conflicts with main.
- sdk-bundle-size CI job + helm-lint both included
- createRemittanceBatch and batchCreateRemittances both preserved

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…+ FX rate provider failover

Manually merged after resolving conflicts with main.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tion, mock client, and npm release automation

Manually merged after resolving conflicts with main.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

Add performance regression benchmarks to CI