Skip to content

test(indexer-lag): add unit tests for IndexerLagService and IndexerLagGuard - #984

Open
oziginwambada wants to merge 65 commits into
Pulsefy:mainfrom
oziginwambada:feat/indexer-lag-monitoring-tests
Open

oziginwambada wants to merge 65 commits into
Pulsefy:mainfrom
oziginwambada:feat/indexer-lag-monitoring-tests

Conversation

@oziginwambada

Copy link
Copy Markdown

Summary

The IndexerLagService and IndexerLagGuard are critical components that monitor Horizon ledger lag and gate risky write flows when the indexer falls behind the network. Despite being fully implemented, they had zero unit tests, leaving the monitoring path completely unverified.

This PR adds comprehensive unit tests for both components.

Changes

indexer-lag.service.unit.spec.ts

Covers the full behaviour of IndexerLagService:

  • getStatus() — null ledgers on startup, lag below/above threshold, isLagging flag, isEnabled/isOverridden reflection, threshold exposure, history_latest_ledger fallback
  • isBlocked() — guard disabled, override active, lagging + guard enabled, not lagging, no ledger data yet
  • pollHorizon() — network ledger update, checkpoint update, no contract ID (skips checkpoint), Horizon fetch failure, non-OK HTTP status, DB error from checkpoint repo, empty body (no ledger field)
  • Metrics reportingrecordIndexerLag called with correct value, skipped when lag is null, setIndexerLagGuardStatus for all four states (0=disabled, 1=healthy, 2=overridden, 3=lagging)

indexer-lag.guard.unit.spec.ts

Covers the full behaviour of IndexerLagGuard:

  • No decorator — passes through without calling isBlocked()
  • Not blocked — allows the request
  • Blocked — throws ServiceUnavailableException with lag details in response
  • Metrics side-effectrecordIndexerLagGuardBlockedRequest called with correct method/route
  • Audit side-effectauditService.log called with correct actor (user ID or anonymous)
  • Reflector key — confirms REQUIRE_INDEXER_LAG_CHECK_KEY is checked on both handler and class

Testing

Tests follow the project's established *.unit.spec.ts pattern using NestJS TestingModule with jest mocks for all dependencies.

Closes #42
Closes #43
Closes #44
Closes #45

dependabot Bot and others added 30 commits August 10, 2026 10:45
Bumps the cargo-deps group in /app/contract with 1 update: [soroban-sdk](https://github.com/stellar/rs-soroban-sdk).


Updates `soroban-sdk` from 23.4.1 to 27.0.5
- [Release notes](https://github.com/stellar/rs-soroban-sdk/releases)
- [Commits](stellar/rs-soroban-sdk@v23.4.1...v27.0.5)

---
updated-dependencies:
- dependency-name: soroban-sdk
  dependency-version: 27.0.5
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: cargo-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps the npm-deps group with 92 updates:

| Package | From | To |
| --- | --- | --- |
| [node-fetch](https://github.com/node-fetch/node-fetch) | `2.7.0` | `3.3.2` |
| [toml](https://github.com/BinaryMuse/toml-node) | `3.0.0` | `5.0.0` |
| [turbo](https://github.com/vercel/turborepo) | `2.8.20` | `2.10.8` |
| [typescript](https://github.com/microsoft/TypeScript) | `5.3.3` | `7.0.2` |
| [@nestjs/common](https://github.com/nestjs/nest/tree/HEAD/packages/common) | `10.4.22` | `11.1.28` |
| [@nestjs/config](https://github.com/nestjs/config) | `3.3.0` | `4.0.4` |
| [@nestjs/core](https://github.com/nestjs/nest/tree/HEAD/packages/core) | `10.4.22` | `11.1.28` |
| [@nestjs/event-emitter](https://github.com/nestjs/event-emitter) | `3.0.1` | `3.1.0` |
| [@nestjs/platform-express](https://github.com/nestjs/nest/tree/HEAD/packages/platform-express) | `10.4.22` | `11.1.28` |
| [@nestjs/schedule](https://github.com/nestjs/schedule) | `3.0.4` | `6.1.3` |
| [@nestjs/swagger](https://github.com/nestjs/swagger) | `7.4.2` | `11.4.6` |
| [@sentry/nestjs](https://github.com/getsentry/sentry-javascript) | `10.46.0` | `10.69.0` |
| [@sentry/node](https://github.com/getsentry/sentry-javascript) | `10.46.0` | `10.69.0` |
| [@sentry/profiling-node](https://github.com/getsentry/sentry-javascript) | `10.46.0` | `10.69.0` |
| [@stellar/stellar-sdk](https://github.com/stellar/js-stellar-sdk) | `14.6.1` | `16.2.0` |
| [@supabase/supabase-js](https://github.com/supabase/supabase-js/tree/HEAD/packages/core/supabase-js) | `2.100.0` | `2.112.2` |
| [class-validator](https://github.com/typestack/class-validator) | `0.14.4` | `0.15.1` |
| [helmet](https://github.com/helmetjs/helmet) | `8.1.0` | `8.3.0` |
| [ipaddr.js](https://github.com/whitequark/ipaddr.js) | `2.4.0` | `2.5.0` |
| [joi](https://github.com/hapijs/joi) | `18.1.1` | `18.2.3` |
| [lru-cache](https://github.com/isaacs/node-lru-cache) | `11.3.5` | `11.5.2` |
| [reflect-metadata](https://github.com/rbuckton/reflect-metadata) | `0.1.14` | `0.2.2` |
| [uuid](https://github.com/uuidjs/uuid) | `9.0.1` | `14.0.1` |
| [@nestjs/cli](https://github.com/nestjs/nest-cli) | `10.4.9` | `11.0.24` |
| [@nestjs/testing](https://github.com/nestjs/nest/tree/HEAD/packages/testing) | `10.4.22` | `11.1.28` |
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `20.19.37` | `26.1.2` |
| [@types/uuid](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/uuid) | `9.0.8` | `11.0.0` |
| [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `6.21.0` | `8.66.0` |
| [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `6.21.0` | `8.66.0` |
| [eslint](https://github.com/eslint/eslint) | `8.57.1` | `10.8.0` |
| [fast-check](https://github.com/dubzzz/fast-check/tree/HEAD/packages/fast-check) | `4.8.0` | `4.9.0` |
| [jest](https://github.com/jestjs/jest/tree/HEAD/packages/jest) | `29.7.0` | `30.4.2` |
| [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) | `29.5.14` | `30.0.0` |
| [supertest](https://github.com/ladjs/supertest) | `6.3.4` | `7.2.2` |
| [@types/supertest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/supertest) | `2.0.16` | `7.2.1` |
| [ts-jest](https://github.com/kulshekhar/ts-jest) | `29.4.6` | `29.4.12` |
| [i18next](https://github.com/i18next/i18next) | `23.16.8` | `26.3.6` |
| [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `1.11.0` | `1.30.0` |
| [next](https://github.com/vercel/next.js) | `15.5.9` | `16.3.0` |
| [react](https://github.com/react/react/tree/HEAD/packages/react) | `19.1.0` | `19.2.8` |
| [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) | `19.1.17` | `19.2.18` |
| [react-dom](https://github.com/react/react/tree/HEAD/packages/react-dom) | `19.1.0` | `19.2.8` |
| [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) | `19.2.3` | `19.2.4` |
| [react-i18next](https://github.com/i18next/react-i18next) | `13.5.0` | `17.0.11` |
| [react-qr-code](https://github.com/rosskhanas/react-qr-code) | `2.0.18` | `2.2.0` |
| [recharts](https://github.com/recharts/recharts) | `3.8.1` | `3.10.1` |
| [@eslint/eslintrc](https://github.com/eslint/eslintrc) | `3.3.5` | `3.3.6` |
| [@tailwindcss/postcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss) | `4.2.2` | `4.3.3` |
| [@testing-library/jest-dom](https://github.com/testing-library/jest-dom) | `6.9.1` | `7.0.0` |
| [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) | `15.5.9` | `16.3.0` |
| [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) | `4.2.2` | `4.3.3` |
| [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `3.2.6` | `4.1.10` |
| [@react-native-async-storage/async-storage](https://github.com/react-native-async-storage/async-storage/tree/HEAD/packages/async-storage) | `1.24.0` | `3.1.1` |
| [@react-native-community/cli](https://github.com/react-native-community/cli/tree/HEAD/packages/cli) | `20.1.3` | `20.2.0` |
| [@react-native-community/netinfo](https://github.com/react-native-netinfo/react-native-netinfo) | `11.4.1` | `12.0.1` |
| [@react-navigation/bottom-tabs](https://github.com/react-navigation/react-navigation/tree/HEAD/packages/bottom-tabs) | `7.15.7` | `7.18.15` |
| [@react-navigation/elements](https://github.com/react-navigation/react-navigation/tree/HEAD/packages/elements) | `2.9.12` | `2.9.37` |
| [@react-navigation/native](https://github.com/react-navigation/react-navigation/tree/HEAD/packages/native) | `7.2.0` | `7.3.15` |
| [@shopify/flash-list](https://github.com/Shopify/flash-list) | `1.8.3` | `2.3.2` |
| [@stellar/stellar-base](https://github.com/stellar/js-stellar-base) | `14.1.0` | `15.0.0` |
| [expo](https://github.com/expo/expo/tree/HEAD/packages/expo) | `54.0.33` | `57.0.11` |
| [expo-av](https://github.com/expo/expo/tree/HEAD/packages/expo-av) | `13.3.0` | `16.0.8` |
| [expo-background-task](https://github.com/expo/expo/tree/HEAD/packages/expo-background-task) | `55.0.17` | `57.0.8` |
| [expo-camera](https://github.com/expo/expo/tree/HEAD/packages/expo-camera) | `17.0.10` | `57.0.3` |
| [expo-clipboard](https://github.com/expo/expo/tree/HEAD/packages/expo-clipboard) | `8.0.8` | `57.0.1` |
| [expo-constants](https://github.com/expo/expo/tree/HEAD/packages/expo-constants) | `18.0.13` | `57.0.9` |
| [expo-crypto](https://github.com/expo/expo/tree/HEAD/packages/expo-crypto) | `55.0.10` | `57.0.1` |
| [expo-file-system](https://github.com/expo/expo/tree/HEAD/packages/expo-file-system) | `19.0.21` | `57.0.2` |
| [expo-font](https://github.com/expo/expo/tree/HEAD/packages/expo-font) | `14.0.11` | `57.0.1` |
| [expo-haptics](https://github.com/expo/expo/tree/HEAD/packages/expo-haptics) | `15.0.8` | `57.0.1` |
| [expo-image](https://github.com/expo/expo/tree/HEAD/packages/expo-image) | `3.0.11` | `57.0.2` |
| [expo-linking](https://github.com/expo/expo/tree/HEAD/packages/expo-linking) | `8.0.11` | `57.0.5` |
| [expo-local-authentication](https://github.com/expo/expo/tree/HEAD/packages/expo-local-authentication) | `55.0.9` | `57.0.2` |
| [expo-notifications](https://github.com/expo/expo/tree/HEAD/packages/expo-notifications) | `55.0.20` | `57.0.9` |
| [expo-router](https://github.com/expo/expo/tree/HEAD/packages/expo-router) | `6.0.23` | `57.0.11` |
| [expo-secure-store](https://github.com/expo/expo/tree/HEAD/packages/expo-secure-store) | `55.0.9` | `57.0.1` |
| [expo-sharing](https://github.com/expo/expo/tree/HEAD/packages/expo-sharing) | `55.0.15-canary-20260328-2049187` | `57.0.10` |
| [expo-splash-screen](https://github.com/expo/expo/tree/HEAD/packages/expo-splash-screen) | `31.0.13` | `57.0.5` |
| [expo-status-bar](https://github.com/expo/expo/tree/HEAD/packages/expo-status-bar) | `3.0.9` | `57.0.1` |
| [expo-symbols](https://github.com/expo/expo/tree/HEAD/packages/expo-symbols) | `1.0.8` | `57.0.2` |
| [expo-system-ui](https://github.com/expo/expo/tree/HEAD/packages/expo-system-ui) | `6.0.9` | `57.0.2` |
| [expo-task-manager](https://github.com/expo/expo/tree/HEAD/packages/expo-task-manager) | `55.0.15` | `57.0.8` |
| [expo-web-browser](https://github.com/expo/expo/tree/HEAD/packages/expo-web-browser) | `15.0.10` | `57.0.2` |
| [react-native](https://github.com/react/react-native/tree/HEAD/packages/react-native) | `0.81.5` | `0.86.2` |
| [react-native-gesture-handler](https://github.com/software-mansion/react-native-gesture-handler) | `2.28.0` | `3.1.0` |
| [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated/tree/HEAD/packages/react-native-reanimated) | `4.1.7` | `4.5.3` |
| [react-native-safe-area-context](https://github.com/AppAndFlow/react-native-safe-area-context) | `5.6.2` | `5.8.1` |
| [react-native-screens](https://github.com/software-mansion/react-native-screens) | `4.16.0` | `4.27.0` |
| [react-native-worklets](https://github.com/software-mansion/react-native-reanimated/tree/HEAD/packages/react-native-worklets) | `0.5.1` | `0.11.3` |
| [eslint-config-expo](https://github.com/expo/expo/tree/HEAD/packages/eslint-config-expo) | `10.0.0` | `57.0.1` |
| [jest-expo](https://github.com/expo/expo/tree/HEAD/packages/jest-expo) | `54.0.17` | `57.0.3` |
| [react-test-renderer](https://github.com/react/react/tree/HEAD/packages/react-test-renderer) | `19.2.4` | `19.2.8` |


Updates `node-fetch` from 2.7.0 to 3.3.2
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Commits](node-fetch/node-fetch@v2.7.0...v3.3.2)

Updates `toml` from 3.0.0 to 5.0.0
- [Changelog](https://github.com/BinaryMuse/toml-node/blob/master/CHANGELOG.md)
- [Commits](BinaryMuse/toml-node@v3.0.0...v5.0.0)

Updates `turbo` from 2.8.20 to 2.10.8
- [Release notes](https://github.com/vercel/turborepo/releases)
- [Changelog](https://github.com/vercel/turborepo/blob/main/RELEASE.md)
- [Commits](vercel/turborepo@v2.8.20...v2.10.8)

Updates `typescript` from 5.3.3 to 7.0.2
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Commits](https://github.com/microsoft/TypeScript/commits)

Updates `@nestjs/common` from 10.4.22 to 11.1.28
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.28/packages/common)

Updates `@nestjs/config` from 3.3.0 to 4.0.4
- [Release notes](https://github.com/nestjs/config/releases)
- [Commits](nestjs/config@3.3.0...4.0.4)

Updates `@nestjs/core` from 10.4.22 to 11.1.28
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.28/packages/core)

Updates `@nestjs/event-emitter` from 3.0.1 to 3.1.0
- [Release notes](https://github.com/nestjs/event-emitter/releases)
- [Commits](nestjs/event-emitter@3.0.1...3.1.0)

Updates `@nestjs/platform-express` from 10.4.22 to 11.1.28
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.28/packages/platform-express)

Updates `@nestjs/schedule` from 3.0.4 to 6.1.3
- [Release notes](https://github.com/nestjs/schedule/releases)
- [Commits](nestjs/schedule@3.0.4...6.1.3)

Updates `@nestjs/swagger` from 7.4.2 to 11.4.6
- [Release notes](https://github.com/nestjs/swagger/releases)
- [Commits](nestjs/swagger@7.4.2...11.4.6)

Updates `@sentry/nestjs` from 10.46.0 to 10.69.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/10.69.0/CHANGELOG.md)
- [Commits](getsentry/sentry-javascript@10.46.0...10.69.0)

Updates `@sentry/node` from 10.46.0 to 10.69.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/10.69.0/CHANGELOG.md)
- [Commits](getsentry/sentry-javascript@10.46.0...10.69.0)

Updates `@sentry/profiling-node` from 10.46.0 to 10.69.0
- [Release notes](https://github.com/getsentry/sentry-javascript/releases)
- [Changelog](https://github.com/getsentry/sentry-javascript/blob/10.69.0/CHANGELOG.md)
- [Commits](getsentry/sentry-javascript@10.46.0...10.69.0)

Updates `@stellar/stellar-sdk` from 14.6.1 to 16.2.0
- [Release notes](https://github.com/stellar/js-stellar-sdk/releases)
- [Changelog](https://github.com/stellar/js-stellar-sdk/blob/main/CHANGELOG.md)
- [Commits](stellar/js-stellar-sdk@v14.6.1...v16.2.0)

Updates `@supabase/supabase-js` from 2.100.0 to 2.112.2
- [Release notes](https://github.com/supabase/supabase-js/releases)
- [Changelog](https://github.com/supabase/supabase-js/blob/master/packages/core/supabase-js/CHANGELOG.md)
- [Commits](https://github.com/supabase/supabase-js/commits/v2.112.2/packages/core/supabase-js)

Updates `class-validator` from 0.14.4 to 0.15.1
- [Release notes](https://github.com/typestack/class-validator/releases)
- [Changelog](https://github.com/typestack/class-validator/blob/develop/CHANGELOG.md)
- [Commits](typestack/class-validator@v0.14.4...v0.15.1)

Updates `helmet` from 8.1.0 to 8.3.0
- [Changelog](https://github.com/helmetjs/helmet/blob/main/CHANGELOG.md)
- [Commits](helmetjs/helmet@v8.1.0...v8.3.0)

Updates `ipaddr.js` from 2.4.0 to 2.5.0
- [Changelog](https://github.com/whitequark/ipaddr.js/blob/main/Changes.md)
- [Commits](https://github.com/whitequark/ipaddr.js/commits)

Updates `joi` from 18.1.1 to 18.2.3
- [Commits](hapijs/joi@v18.1.1...v18.2.3)

Updates `lru-cache` from 11.3.5 to 11.5.2
- [Changelog](https://github.com/isaacs/node-lru-cache/blob/main/CHANGELOG.md)
- [Commits](isaacs/node-lru-cache@v11.3.5...v11.5.2)

Updates `reflect-metadata` from 0.1.14 to 0.2.2
- [Release notes](https://github.com/rbuckton/reflect-metadata/releases)
- [Commits](https://github.com/rbuckton/reflect-metadata/commits)

Updates `uuid` from 9.0.1 to 14.0.1
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](uuidjs/uuid@v9.0.1...v14.0.1)

Updates `@nestjs/cli` from 10.4.9 to 11.0.24
- [Release notes](https://github.com/nestjs/nest-cli/releases)
- [Commits](nestjs/nest-cli@10.4.9...11.0.24)

Updates `@nestjs/testing` from 10.4.22 to 11.1.28
- [Release notes](https://github.com/nestjs/nest/releases)
- [Commits](https://github.com/nestjs/nest/commits/v11.1.28/packages/testing)

Updates `@types/node` from 20.19.37 to 26.1.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Updates `@types/uuid` from 9.0.8 to 11.0.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/uuid)

Updates `@typescript-eslint/eslint-plugin` from 6.21.0 to 8.66.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.66.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 6.21.0 to 8.66.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.66.0/packages/parser)

Updates `eslint` from 8.57.1 to 10.8.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](eslint/eslint@v8.57.1...v10.8.0)

Updates `fast-check` from 4.8.0 to 4.9.0
- [Release notes](https://github.com/dubzzz/fast-check/releases)
- [Changelog](https://github.com/dubzzz/fast-check/blob/main/packages/fast-check/CHANGELOG.md)
- [Commits](https://github.com/dubzzz/fast-check/commits/v4.9.0/packages/fast-check)

Updates `jest` from 29.7.0 to 30.4.2
- [Release notes](https://github.com/jestjs/jest/releases)
- [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jestjs/jest/commits/v30.4.2/packages/jest)

Updates `@types/jest` from 29.5.14 to 30.0.0
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest)

Updates `supertest` from 6.3.4 to 7.2.2
- [Release notes](https://github.com/ladjs/supertest/releases)
- [Commits](forwardemail/supertest@v6.3.4...v7.2.2)

Updates `@types/supertest` from 2.0.16 to 7.2.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/supertest)

Updates `ts-jest` from 29.4.6 to 29.4.12
- [Release notes](https://github.com/kulshekhar/ts-jest/releases)
- [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md)
- [Commits](kulshekhar/ts-jest@v29.4.6...v29.4.12)

Updates `i18next` from 23.16.8 to 26.3.6
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](i18next/i18next@v23.16.8...v26.3.6)

Updates `lucide-react` from 1.11.0 to 1.30.0
- [Release notes](https://github.com/lucide-icons/lucide/releases)
- [Commits](https://github.com/lucide-icons/lucide/commits/1.30.0/packages/lucide-react)

Updates `next` from 15.5.9 to 16.3.0
- [Release notes](https://github.com/vercel/next.js/releases)
- [Commits](vercel/next.js@v15.5.9...v16.3.0)

Updates `react` from 19.1.0 to 19.2.8
- [Release notes](https://github.com/react/react/releases)
- [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/react/react/commits/v19.2.8/packages/react)

Updates `@types/react` from 19.1.17 to 19.2.18
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `react-dom` from 19.1.0 to 19.2.8
- [Release notes](https://github.com/react/react/releases)
- [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/react/react/commits/v19.2.8/packages/react-dom)

Updates `@types/react-dom` from 19.2.3 to 19.2.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

Updates `react-i18next` from 13.5.0 to 17.0.11
- [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md)
- [Commits](i18next/react-i18next@v13.5.0...v17.0.11)

Updates `react-qr-code` from 2.0.18 to 2.2.0
- [Release notes](https://github.com/rosskhanas/react-qr-code/releases)
- [Changelog](https://github.com/rosskhanas/react-qr-code/blob/master/CHANGELOG.md)
- [Commits](rosskhanas/react-qr-code@2.0.18...2.2.0)

Updates `recharts` from 3.8.1 to 3.10.1
- [Release notes](https://github.com/recharts/recharts/releases)
- [Changelog](https://github.com/recharts/recharts/blob/main/CHANGELOG.md)
- [Commits](recharts/recharts@v3.8.1...v3.10.1)

Updates `@eslint/eslintrc` from 3.3.5 to 3.3.6
- [Release notes](https://github.com/eslint/eslintrc/releases)
- [Changelog](https://github.com/eslint/eslintrc/blob/main/CHANGELOG.md)
- [Commits](eslint/eslintrc@eslintrc-v3.3.5...eslintrc-v3.3.6)

Updates `@tailwindcss/postcss` from 4.2.2 to 4.3.3
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/packages/@tailwindcss-postcss)

Updates `@testing-library/jest-dom` from 6.9.1 to 7.0.0
- [Release notes](https://github.com/testing-library/jest-dom/releases)
- [Changelog](https://github.com/testing-library/jest-dom/blob/main/CHANGELOG.md)
- [Commits](testing-library/jest-dom@v6.9.1...v7.0.0)

Updates `@types/react` from 19.1.17 to 19.2.18
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react)

Updates `@types/react-dom` from 19.2.3 to 19.2.4
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

Updates `eslint-config-next` from 15.5.9 to 16.3.0
- [Release notes](https://github.com/vercel/next.js/releases)
- [Commits](https://github.com/vercel/next.js/commits/v16.3.0/packages/eslint-config-next)

Updates `tailwindcss` from 4.2.2 to 4.3.3
- [Release notes](https://github.com/tailwindlabs/tailwindcss/releases)
- [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.3/packages/tailwindcss)

Updates `vitest` from 3.2.6 to 4.1.10
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md)
- [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.10/packages/vitest)

Updates `@react-native-async-storage/async-storage` from 1.24.0 to 3.1.1
- [Release notes](https://github.com/react-native-async-storage/async-storage/releases)
- [Changelog](https://github.com/react-native-async-storage/async-storage/blob/main/packages/async-storage/CHANGELOG.md)
- [Commits](https://github.com/react-native-async-storage/async-storage/commits/@react-native-async-storage/async-storage@3.1.1/packages/async-storage)

Updates `@react-native-community/cli` from 20.1.3 to 20.2.0
- [Release notes](https://github.com/react-native-community/cli/releases)
- [Changelog](https://github.com/react-native-community/cli/blob/main/packages/cli/CHANGELOG.md)
- [Commits](https://github.com/react-native-community/cli/commits/v20.2.0/packages/cli)

Updates `@react-native-community/netinfo` from 11.4.1 to 12.0.1
- [Release notes](https://github.com/react-native-netinfo/react-native-netinfo/releases)
- [Changelog](https://github.com/react-native-netinfo/react-native-netinfo/blob/master/CHANGELOG.md)
- [Commits](react-native-netinfo/react-native-netinfo@v11.4.1...v12.0.1)

Updates `@react-navigation/bottom-tabs` from 7.15.7 to 7.18.15
- [Release notes](https://github.com/react-navigation/react-navigation/releases)
- [Changelog](https://github.com/react-navigation/react-navigation/blob/@react-navigation/bottom-tabs@7.18.15/packages/bottom-tabs/CHANGELOG.md)
- [Commits](https://github.com/react-navigation/react-navigation/commits/@react-navigation/bottom-tabs@7.18.15/packages/bottom-tabs)

Updates `@react-navigation/elements` from 2.9.12 to 2.9.37
- [Release notes](https://github.com/react-navigation/react-navigation/releases)
- [Changelog](https://github.com/react-navigation/react-navigation/blob/@react-navigation/elements@2.9.37/packages/elements/CHANGELOG.md)
- [Commits](https://github.com/react-navigation/react-navigation/commits/@react-navigation/elements@2.9.37/packages/elements)

Updates `@react-navigation/native` from 7.2.0 to 7.3.15
- [Release notes](https://github.com/react-navigation/react-navigation/releases)
- [Changelog](https://github.com/react-navigation/react-navigation/blob/@react-navigation/native@7.3.15/packages/native/CHANGELOG.md)
- [Commits](https://github.com/react-navigation/react-navigation/commits/@react-navigation/native@7.3.15/packages/native)

Updates `@shopify/flash-list` from 1.8.3 to 2.3.2
- [Release notes](https://github.com/Shopify/flash-list/releases)
- [Changelog](https://github.com/Shopify/flash-list/blob/main/CHANGELOG.md)
- [Commits](Shopify/flash-list@v1.8.3...v2.3.2)

Updates `@stellar/stellar-base` from 14.1.0 to 15.0.0
- [Release notes](https://github.com/stellar/js-stellar-base/releases)
- [Changelog](https://github.com/stellar/js-stellar-base/blob/master/CHANGELOG.md)
- [Commits](stellar/js-stellar-base@v14.1.0...v15.0.0)

Updates `expo` from 54.0.33 to 57.0.11
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo)

Updates `expo-av` from 13.3.0 to 16.0.8
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-av)

Updates `expo-background-task` from 55.0.17 to 57.0.8
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-background-task/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-background-task)

Updates `expo-camera` from 17.0.10 to 57.0.3
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-camera/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-camera)

Updates `expo-clipboard` from 8.0.8 to 57.0.1
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-clipboard/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-clipboard)

Updates `expo-constants` from 18.0.13 to 57.0.9
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-constants)

Updates `expo-crypto` from 55.0.10 to 57.0.1
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-crypto/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-crypto)

Updates `expo-file-system` from 19.0.21 to 57.0.2
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-file-system)

Updates `expo-font` from 14.0.11 to 57.0.1
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-font/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-font)

Updates `expo-haptics` from 15.0.8 to 57.0.1
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-haptics/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-haptics)

Updates `expo-image` from 3.0.11 to 57.0.2
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-image/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-image)

Updates `expo-linking` from 8.0.11 to 57.0.5
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-linking)

Updates `expo-local-authentication` from 55.0.9 to 57.0.2
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-local-authentication/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-local-authentication)

Updates `expo-notifications` from 55.0.20 to 57.0.9
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-notifications/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-notifications)

Updates `expo-router` from 6.0.23 to 57.0.11
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-router)

Updates `expo-secure-store` from 55.0.9 to 57.0.1
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-secure-store/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-secure-store)

Updates `expo-sharing` from 55.0.15-canary-20260328-2049187 to 57.0.10
- [Changelog](https://github.com/expo/expo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-sharing)

Updates `expo-splash-screen` from 31.0.13 to 57.0.5
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-splash-screen/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-splash-screen)

Updates `expo-status-bar` from 3.0.9 to 57.0.1
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-status-bar/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-status-bar)

Updates `expo-symbols` from 1.0.8 to 57.0.2
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-symbols/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-symbols)

Updates `expo-system-ui` from 6.0.9 to 57.0.2
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-system-ui/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-system-ui)

Updates `expo-task-manager` from 55.0.15 to 57.0.8
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-task-manager/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-task-manager)

Updates `expo-web-browser` from 15.0.10 to 57.0.2
- [Changelog](https://github.com/expo/expo/blob/main/packages/expo-web-browser/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/expo-web-browser)

Updates `react-native` from 0.81.5 to 0.86.2
- [Release notes](https://github.com/react/react-native/releases)
- [Changelog](https://github.com/react/react-native/blob/main/CHANGELOG.md)
- [Commits](https://github.com/react/react-native/commits/v0.86.2/packages/react-native)

Updates `react-native-gesture-handler` from 2.28.0 to 3.1.0
- [Release notes](https://github.com/software-mansion/react-native-gesture-handler/releases)
- [Commits](software-mansion/react-native-gesture-handler@2.28.0...v3.1.0)

Updates `react-native-reanimated` from 4.1.7 to 4.5.3
- [Release notes](https://github.com/software-mansion/react-native-reanimated/releases)
- [Changelog](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-reanimated/RELEASE.md)
- [Commits](https://github.com/software-mansion/react-native-reanimated/commits/4.5.3/packages/react-native-reanimated)

Updates `react-native-safe-area-context` from 5.6.2 to 5.8.1
- [Release notes](https://github.com/AppAndFlow/react-native-safe-area-context/releases)
- [Commits](appandflow/react-native-safe-area-context@v5.6.2...v5.8.1)

Updates `react-native-screens` from 4.16.0 to 4.27.0
- [Release notes](https://github.com/software-mansion/react-native-screens/releases)
- [Commits](software-mansion/react-native-screens@4.16.0...4.27.0)

Updates `react-native-worklets` from 0.5.1 to 0.11.3
- [Release notes](https://github.com/software-mansion/react-native-reanimated/releases)
- [Commits](https://github.com/software-mansion/react-native-reanimated/commits/worklets-0.11.3/packages/react-native-worklets)

Updates `eslint-config-expo` from 10.0.0 to 57.0.1
- [Changelog](https://github.com/expo/expo/blob/main/packages/eslint-config-expo/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/eslint-config-expo)

Updates `jest-expo` from 54.0.17 to 57.0.3
- [Changelog](https://github.com/expo/expo/blob/main/packages/jest-expo/CHANGELOG.md)
- [Commits](https://github.com/expo/expo/commits/HEAD/packages/jest-expo)

Updates `react-test-renderer` from 19.2.4 to 19.2.8
- [Release notes](https://github.com/react/react/releases)
- [Changelog](https://github.com/react/react/blob/main/CHANGELOG.md)
- [Commits](https://github.com/react/react/commits/v19.2.8/packages/react-test-renderer)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-version: 3.3.2
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: toml
  dependency-version: 5.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: turbo
  dependency-version: 2.10.8
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: typescript
  dependency-version: 7.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@nestjs/common"
  dependency-version: 11.1.28
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@nestjs/config"
  dependency-version: 4.0.4
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@nestjs/core"
  dependency-version: 11.1.28
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@nestjs/event-emitter"
  dependency-version: 3.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: "@nestjs/platform-express"
  dependency-version: 11.1.28
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@nestjs/schedule"
  dependency-version: 6.1.3
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@nestjs/swagger"
  dependency-version: 11.4.6
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@sentry/nestjs"
  dependency-version: 10.69.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: "@sentry/node"
  dependency-version: 10.69.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: "@sentry/profiling-node"
  dependency-version: 10.69.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: "@stellar/stellar-sdk"
  dependency-version: 16.2.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@supabase/supabase-js"
  dependency-version: 2.112.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: class-validator
  dependency-version: 0.15.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: helmet
  dependency-version: 8.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: ipaddr.js
  dependency-version: 2.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: joi
  dependency-version: 18.2.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: lru-cache
  dependency-version: 11.5.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: reflect-metadata
  dependency-version: 0.2.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: uuid
  dependency-version: 14.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@nestjs/cli"
  dependency-version: 11.0.24
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@nestjs/testing"
  dependency-version: 11.1.28
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@types/node"
  dependency-version: 26.1.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@types/uuid"
  dependency-version: 11.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.66.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.66.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: eslint
  dependency-version: 10.8.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: fast-check
  dependency-version: 4.9.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: jest
  dependency-version: 30.4.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@types/jest"
  dependency-version: 30.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: supertest
  dependency-version: 7.2.2
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@types/supertest"
  dependency-version: 7.2.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: ts-jest
  dependency-version: 29.4.12
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-deps
- dependency-name: i18next
  dependency-version: 26.3.6
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: lucide-react
  dependency-version: 1.30.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: next
  dependency-version: 16.3.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: react
  dependency-version: 19.2.8
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: "@types/react"
  dependency-version: 19.2.18
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: react-dom
  dependency-version: 19.2.8
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-deps
- dependency-name: react-i18next
  dependency-version: 17.0.11
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: react-qr-code
  dependency-version: 2.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: recharts
  dependency-version: 3.10.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: "@eslint/eslintrc"
  dependency-version: 3.3.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-deps
- dependency-name: "@tailwindcss/postcss"
  dependency-version: 4.3.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: "@testing-library/jest-dom"
  dependency-version: 7.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@types/react"
  dependency-version: 19.2.18
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: "@types/react-dom"
  dependency-version: 19.2.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-deps
- dependency-name: eslint-config-next
  dependency-version: 16.3.0
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: tailwindcss
  dependency-version: 4.3.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: vitest
  dependency-version: 4.1.10
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@react-native-async-storage/async-storage"
  dependency-version: 3.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@react-native-community/cli"
  dependency-version: 20.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: "@react-native-community/netinfo"
  dependency-version: 12.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@react-navigation/bottom-tabs"
  dependency-version: 7.18.15
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: "@react-navigation/elements"
  dependency-version: 2.9.37
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: npm-deps
- dependency-name: "@react-navigation/native"
  dependency-version: 7.3.15
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: "@shopify/flash-list"
  dependency-version: 2.3.2
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: "@stellar/stellar-base"
  dependency-version: 15.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo
  dependency-version: 57.0.11
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-av
  dependency-version: 16.0.8
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-background-task
  dependency-version: 57.0.8
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-camera
  dependency-version: 57.0.3
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-clipboard
  dependency-version: 57.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-constants
  dependency-version: 57.0.9
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-crypto
  dependency-version: 57.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-file-system
  dependency-version: 57.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-font
  dependency-version: 57.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-haptics
  dependency-version: 57.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-image
  dependency-version: 57.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-linking
  dependency-version: 57.0.5
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-local-authentication
  dependency-version: 57.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-notifications
  dependency-version: 57.0.9
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-router
  dependency-version: 57.0.11
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-secure-store
  dependency-version: 57.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-sharing
  dependency-version: 57.0.10
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-splash-screen
  dependency-version: 57.0.5
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-status-bar
  dependency-version: 57.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-symbols
  dependency-version: 57.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-system-ui
  dependency-version: 57.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-task-manager
  dependency-version: 57.0.8
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: expo-web-browser
  dependency-version: 57.0.2
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: react-native
  dependency-version: 0.86.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: react-native-gesture-handler
  dependency-version: 3.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: react-native-reanimated
  dependency-version: 4.5.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: react-native-safe-area-context
  dependency-version: 5.8.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: react-native-screens
  dependency-version: 4.27.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: react-native-worklets
  dependency-version: 0.11.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: npm-deps
- dependency-name: eslint-config-expo
  dependency-version: 57.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: jest-expo
  dependency-version: 57.0.3
  dependency-type: direct:development
  update-type: version-update:semver-major
  dependency-group: npm-deps
- dependency-name: react-test-renderer
  dependency-version: 19.2.8
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: npm-deps
...

Signed-off-by: dependabot[bot] <support@github.com>
…pport, and milestone tracking

Implements four major feature enhancements:

1. Emergency Mode with Irreversible Halt (Pulsefy#120)
   - activate_emergency_mode() documented as admin-only irreversible operation
   - All operations blocked after activation
   - Emergency mode activation emits EmergencyModeActivatedEvent
   - Recovery requires contract upgrade

2. Contract Metadata Endpoint for Client Compatibility (Pulsefy#121)
   - get_deployment_metadata() returns version, wasm_hash, event_schema_version, contract_id
   - get_version() returns stored contract version
   - Enables clients to detect version mismatches on startup
   - Metadata includes event schema version for indexers

3. Deposit with Memo and Metadata (Pulsefy#122)
   - deposit() and deposit_with_commitment() now accept optional memo parameter
   - Memo stored in EscrowEntry (max 1024 bytes)
   - Memo visible to owner and recipient
   - Memo included in get_escrow_details() response
   - Memo queryable through PrivacyAwareEscrowView

4. Escrow Partial Payment with Milestone Tracking (Pulsefy#123)
   - deposit_partial() supports optional milestones array
   - Milestone struct tracks id, description, amount, and completion status
   - partial_payment() automatically marks milestones as completed
   - MilestoneCompletedEvent emitted when milestone payment threshold reached
   - Remaining amount properly calculated for each partial payment
   - Final milestone completion triggers EscrowFinalizedEvent

Changes:
- types.rs: Added Memo and Milestone structs, updated EscrowEntry and PrivacyAwareEscrowView
- escrow.rs: Updated deposit functions to accept memo parameter; enhanced partial_payment with milestone tracking
- events.rs: Added MilestoneCompletedEvent and publish_milestone_completed function
- lib.rs: Updated function signatures and calls for deposit, deposit_with_commitment, and deposit_partial

Closes Pulsefy#120
Closes Pulsefy#121
Closes Pulsefy#122
Closes Pulsefy#123
…, oracle dynamic fees, and upgrade window with validation

This commit addresses four major feature implementations:

## Task Pulsefy#108: Hook Registry with Callback Validation
- Added hook contract interface validation in register_hook()
- Implemented hook whitelist enforcement (HookNotAllowed error handling)
- Events filtered by hook subscription - only registered hooks are invoked
- Hook timeout enforcement: logs warning if execution exceeds 5 seconds
- Failed hooks do not block main flow (errors swallowed in invoke_hooks)
- Hook events logged for audit: HookRegistered, HookUnregistered, HookInvocationFailed, HookTimeoutWarning
- Added validate_hook_contract() to prevent self-registration
- Enhanced hook invocation with timeout tracking and error logging

## Task Pulsefy#109: Per-Asset Fee Configuration with Overrides
- set_per_asset_fee() accepts token and PerAssetFeeConfig
- Fee lookup by token address via get_per_asset_fee()
- Fallback to global fee config if no per-asset override exists
- Admin/Operator roles required for configuration
- Events emitted on change via publish_per_asset_fee_set()
- get_per_asset_fee view fully accessible from contract interface

## Task Pulsefy#110: Oracle-Priced Dynamic Fees
- record_oracle_price() accepts price in micros (1_000_000 = 1 USD)
- Price freshness validated with max 1 hour (3600 seconds) threshold
- Added validation in set_oracle_fee_config() to enforce max staleness threshold
- Fee calculation uses oracle price when configured and fresh
- Fallback to static fees if oracle is stale or unavailable
- Admin/Operator can update price via record_oracle_price()
- Events emitted for price changes via publish_oracle_price_updated()

## Task Pulsefy#111: Upgrade Window with Time-Based Restrictions
- set_upgrade_window() now validates start < end (returns error when end != 0 and end <= start)
- start_upgrade() blocked outside active upgrade window
- Window stored on-chain in persistent storage
- UpgradeWindowChanged event emitted on window changes
- Admin can clear window by setting start = 0
- View get_upgrade_window() returns (start, end) tuple

### Files Modified:
- admin.rs: Enhanced upgrade window validation, oracle config validation, window event emission
- events.rs: Added UpgradeWindowChangedEvent and publish_upgrade_window_changed()
- hook.rs: Enhanced register_hook with validation, added logging, timeout tracking in invoke_hooks
- storage.rs: Changed set_upgrade_window() to return Result and validate parameters

Closes Pulsefy#108 Pulsefy#109 Pulsefy#110 Pulsefy#111
…nsions, nonce registry enhancements, and dispute evidence submission

## Summary

This commit implements four major feature enhancements to the QuickEx smart contract:

### Task Pulsefy#112: Stealth Address Privacy v2
- Stealth address system with ephemeral key registration and withdrawal
- Funds locked under one-time stealth addresses derived via Diffie-Hellman
- Privacy-preserving: recipient's main address never linked on-chain
- Events emitted for registration (EphemeralKeyRegistered) and withdrawal (StealthWithdrawn)
- Full nonce-based replay protection for stealth operations

### Task Pulsefy#113: Escrow Extension with TTL Renewal
- New `extend_escrow_expiry()` function for configurable time extensions
- Tracks extension count per escrow with maximum limits (e.g., 3 extensions)
- Enforces maximum total lifetime constraints (e.g., cannot exceed original creation + max_lifetime)
- New storage type `EscrowExtension` records extension history
- Events emitted for each extension (EscrowExtensionApplied)
- Works with both pending and disputed escrows

### Task Pulsefy#114: Nonce Registry for Replay Protection
- Per-signer, per-action nonce uniqueness enforcement via `verify_and_consume()`
- Canonical v2 signed payload format with domain separation by action type
- Nonce expiry via `valid_until` ledger timestamp (prevents replay)
- View function `is_nonce_used()` for off-chain pre-flight checks
- 6-month TTL in persistent storage prevents unbounded registry growth
- Backward compatibility with legacy v1 nonce format

### Task Pulsefy#115: Escrow Dispute with Evidence Submission
- New `submit_dispute_evidence()` function for evidence hash submission
- Evidence stored on-chain with submitter address and timestamp
- New storage type `DisputeEvidence` tracks evidence submissions
- Evidence visible to arbiters and both dispute parties
- Maximum evidence size enforced (2048 bytes per hash)
- Validates evidence hash is not all zeros (prevents spam)
- Events emitted for evidence submission (DisputeEvidenceSubmitted)
- View function `get_dispute_evidence()` for retrieving stored evidence

## Technical Changes

### New Types (types.rs)
- `EscrowExtension`: Tracks escrow extension count, timestamps, and new expiry
- `DisputeEvidence`: Stores evidence hash, submitter, and timestamp

### New Error Codes (errors.rs)
- `MaxExtensionsReached` (323): Escrow exhausted maximum extensions
- `ExtensionExceedsMaxLifetime` (324): Extension would violate max lifetime
- `InvalidEvidenceHash` (325): Evidence hash is invalid (all zeros)
- `EvidenceSizeExceeded` (326): Evidence size exceeds maximum allowed

### New Storage Keys (storage.rs)
- `EscrowExtension(Bytes)`: Maps commitment to extension record
- `DisputeEvidence(Bytes, BytesN<32>)`: Maps (commitment, evidence_hash) to evidence record

### New Events (events.rs)
- `EscrowExtensionApplied`: Published when escrow expiry is extended
- `DisputeEvidenceSubmitted`: Published when evidence is submitted

### New Functions (escrow.rs)
- `extend_escrow_expiry()`: Extend escrow expiry with configurable limits
- `submit_dispute_evidence()`: Submit evidence hash for disputed escrow
- `get_dispute_evidence()`: Retrieve evidence record

### New Public Methods (lib.rs)
- `extend_escrow_expiry()`: Public contract method for TTL extension
- `submit_dispute_evidence()`: Public method for evidence submission
- `get_dispute_evidence()`: Public view method for evidence retrieval

### Updated Entry Points (pause_policy.rs)
- Added `ExtendEscrowExpiry` variant to `EntryPoint` enum
- Configured as emergency-safe operation (allowed during emergency mode)

## Backward Compatibility
- All changes are additive; no existing APIs modified
- Storage layout remains compatible through lazy migration
- Nonce v1 format still supported alongside v2
- Escrows without extensions work unchanged

## Storage Overhead
- Extension tracking: ~128 bytes per extended escrow
- Evidence storage: ~64 bytes per evidence submission (32-byte hash + address + timestamp)
- Both use TTL-based cleanup (6-month expiration)

Closes Pulsefy#112 Closes Pulsefy#113 Closes Pulsefy#114 Closes Pulsefy#115
…o-pay, and security center

**Pulsefy#100 - Crash Reporting & Analytics with Sentry Integration**
- Added CrashReportingService for recording crashes with breadcrumb tracking
- Implemented crash reporting consent screen (crash-reporting-consent.tsx)
- Added crash reports viewer and export functionality (crash-reports.tsx)
- Integrated breadcrumb recording for navigation and user actions
- Support for user context attachment and device information capture
- Crash report export via sharing interface

**Pulsefy#101 - App Update Prompt with Release Notes**
- Created AppUpdateService for version checking and update management
- Implemented in-app update prompt modal (app-update-prompt.tsx)
- Added support for force updates and optional update reminders
- Created update history screen to track version changes (update-history.tsx)
- Release notes display with version comparison
- "Remind Later" functionality for optional updates

**Pulsefy#102 - Scan-to-Pay with Camera & Confirmation**
- Enhanced scan-to-pay.tsx with comprehensive payment confirmation dialog
- Added detailed payment review screen before transaction signing
- Improved error handling for invalid QR codes with haptic feedback
- Modal-based confirmation flow showing recipient, amount, asset, memo, and privacy settings
- Transaction signing with user consent
- Breadcrumb integration for crash reporting

**Pulsefy#103 - Security Center with PIN Management & Biometrics**
- Enhanced security-center.tsx with multi-tab interface
- Overview tab: Security checklist and overall security score
- Sessions tab: Active device sessions with revoke capability
- History tab: Login history with success/failure status
- 2FA Setup tab: Step-by-step two-factor authentication guide
- Security Tips tab: Best practices for account security
- Session management with current device indicator
- Device location and last activity tracking
- Real-time security posture assessment

All features include:
- Comprehensive error handling
- Theme-aware UI components
- Haptic feedback for critical actions
- Breadcrumb tracking for analytics
- Secure storage of sensitive data

Closes Pulsefy#100 Pulsefy#101 Pulsefy#102 Pulsefy#103
…story, commitment hash migration, and privacy-aware escrow queries

This commit addresses issues Pulsefy#116, Pulsefy#117, Pulsefy#118, and Pulsefy#119 with the following changes:

## Pulsefy#117: Granular Pause Policy with Per-Feature Control
- Add PauseStatus type to query current pause state
- Implement get_pause_status() contract method for clients to check which operations are paused
- Pause reason codes already tracked per-feature via existing FeaturePauseReasons storage
- EntryPoint enum with pause_flag mapping enables per-feature granularity
- Global pause and per-feature pauses both queryable with reason codes

## Pulsefy#116: Fee Collector Rotation with History and Cooldown
- Add FeeCollectorRotationEntry type to track rotation audit trail
- Implement 24-hour rotation cooldown via FeeCollectorLastRotation timestamp
- Add rotation history storage (FeeCollectorRotationHistory) for queryable audit trail
- Update rotate_fee_collector() to enforce cooldown and log rotation entries
- Add get_fee_collector_rotation_history() contract method to query all rotations
- Rotation entries include: rotation_index, new_collector, previous_collector, rotated_at timestamp

## Pulsefy#118: Commitment Hash Migration for Legacy SHA256
- Document legacy SHA256 to KECCAK256 migration path in README
- verify_amount_commitment() already accepts both SHA256 and KECCAK256 for backward compat
- create_amount_commitment() defaults to KECCAK256 (more secure)
- Add deprecation timeline (v1.0 current, v2.0 Q2 2025 deprecated, v3.0 Q4 2025 removed)
- Update salt max length doc from 256 to 1024 bytes
- Legacy SHA256 commitments logged for audit trails

## Pulsefy#119: Escrow Status Query with Privacy-Aware Views
- get_escrow_details() already implements privacy-aware filtering
- Owner sees full details, arbiter sees full details
- Non-owner without privacy sees redacted view (amounts/owner/arbiter as None)
- Add PrivacyAccessAttemptEvent to log when privacy filtering occurs
- Event published on access to redacted escrows for security audits
- Privacy toggle enforcement at query time based on escrow owner's setting

Changes made:
- types.rs: Add PauseStatus and FeeCollectorRotationEntry types
- storage.rs: Add pause status getter, rotation history storage and getters, cooldown constant
- fee_router.rs: Update rotate_collector() with cooldown check and history tracking
- admin.rs: Update rotate_fee_collector() to handle Result from fee_router
- lib.rs: Add get_pause_status(), get_fee_collector_rotation_history() contract methods; enhance get_escrow_details() with event logging
- events.rs: Add PrivacyAccessAttemptEvent schema and publisher
- README.md: Document KECCAK256 default, legacy SHA256 acceptance, and deprecation timeline

Closes Pulsefy#116 Pulsefy#117 Pulsefy#118 Pulsefy#119
…yment checklist

This commit addresses four interconnected feature requests for contract
hardening, storage optimization, and production readiness.

## Task Pulsefy#105: Expand Fuzzing Coverage

Added comprehensive property-based fuzz tests using proptest to increase
edge-case coverage across critical escrow operations:

- Fuzz deposit_with_commitment: Tests commitment uniqueness and duplicate
  rejection. Verifies that off-chain commitment creation integrates correctly
  with on-chain validation.

- Fuzz partial_payment boundaries: Validates payment amount checks (exact
  remainder, overpayment rejection) across arbitrary remaining balances.
  Ensures the contract never accepts payments exceeding outstanding amounts.

- Fuzz dispute with multiple arbiters: Tests multi-sig voting mechanics to
  ensure arbiters can vote independently and funds remain locked until
  threshold is reached.

- Fuzz cleanup_escrow after finalize: Validates that terminal state escrows
  (Spent/Refunded) can be cleaned up and non-terminal states correctly reject
  cleanup attempts.

- Fuzz extend_escrow_ttl timing: Ensures TTL extensions don't corrupt escrow
  state, don't trigger spurious expirations, and cumulative extensions work
  reliably.

Coverage increase: ~25 new proptest blocks covering edge cases identified
in security review and operational testing.

## Task Pulsefy#106: Implement Escrow Cleanup Job for Expired Entries

Enhanced storage cleanup mechanism to support batch operations and document
gas costs:

- Improved cleanup_escrow: Expanded documentation with detailed gas cost
  estimates (1,000-2,000 stroops per operation). Clarified storage deposit
  refund mechanics and added proper status-based error handling.

- Added batch cleanup (cleanup_escrow_batch): New function accepts Vec of
  commitments and cleanly removes all terminal escrows, returning count of
  successfully cleaned entries. Skips non-terminal escrows gracefully.

- Added contract endpoint cleanup_escrow_batch: Public contract method that
  invokes batch cleanup with authorization and pause policy checks.

- Added EscrowCleaned event: New event emitted on cleanup with commitment
  and terminal status, enabling off-chain tracking of storage reclamation.
  Integrated into event schema and EVENT_SCHEMAS registry.

Storage reclamation workflow:
1. Escrow reaches terminal state (Spent/Refunded)
2. Anyone can call cleanup_escrow or cleanup_escrow_batch
3. Storage entry removed (Soroban ledger auto-refunds deposit)
4. EscrowCleaned event emitted for indexer tracking

## Task Pulsefy#107: Add Multi-sig Arbitration with Configurable Threshold

Verified existing multi-sig implementation is complete and functional:
- vote_for_dispute: Arbiters vote independently, once per dispute
- resolve_dispute_multi_sig: Resolves when threshold reached via majority
- Arbiters field in EscrowEntry for M-of-N setup
- arbiter_threshold field tracks required votes
- Proper nonce replay protection and auth checks

No changes required; implementation already exceeds requirements.

## Task Pulsefy#104: Implement Mainnet Deployment Checklist and Audit Gates

Created comprehensive MAINNET_DEPLOYMENT_CHECKLIST.md covering:

- Pre-audit phase: Code review, testing, security review, documentation
  completeness checklist with specific thresholds (85% coverage, ≤1,500
  stroops per deposit, etc.)

- Audit phase: Audit coordination, execution tracking, and audit report
  template with standardized finding severity levels, remediation tracking,
  and sign-off sections.

- Post-audit remediation: Issue tracking workflow, regression testing
  requirements, and sign-off gates before mainnet deployment.

- WASM hash pinning: Deterministic build process, hash computation,
  verification on-chain, and secure storage of expected hashes.

- Contract ID registration: Derivation process, configuration management,
  multisig authorization, and verification procedures.

- Rollback plan: Preconditions, rollback criteria (functional failures,
  performance degradation, security incidents), execution steps,
  communication templates, and post-incident review process.

- Deployment day checklist: Pre-deployment verification, execution steps,
  post-deployment monitoring, and first-week smoke tests.

- Cross-references to related security and architecture documentation.

---

Fixes: Closes Pulsefy#105 Closes Pulsefy#106 Closes Pulsefy#107 Closes Pulsefy#104
Add native iOS and Android home-screen widgets, harden QR payment scanning, and add focused scanner coverage. Make contacts durable and device-local with Stellar address validation and offline CRUD. Complete receipt sharing with valid transaction links and explorer navigation.
Add visible export format controls, configurable webhook test events, live analytics updates over SSE, and shared keyboard navigation for modal dialogs.
fix(mobile): complete security and runtime flows
…tifications-and-ux

feat: add transaction filters haptics deep links and push registration
…rovements

feat(mobile): improve onboarding and transaction UX
…vements

feat: improve dashboard UX and accessibility
…updates

feat(mobile): expand core app experiences
…mobile-payment-tools

feat(mobile): add payment utility features
…eployment

feat(contract): Add fuzzing, batch cleanup, and mainnet deployment
…nce-evidence

feat(contract): Implement stealth address privacy v2, escrow TTL exte…
…ct/cargo-deps-5a15a87651

build(deps): bump soroban-sdk from 23.4.1 to 27.0.5 in /app/contract in the cargo-deps group
…-deps-0fb7b3b6f1

build(deps): bump the npm-deps group with 92 updates
…ements-120-123

feat(contract): Implement emergency mode, metadata endpoints, memo su…
…t breaker, strict OpenAPI spec

- Pulsefy#7: normalize error responses to a canonical envelope with stable traceId
- Pulsefy#9: replace @nestjs/throttler global guard with a Redis sliding-window
  rate limiter (in-memory graceful fallback, X-RateLimit-* + Retry-After)
- Pulsefy#10: add Horizon circuit breaker with Redis-cached degradation and metrics
- Pulsefy#13: enable tryItOut, add POST /docs/json spec export and CI divergence gate

Closes Pulsefy#7, Pulsefy#9, Pulsefy#10, Pulsefy#13
…analytics stale fallback

- webhooks: exponential retry 1m/5m/15m/1h/6h, DLQ endpoint, X-QuickEx-Delivery-ID dedup & 202 ack, delivery metrics (Pulsefy#17)
- health: composite readiness checks with 5s cache and Sentry alerting (Pulsefy#19)
- rate limits: env-driven per-profile config via RateLimitConfigService (Pulsefy#12)
- analytics: stale-report fallback cache + X-Cache-Status header (Pulsefy#16)
- add resilient RedisService (graceful fallback when REDIS_URL unset)
Viky207 and others added 29 commits August 27, 2026 19:11
…security-session-network

feat(mobile): improve security and wallet sessions
…kflows-sync

feat: connect real workflow data and sync
…hook-retry-dlq-health

feat(backend): webhook retry/DLQ, composite health, env rate limits, analytics stale fallback
Cache expensive compose/simulate responses using SHA-256 request ETags.
Return 304 on If-None-Match, support 5m/1m TTLs, bypass when X-API-Key is
present, and track cache hit ratio via etag_cache_total metrics.
Run the expiry sweep every 5 minutes and add the paymentlinks.expired.count
metric. The job remains idempotent and continues emitting payment.link.expired
events. Update existing unit and integration tests for the new MetricsService
dependency.
Pulsefy#97 - feat(mobile): add related transactions list to transaction detail
- Import findRelatedTransactions from cache service
- Add RelatedTransactions sub-component with navigation to detail
- Add findRelatedTransactions to services/cache.ts (searches by
  source/destination address across all cached accounts)

Pulsefy#64 - feat(frontend): implement payment history filtering and search
- Extend ActivityFilterState with dateFrom/dateTo, amountMin/amountMax,
  memo field filter
- Add URL query param serialisation (filtersToParams/paramsToFilters)
- Add saved filter presets via localStorage (savePreset/deletePreset)
- Add CSV export (downloadCsv) and print-to-PDF (printToPdf) helpers
- New PaymentHistoryFilters component with full UI for all criteria
- Dashboard updated to use PaymentHistoryFilters component

Pulsefy#63 - feat(frontend): add named OG image routes with edge cache
- /api/og/payment-link → dynamic OG image for payment links
- /api/og/profile      → dynamic OG image for user profiles
- Both routes set Cache-Control: public, max-age=3600, s-maxage=3600
- Main /api/og route also updated with cache headers
- Redirect to default image when required params are missing

Pulsefy#62 - feat(frontend+backend): implement team management with real backend
- NestJS TeamsModule: TeamsService (CRUD, roles, invite links,
  ownership transfer), TeamsController (REST endpoints), DTOs
- Roles: owner > admin > member > viewer
- POST /teams, GET /teams/:id, POST /teams/:id/members
- POST /teams/:id/invite-link (7-day expiry token)
- POST /teams/:id/transfer-ownership (owner only)
- Supabase migration: teams, team_members, team_invites tables
- Frontend teams page updated to use real backend API
…saction detail (Pulsefy#62 Pulsefy#63 Pulsefy#64 Pulsefy#97)

- feat(backend): Add teams module with full CRUD, roles (owner/admin/member/viewer),
  invite links with 7-day expiry, member list with joined/last-active dates,
  ownership transfer restricted to owner, and Supabase migration

- feat(frontend): Replace mocked team page with real backend integration —
  create team, invite members, role assignment, remove members, generate
  invite links with expiry display, and owner-only delete/transfer guards

- feat(frontend): Add /api/og/payment-link and /api/og/profile edge routes
  with 1h Cache-Control (s-maxage=3600) and fallback to default OG image;
  update base /api/og route to set the same cache header

- feat(frontend): Add /history payment history page with date/asset/status/
  amount filters, tx-hash/memo/address search, CSV/PDF export, saved filter
  presets persisted to localStorage, URL query params reflecting all filters,
  and empty state with actionable suggestions

- feat(mobile): Enhance transaction detail — add RelatedTransactions section
  (counterparty-matched from cache), fee breakdown section, and expose
  getCachedTransactions helper in cache service
…y#28)

- Add UsernameRankingService that loads weights from feature flag
  'username.ranking_weights' (metadata: similarity, transactionVolume,
  lastActiveAt, isFeatured); weights are normalised to sum to 1 before
  scoring and cached in memory with a 60-second TTL
- Register default ranking-weights flag in DEFAULT_FLAGS with sensible
  defaults (isFeatured=2 gives featured profiles a strong boost)
- Wire UsernameRankingService into UsernamesService.searchDiscovery,
  replacing the fixed similarity-only sort
- Add PATCH /admin/feature-flags/username.ranking_weights endpoint with
  full Swagger documentation including the ranking formula
- Add unit tests covering getWeights (caching, fallback, invalid values)
  and rank (similarity, recency, volume, featured, edge-cases)
Pulsefy#27)

- Set tracesSampleRate to 0.1 (10%) in instrument.ts; rate is overridable
  via SENTRY_TRACES_SAMPLE_RATE env var
- Release tag now sourced from SENTRY_RELEASE env var (fallback to
  quickex-backend@0.1.0 for local dev)
- Add SentryTracingService with dedicated span-wrapper helpers for:
    traceCompose, traceSimulate, traceSubmit  (transaction paths)
    traceHorizon, traceSoroban               (external calls)
    traceCache                               (cache layer)
- Wire SentryTracingService into TransactionsController so compose,
  build, simulate and submit endpoints create named Sentry spans
- Expand PII scrubbing in beforeSend/beforeBreadcrumb to replace Stellar
  public keys (G[A-Z2-7]{55}) in request data, extras and message strings
- Export SentryTracingService and SpanOp from sentry/index.ts
- Add unit tests for SentryTracingService (all ops, error propagation)
…ulsefy#26)

- Resolve actor in PATCH /admin/feature-flags/:key using priority:
    1. req.apiKey.id (authenticated API key, prefixed 'apiKey:<id>')
    2. X-Admin-Actor header (trusted internal tooling)
    3. ForbiddenException — anonymous changes are blocked
- Record a FlagAuditEntry in audit log metadata with shape:
    { flagKey, previousValue, newValue, actor, ip, userAgent }
- Remove duplicate internal audit log call from FeatureFlagsService
  so each change produces exactly one enriched audit entry
- Add FlagAuditEntry interface to audit.model.ts
- Annotate GET /admin/audit with Swagger docs describing the
  flagAuditEntry metadata field format
- Add unit tests: actor from apiKey.id, X-Admin-Actor fallback,
  anonymous blocked, whitespace-only header blocked, audit shape
…ulsefy#24)

- Create StellarExceptionMapper (common/stellar-errors/) with:
    ConnectionError (network/fetch errors)   → 502 BAD_GATEWAY
    NotFoundError (404 / account not found)  → 404 NOT_FOUND
    RateLimitError (429 / rate limit msg)    → 429 TOO_MANY_REQUESTS + Retry-After
    ContractError  (HostError / simulation)  → 400 BAD_REQUEST with code & details
    Timeout        (ETIMEDOUT / timed out)   → 504 GATEWAY_TIMEOUT
    Unmapped                                 → 500 (no stack trace exposed)
- Every mapped exception embeds a traceId in the response body
- throwMappedStellarException() factory converts to NestJS HttpException
  sub-classes (NotFoundException, TooManyRequestsException, etc.)
- Wire mapper into HorizonService.handleHorizonError() replacing the
  hand-rolled status switch
- Wire mapper into SorobanRpcService.getAccount/simulateTransaction/
  getNetworkPassphrase so Soroban errors are also stably mapped
- Add 30+ unit tests covering all status codes, traceId embedding,
  Retry-After extraction, HostError detail parsing, and edge cases
feat: implement team management, OG images, payment history, and tran…
…ception-mapper

feat(backend): map Stellar SDK exceptions to stable HTTP error codes …
…r-attribution

feat(backend): implement feature flag audit with actor attribution (Pulsefy#26)
…formance-monitoring

feat(backend): add Sentry performance monitoring for transaction path…
…earch-ranking

feat(backend): implement configurable username search ranking (Pulsefy#28)
…-benchmarks

feat(contract): add multisig roles and governance benchmarks
…k-expiration-job

feat(backend): Add scheduled payment link expiration job
…caching-compose-simulate

feat(backend): Add ETag-based caching for compose/simulate responses
…-envelope-swagger-validation

feat: error envelope, Redis sliding-window rate limit, Horizon circuit breaker, strict OpenAPI spec
…gGuard

The IndexerLagService had no unit tests despite being a critical component
that monitors Horizon ledger lag and gates risky operations. Add comprehensive
coverage for:

- IndexerLagService: getStatus(), isBlocked(), pollHorizon(), metric
  reporting, and edge cases (null ledgers, Horizon errors, DB errors,
  guard disabled/overridden states)
- IndexerLagGuard: canActivate() paths for no-decorator, not-blocked,
  and blocked scenarios, including audit logging and metrics side-effects

Closes Pulsefy#42
Closes Pulsefy#43
Closes Pulsefy#44
Closes Pulsefy#45
@Cedarich

Copy link
Copy Markdown
Contributor

Kindly fix conflict

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.