Skip to content

feat: maskWebhookUrl helper, webhook payload builder, structured logs, and wallet holdings endpoint#453

Open
chinelo002 wants to merge 4 commits into
accesslayerorg:mainfrom
chinelo002:feat/webhook-helpers-holdings-test
Open

feat: maskWebhookUrl helper, webhook payload builder, structured logs, and wallet holdings endpoint#453
chinelo002 wants to merge 4 commits into
accesslayerorg:mainfrom
chinelo002:feat/webhook-helpers-holdings-test

Conversation

@chinelo002

@chinelo002 chinelo002 commented Jun 25, 2026

Copy link
Copy Markdown

Summary

This PR adds four features: a URL masking utility for webhook callback URLs, a buildWebhookPayload helper for serialising trade events, structured info logs on webhook registration/deletion, and a new GET /wallets/:address/holdings endpoint with an integration test for the empty-wallet case.

closes #442
closes #444
closes #449
closes #450

Changes

  • Add helper for masking webhook callback URLs in logs and error responses #444 — maskWebhookUrl helper: Added src/utils/webhook-mask.utils.ts with maskWebhookUrl(url): string — returns scheme://host only using new URL(url).origin, stripping path, query string, and fragment. Returns '[invalid url]' on parse failure. 7 unit tests cover: query string stripped, path stripped, no-path URL, invalid input, empty string, non-standard port preserved, fragment stripped.

  • Add helper for building the trade webhook POST payload from an indexed trade event #450 — buildWebhookPayload helper: Added src/modules/webhooks/webhook-payload.utils.ts with buildWebhookPayload(TradeEvent): WebhookEventPayload that maps camelCase event fields to the snake_case payload contract. Updated webhook.service.ts to replace the inline payload object literal in dispatchWebhookEvent with this helper. 3 unit tests confirm buy/sell event mapping and exact output key set.

  • Add structured log for creator trade webhook registration with creator ID and event types #449 — Structured webhook registration/deletion logs: Edited webhook.service.ts to emit logger.info({ creator_id, webhook_id, event_types, registered_at }, 'Webhook registered') after a successful createWebhook and logger.info({ creator_id, webhook_id, deleted_at }, 'Webhook deleted') after deleteWebhook. The callback URL does not appear in any log line.

  • Add integration test for wallet holdings endpoint returning empty array for wallet with no keys #442 — Wallet holdings endpoint + empty-wallet integration test: Added wallet-holdings.service.ts (calls fetchOwnership and maps to HoldingItem[]), wallet-holdings.controllers.ts (validates address, calls service, returns 200), and registered GET /:address/holdings in wallets.routes.ts. Integration test (wallet-holdings.integration.test.ts) covers: valid address with no holdings → 200 + holdings: [] + total_portfolio_value: '0'; valid address with holdings → 200 + populated data; malformed address → 400 + VALIDATION_ERROR; service error forwarded to next().

Test plan

  • pnpm test or jest for all new test files.
  • All unit tests added alongside each utility.
  • Integration tests mock the service layer (no database required).

@drips-wave

drips-wave Bot commented Jun 25, 2026

Copy link
Copy Markdown

@chinelo002 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@chinelo002 chinelo002 force-pushed the feat/webhook-helpers-holdings-test branch 4 times, most recently from 858c32c to cad9fb3 Compare June 27, 2026 14:43
chinelo002 and others added 4 commits June 28, 2026 09:18
…URLs (accesslayerorg#444)

Returns scheme://host only; removes path, query string, and fragment.
Returns '[invalid url]' on parse failure.

Co-Authored-By: Claude <noreply@anthropic.com>
…ation/deletion logs (accesslayerorg#449 accesslayerorg#450)

- buildWebhookPayload(TradeEvent) centralises the TradeEvent→WebhookEventPayload
  mapping; used in dispatchWebhookEvent to replace the inline object literal
- logger.info emitted on successful webhook creation and deletion with
  creator_id, webhook_id, event_types/deleted_at; callback URL is never logged

Co-Authored-By: Claude <noreply@anthropic.com>
…wallet integration test (accesslayerorg#442)

Add wallet-holdings.service.ts, wallet-holdings.controllers.ts, and register
GET /:address/holdings in wallets.routes.ts. Integration test covers empty
wallet returning 200+[] and malformed address returning 400.

Co-Authored-By: Claude <noreply@anthropic.com>
Add masked callback URL to warn and error log fields so delivery failures
include the endpoint origin without leaking tokens embedded in paths or
query strings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@chinelo002 chinelo002 force-pushed the feat/webhook-helpers-holdings-test branch from cad9fb3 to 0f9f287 Compare June 28, 2026 08:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment