feat: benchmark CI, OWASP scanning, contract auth audit & multi-sig admin ops#1
Open
quartune wants to merge 576 commits into
Open
feat: benchmark CI, OWASP scanning, contract auth audit & multi-sig admin ops#1quartune wants to merge 576 commits into
quartune wants to merge 576 commits into
Conversation
…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.
…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>
…-migrations-env-health
…#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
…ux-improvements feat: E2E tests and UX improvements (Haroldwonder#900-Haroldwonder#903)
…-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>
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
Closes Haroldwonder#935, Haroldwonder#936, Haroldwonder#937, Haroldwonder#253
Haroldwonder#935 — Performance regression benchmarks in CI
.github/workflows/benchmark-ci.ymlrunscargo bench --features benchmarkson every push/PR touchingsrc/orbenches/Haroldwonder#936 — OWASP dependency vulnerability scanning
.github/workflows/security-audit.ymlrunsnpm audit --audit-level=highfor backend, frontend, api, examples; pluscargo auditfor Rust deps.github/dependabot.ymlconfigures weekly Dependabot PRs for all npm directories, the Cargo workspace, and GitHub Actions; minor/patch updates are grouped to reduce noiseHaroldwonder#937 — Smart contract authorization audit
#[contractimpl]functions and verified each state-mutating function has an explicit auth check (require_admin,require_auth, or agent registration check)SECURITY.mdwith the full authorization model: role table, per-function auth table, multi-sig flow description, and defence-in-depth summaryHaroldwonder#253 — Multi-signature admin operations
src/types.rs: newAdminOperationTypeenum (UpdateFee, WithdrawFees, Pause, Unpause) andPendingOperationstruct (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 keysMultiSigThreshold,MultiSigTtlSeconds,OperationCounter,PendingOp(u64)and CRUD helperssrc/multisig.rs: new module withset_multisig_config,propose_operation,approve_operation,expire_operation,get_operation, and internalexecute_operationdispatchsrc/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 APIset_multisig_configSecurity analysis (Haroldwonder#253)
require_admin(which callsrequire_authon-chain), preventing impersonationAlreadyApprovedis returned if the same admin tries to approve twicettl_secondsare swept out of storage on the nextapprove_operationor explicitexpire_operationcall — no dangling state accumulatesset_multisig_configis calledTest plan
initializethenset_multisig_config(2, 3600)propose_operation(UpdateFee, 300, None)as admin-1; verifymsig/proposed+msig/approvedevents, pending op storedapprove_operation(op_id)as admin-2; verifymsig/approved+msig/executed, fee updated, pending op removedpropose_operationand wait for TTL; callexpire_operation; verifymsig/expiredeventpropose_operationorapprove_operation(returnsUnauthorized)npm audit --audit-level=highlocally in each service directory; verify CI step matches