@v3finance/monitoring-sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/CHANGELOG.md +21 -11
  2. package/README.md +223 -148
  3. package/dist/cjs/client.d.ts +23 -42
  4. package/dist/cjs/client.d.ts.map +1 -1
  5. package/dist/cjs/client.js +44 -53
  6. package/dist/cjs/client.js.map +1 -1
  7. package/dist/cjs/core/errors.d.ts +18 -18
  8. package/dist/cjs/core/errors.d.ts.map +1 -1
  9. package/dist/cjs/core/errors.js +17 -17
  10. package/dist/cjs/core/errors.js.map +1 -1
  11. package/dist/cjs/core/http.d.ts +22 -26
  12. package/dist/cjs/core/http.d.ts.map +1 -1
  13. package/dist/cjs/core/http.js +28 -36
  14. package/dist/cjs/core/http.js.map +1 -1
  15. package/dist/cjs/core/pagination.d.ts +6 -7
  16. package/dist/cjs/core/pagination.d.ts.map +1 -1
  17. package/dist/cjs/core/pagination.js +1 -1
  18. package/dist/cjs/core/pagination.js.map +1 -1
  19. package/dist/cjs/core/scope.d.ts +8 -0
  20. package/dist/cjs/core/scope.d.ts.map +1 -0
  21. package/dist/cjs/core/scope.js +3 -0
  22. package/dist/cjs/core/scope.js.map +1 -0
  23. package/dist/cjs/generated/types.d.ts +129 -117
  24. package/dist/cjs/generated/types.d.ts.map +1 -1
  25. package/dist/cjs/generated/types.js +1 -1
  26. package/dist/cjs/generated/types.js.map +1 -1
  27. package/dist/cjs/index.d.ts +6 -6
  28. package/dist/cjs/index.d.ts.map +1 -1
  29. package/dist/cjs/index.js +13 -16
  30. package/dist/cjs/index.js.map +1 -1
  31. package/dist/cjs/resources/account.d.ts +12 -51
  32. package/dist/cjs/resources/account.d.ts.map +1 -1
  33. package/dist/cjs/resources/account.js +17 -61
  34. package/dist/cjs/resources/account.js.map +1 -1
  35. package/dist/cjs/resources/addresses.d.ts +49 -65
  36. package/dist/cjs/resources/addresses.d.ts.map +1 -1
  37. package/dist/cjs/resources/addresses.js +60 -69
  38. package/dist/cjs/resources/addresses.js.map +1 -1
  39. package/dist/cjs/resources/catalog.d.ts +17 -10
  40. package/dist/cjs/resources/catalog.d.ts.map +1 -1
  41. package/dist/cjs/resources/catalog.js +23 -17
  42. package/dist/cjs/resources/catalog.js.map +1 -1
  43. package/dist/cjs/resources/deliveries.d.ts +34 -23
  44. package/dist/cjs/resources/deliveries.d.ts.map +1 -1
  45. package/dist/cjs/resources/deliveries.js +27 -17
  46. package/dist/cjs/resources/deliveries.js.map +1 -1
  47. package/dist/cjs/resources/transactions.d.ts +14 -14
  48. package/dist/cjs/resources/transactions.d.ts.map +1 -1
  49. package/dist/cjs/resources/transactions.js +15 -16
  50. package/dist/cjs/resources/transactions.js.map +1 -1
  51. package/dist/cjs/resources/webhooks.d.ts +22 -0
  52. package/dist/cjs/resources/webhooks.d.ts.map +1 -0
  53. package/dist/cjs/resources/webhooks.js +35 -0
  54. package/dist/cjs/resources/webhooks.js.map +1 -0
  55. package/dist/cjs/units.d.ts +11 -11
  56. package/dist/cjs/units.js +14 -14
  57. package/dist/cjs/units.js.map +1 -1
  58. package/dist/cjs/version.d.ts +3 -3
  59. package/dist/cjs/version.d.ts.map +1 -1
  60. package/dist/cjs/version.js +3 -3
  61. package/dist/cjs/version.js.map +1 -1
  62. package/dist/cjs/webhooks.d.ts +33 -28
  63. package/dist/cjs/webhooks.d.ts.map +1 -1
  64. package/dist/cjs/webhooks.js +33 -28
  65. package/dist/cjs/webhooks.js.map +1 -1
  66. package/dist/esm/client.d.ts +23 -42
  67. package/dist/esm/client.d.ts.map +1 -1
  68. package/dist/esm/client.js +46 -55
  69. package/dist/esm/client.js.map +1 -1
  70. package/dist/esm/core/errors.d.ts +18 -18
  71. package/dist/esm/core/errors.d.ts.map +1 -1
  72. package/dist/esm/core/errors.js +17 -17
  73. package/dist/esm/core/errors.js.map +1 -1
  74. package/dist/esm/core/http.d.ts +22 -26
  75. package/dist/esm/core/http.d.ts.map +1 -1
  76. package/dist/esm/core/http.js +28 -36
  77. package/dist/esm/core/http.js.map +1 -1
  78. package/dist/esm/core/pagination.d.ts +6 -7
  79. package/dist/esm/core/pagination.d.ts.map +1 -1
  80. package/dist/esm/core/pagination.js +1 -1
  81. package/dist/esm/core/pagination.js.map +1 -1
  82. package/dist/esm/core/scope.d.ts +8 -0
  83. package/dist/esm/core/scope.d.ts.map +1 -0
  84. package/dist/esm/core/scope.js +2 -0
  85. package/dist/esm/core/scope.js.map +1 -0
  86. package/dist/esm/generated/types.d.ts +129 -117
  87. package/dist/esm/generated/types.d.ts.map +1 -1
  88. package/dist/esm/generated/types.js +1 -1
  89. package/dist/esm/generated/types.js.map +1 -1
  90. package/dist/esm/index.d.ts +6 -6
  91. package/dist/esm/index.d.ts.map +1 -1
  92. package/dist/esm/index.js +6 -6
  93. package/dist/esm/index.js.map +1 -1
  94. package/dist/esm/resources/account.d.ts +12 -51
  95. package/dist/esm/resources/account.d.ts.map +1 -1
  96. package/dist/esm/resources/account.js +15 -57
  97. package/dist/esm/resources/account.js.map +1 -1
  98. package/dist/esm/resources/addresses.d.ts +49 -65
  99. package/dist/esm/resources/addresses.d.ts.map +1 -1
  100. package/dist/esm/resources/addresses.js +60 -69
  101. package/dist/esm/resources/addresses.js.map +1 -1
  102. package/dist/esm/resources/catalog.d.ts +17 -10
  103. package/dist/esm/resources/catalog.d.ts.map +1 -1
  104. package/dist/esm/resources/catalog.js +23 -17
  105. package/dist/esm/resources/catalog.js.map +1 -1
  106. package/dist/esm/resources/deliveries.d.ts +34 -23
  107. package/dist/esm/resources/deliveries.d.ts.map +1 -1
  108. package/dist/esm/resources/deliveries.js +27 -17
  109. package/dist/esm/resources/deliveries.js.map +1 -1
  110. package/dist/esm/resources/transactions.d.ts +14 -14
  111. package/dist/esm/resources/transactions.d.ts.map +1 -1
  112. package/dist/esm/resources/transactions.js +15 -16
  113. package/dist/esm/resources/transactions.js.map +1 -1
  114. package/dist/esm/resources/webhooks.d.ts +22 -0
  115. package/dist/esm/resources/webhooks.d.ts.map +1 -0
  116. package/dist/esm/resources/webhooks.js +31 -0
  117. package/dist/esm/resources/webhooks.js.map +1 -0
  118. package/dist/esm/units.d.ts +11 -11
  119. package/dist/esm/units.js +14 -14
  120. package/dist/esm/units.js.map +1 -1
  121. package/dist/esm/version.d.ts +3 -3
  122. package/dist/esm/version.d.ts.map +1 -1
  123. package/dist/esm/version.js +3 -3
  124. package/dist/esm/version.js.map +1 -1
  125. package/dist/esm/webhooks.d.ts +33 -28
  126. package/dist/esm/webhooks.d.ts.map +1 -1
  127. package/dist/esm/webhooks.js +33 -28
  128. package/dist/esm/webhooks.js.map +1 -1
  129. package/package.json +8 -5
  130. package/src/client.ts +50 -61
  131. package/src/core/errors.ts +18 -18
  132. package/src/core/http.ts +45 -55
  133. package/src/core/pagination.ts +7 -8
  134. package/src/core/scope.ts +8 -0
  135. package/src/generated/types.ts +139 -125
  136. package/src/index.ts +7 -24
  137. package/src/resources/account.ts +18 -72
  138. package/src/resources/addresses.ts +84 -109
  139. package/src/resources/catalog.ts +28 -19
  140. package/src/resources/deliveries.ts +43 -30
  141. package/src/resources/transactions.ts +18 -17
  142. package/src/resources/webhooks.ts +36 -0
  143. package/src/units.ts +14 -14
  144. package/src/version.ts +3 -3
  145. package/src/webhooks.ts +37 -32
  146. package/dist/cjs/resources/clients.d.ts +0 -84
  147. package/dist/cjs/resources/clients.d.ts.map +0 -1
  148. package/dist/cjs/resources/clients.js +0 -102
  149. package/dist/cjs/resources/clients.js.map +0 -1
  150. package/dist/esm/resources/clients.d.ts +0 -84
  151. package/dist/esm/resources/clients.d.ts.map +0 -1
  152. package/dist/esm/resources/clients.js +0 -97
  153. package/dist/esm/resources/clients.js.map +0 -1
  154. package/src/resources/clients.ts +0 -135
package/CHANGELOG.md CHANGED
@@ -1,16 +1,26 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to this package. The format follows [Keep a Changelog](https://keepachangelog.com), versions —
4
- [SemVer](https://semver.org).
3
+ All notable changes to this package are documented in this file. The format is based on
4
+ [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org).
5
5
 
6
- ## 0.1.0 — 2026-10-28
6
+ ## 0.2.0 — 2026-10-28
7
+
8
+ ### Breaking changes
9
+
10
+ - `MonitoringClient` authenticates with an API key only. Your client ID is resolved from the key, so methods no
11
+ longer take it as a parameter.
12
+ - Removed account management APIs: `MonitoringClient.signIn`, `auth`, `account.keys` and `clients`.
13
+ - `clients.sendTestWebhook()` is now `webhooks.sendTest()`.
14
+ - `AddressDefaults` is renamed to `SubscriptionDefaults`, and `AddressSubscriptionUpdate` to `AddressUpdate`.
15
+
16
+ ### Added
7
17
 
8
- First release.
18
+ - `account.get()` and `account.id()`.
19
+
20
+ ### Changed
21
+
22
+ - Documentation and type descriptions are now in English.
23
+
24
+ ## 0.1.0 — 2026-10-28
9
25
 
10
- - `MonitoringClient`: account and personal keys, sign-in, networks and assets, your client (webhook URL, signing
11
- secret, client keys, members, test webhook), addresses and subscriptions with automatic batching, webhook history,
12
- transaction lookup with confirmations and finality.
13
- - Webhooks: `parseWebhook`, `verifyWebhookSignature`, `signWebhookBody`, `isTestWebhook`, `webhookIdempotencyKey`.
14
- - Amounts: `formatUnits`, `parseUnits`.
15
- - Timeouts, cancellation, retries on 429 and 503, typed errors with per-item details.
16
- - Types generated from the OpenAPI spec of the API.
26
+ - Initial release.
package/README.md CHANGED
@@ -1,145 +1,249 @@
1
- # @v3finance/monitoring-sdk
2
-
3
- Official TypeScript SDK for the [V3 Finance address monitoring API](https://monitoring.v3.finance/docs):
4
- watch addresses on TRON and EVM networks and receive a signed webhook for every incoming and outgoing transfer.
5
-
6
- - **Typed end to end** — request and response types are generated from the API's OpenAPI spec, with docs on hover.
7
- - **Webhooks** — signature verification and typed parsing with no network calls, using Web Crypto.
8
- - **Built for production** — timeouts, cancellation, retries on rate limits, typed errors with per-item details,
9
- automatic batching of large address lists, async iteration over pages.
10
- - **Zero runtime dependencies** — Node.js 20+, Bun, Deno, Cloudflare Workers; ESM and CommonJS.
11
-
12
- [Русская версия ниже](#по-русски).
13
-
14
- ## Install
1
+ # V3 Finance Monitoring SDK
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@v3finance/monitoring-sdk.svg)](https://www.npmjs.com/package/@v3finance/monitoring-sdk)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@v3finance/monitoring-sdk.svg)](https://www.npmjs.com/package/@v3finance/monitoring-sdk)
5
+ [![types](https://img.shields.io/npm/types/@v3finance/monitoring-sdk.svg)](https://www.npmjs.com/package/@v3finance/monitoring-sdk)
6
+ [![license](https://img.shields.io/npm/l/@v3finance/monitoring-sdk.svg)](./LICENSE)
7
+
8
+ The official TypeScript SDK for the [V3 Finance Monitoring API](https://monitoring.v3.finance/docs).
9
+ Monitor addresses on TRON and EVM networks and receive a signed webhook for every incoming and outgoing transfer.
10
+
11
+ - **Address monitoring** with per-address subscriptions: choose the assets and the direction you are notified about.
12
+ - **Webhooks** with signature verification and fully typed payloads.
13
+ - **Transaction lookup** with confirmations and finality, for any transaction on a supported network.
14
+ - **Delivery history** of every webhook sent to you.
15
+ - **Production-ready**: automatic retries, timeouts, cancellation, pagination and batching.
16
+ - **Fully typed**, zero dependencies, ESM and CommonJS. Runs on Node.js, Bun, Deno and Cloudflare Workers.
17
+
18
+ ## Contents
19
+
20
+ - [Installation](#installation)
21
+ - [Quick start](#quick-start)
22
+ - [Configuration](#configuration)
23
+ - [Addresses](#addresses)
24
+ - [Receiving webhooks](#receiving-webhooks)
25
+ - [Transactions and finality](#transactions-and-finality)
26
+ - [Delivery history](#delivery-history)
27
+ - [Networks and assets](#networks-and-assets)
28
+ - [Amounts](#amounts)
29
+ - [Error handling](#error-handling)
30
+ - [Retries, timeouts and cancellation](#retries-timeouts-and-cancellation)
31
+ - [TypeScript](#typescript)
32
+ - [Requirements](#requirements)
33
+ - [Security](#security)
34
+ - [Versioning](#versioning)
35
+ - [Support](#support)
36
+
37
+ ## Installation
15
38
 
16
39
  ```bash
17
40
  npm install @v3finance/monitoring-sdk
18
41
  ```
19
42
 
20
- Server-side only: an API key in a browser is visible to anyone.
43
+ ```bash
44
+ pnpm add @v3finance/monitoring-sdk
45
+ yarn add @v3finance/monitoring-sdk
46
+ bun add @v3finance/monitoring-sdk
47
+ ```
21
48
 
22
49
  ## Quick start
23
50
 
24
51
  ```ts
25
52
  import { MonitoringClient } from '@v3finance/monitoring-sdk'
26
53
 
27
- const monitoring = new MonitoringClient({ apiKey: process.env.MONITORING_API_KEY })
54
+ const monitoring = new MonitoringClient({ apiKey: process.env.MONITORING_API_KEY! })
55
+
56
+ // Notify about incoming USDT on a deposit address
57
+ await monitoring.addresses.add(
58
+ [{ network: 'tron', address: 'TA8HgQbFjuMLWCaJeGyfrv8FErWSHz82vr', label: 'user-42' }],
59
+ { assets: ['USDT'], direction: 'in' },
60
+ )
61
+ ```
62
+
63
+ Every transfer on the address now triggers a signed webhook to your endpoint — see
64
+ [Receiving webhooks](#receiving-webhooks).
28
65
 
29
- // your client id: for a client key it is in the key's identity
30
- const { actor } = await monitoring.account.me()
31
- const clientId = actor.clientId!
66
+ ## Configuration
32
67
 
33
- // deposit addresses: incoming USDT only
34
- await monitoring.addresses.add(clientId, [{ network: 'tron', address: 'TA8HgQbFjuMLWCaJeGyfrv8FErWSHz82vr', label: 'user-42' }], {
35
- assets: ['USDT'],
36
- direction: 'in',
68
+ ```ts
69
+ const monitoring = new MonitoringClient({
70
+ apiKey: process.env.MONITORING_API_KEY!,
71
+ timeoutMs: 10_000,
72
+ maxRetries: 3,
37
73
  })
38
74
  ```
39
75
 
40
- ## Authentication
76
+ | Option | Type | Default | Description |
77
+ |---|---|---|---|
78
+ | `apiKey` | `string` | — | Your API key. **Required.** |
79
+ | `clientId` | `string` | resolved from the API key | Your client ID. |
80
+ | `baseUrl` | `string` | `https://monitoring.v3.finance` | API base URL. |
81
+ | `timeoutMs` | `number` | `30000` | Request timeout in milliseconds. |
82
+ | `maxRetries` | `number` | `2` | Retries for rate limits and transient errors. |
83
+ | `fetch` | `typeof fetch` | global `fetch` | Custom `fetch` implementation. |
84
+ | `headers` | `Record<string, string>` | — | Additional headers sent with every request. |
85
+
86
+ ## Addresses
41
87
 
42
- | Credential | How to get it | What it can do |
43
- |---|---|---|
44
- | Client key `ce_…` | panel → client → API keys, or `clients.keys.create()` | addresses, history and transactions of that client |
45
- | Personal key `ce_user_…` | panel → Account, or `account.keys.create()` after signing in | everything you can do in the panel, with your role |
46
- | Session | `MonitoringClient.signIn({ email, password })` | same as a personal key |
88
+ An address is monitored on a single network; to watch an EVM address on several networks, add it once per network.
89
+ Each address has a **subscription** — which assets (`assets`) and which direction (`direction`: `in`, `out` or
90
+ `both`) you are notified about. By default it covers all assets of the network in both directions.
47
91
 
48
92
  ```ts
49
- const monitoring = new MonitoringClient({ apiKey: 'ce_…' })
50
- const { client } = await MonitoringClient.signIn({ email, password })
93
+ // Add — lists larger than 1,000 addresses are sent in batches automatically
94
+ await monitoring.addresses.add(
95
+ [
96
+ { network: 'tron', address: 'TA8HgQbFjuMLWCaJeGyfrv8FErWSHz82vr', label: 'user-42' },
97
+ { network: 'ethereum', address: '0x533bcdd534fc3f9651471d7b4469a0d01ca45a2a', assets: ['USDT', 'USDC'] },
98
+ ],
99
+ { direction: 'in' },
100
+ )
101
+
102
+ // Change the subscription
103
+ await monitoring.addresses.update([{ network: 'tron', address: 'TA8HgQbFjuMLWCaJeGyfrv8FErWSHz82vr' }], { direction: 'both' })
104
+
105
+ // Iterate over all monitored addresses
106
+ for await (const address of monitoring.addresses.iterate({ network: 'tron' })) {
107
+ console.log(address.address, address.assets ?? 'all assets', address.direction)
108
+ }
109
+
110
+ // Stop monitoring
111
+ await monitoring.addresses.remove([{ network: 'tron', address: 'TA8HgQbFjuMLWCaJeGyfrv8FErWSHz82vr' }])
51
112
  ```
52
113
 
114
+ Requests are validated as a whole: if any address is invalid for its network, nothing is changed and
115
+ `error.details` lists the problems by index.
116
+
53
117
  ## Receiving webhooks
54
118
 
55
- Every webhook is a `POST` with JSON `{ tx: { network, asset, contract, type, id, block, timestamp, from, to, value, logIndex? } }`
56
- and an `x-signature` header — HMAC-SHA256 of the raw body with your client's secret. Verify it against the **raw**
57
- body: re-serialized JSON will not match.
119
+ Every webhook is a `POST` request with a JSON body and an `x-signature` header — an HMAC-SHA256 of the raw body keyed
120
+ with your webhook secret. `parseWebhook` verifies the signature and returns a typed payload.
121
+
122
+ **Express**
58
123
 
59
124
  ```ts
60
125
  import express from 'express'
61
126
  import { isTestWebhook, parseWebhook, webhookIdempotencyKey, WebhookSignatureError } from '@v3finance/monitoring-sdk'
62
127
 
128
+ const app = express()
129
+
63
130
  app.post('/webhooks/monitoring', express.raw({ type: 'application/json' }), async (req, res) => {
64
131
  try {
65
132
  const event = await parseWebhook(req.body, req.headers, process.env.MONITORING_WEBHOOK_SECRET!)
66
- if (!isTestWebhook(event)) await creditOnce(webhookIdempotencyKey(event), event.tx)
133
+ if (!isTestWebhook(event)) {
134
+ await creditOnce(webhookIdempotencyKey(event), event.tx)
135
+ }
67
136
  res.sendStatus(200)
68
- } catch (e) {
69
- if (e instanceof WebhookSignatureError) return res.sendStatus(401)
70
- throw e
137
+ } catch (error) {
138
+ if (error instanceof WebhookSignatureError) return res.sendStatus(401)
139
+ throw error
71
140
  }
72
141
  })
73
142
  ```
74
143
 
75
- Hono, Next.js route handlers, Cloudflare Workers:
144
+ **Next.js (App Router)** — and any runtime built on the Fetch API: Cloudflare Workers, Bun, Deno
76
145
 
77
146
  ```ts
78
- const event = await parseWebhook(await request.text(), request.headers, env.MONITORING_WEBHOOK_SECRET)
147
+ export async function POST(request: Request) {
148
+ const event = await parseWebhook(await request.text(), request.headers, process.env.MONITORING_WEBHOOK_SECRET!)
149
+ // …
150
+ return new Response(null, { status: 200 })
151
+ }
79
152
  ```
80
153
 
81
- Rules of delivery:
154
+ **Hono**
82
155
 
83
- - Answer **2xx within 15 seconds**; otherwise the webhook is retried after 10 s, 1 min and 5 min.
84
- - The same webhook can arrive more than once — process it idempotently by `webhookIdempotencyKey(event)`.
85
- - `type` is always `TOPUP` for both directions: compare `from` and `to` with your addresses.
86
- - A webhook is sent as soon as the transfer is in a block, before finality. For large amounts check
87
- `final` first (below).
88
- - Test webhooks (`isTestWebhook(event)`, header `x-webhook-test: 1`) must not be credited.
156
+ ```ts
157
+ app.post('/webhooks/monitoring', async (c) => {
158
+ const event = await parseWebhook(await c.req.text(), c.req.raw.headers, c.env.MONITORING_WEBHOOK_SECRET)
159
+ // …
160
+ return c.body(null, 200)
161
+ })
162
+ ```
89
163
 
90
- ## Transactions: confirmations and finality
164
+ The payload:
165
+
166
+ ```json
167
+ {
168
+ "tx": {
169
+ "network": "TRON",
170
+ "asset": "USDT",
171
+ "contract": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
172
+ "type": "TOPUP",
173
+ "id": "1249cb7b7edd42072684b1db37ad495d4a5b7eefd1aff83e595e9bdb63a5fc45",
174
+ "block": 87445412,
175
+ "timestamp": 1793009472000,
176
+ "from": "TW9goADYcUxskhQQRifvwoRBUMHnmTh9MA",
177
+ "to": "TA8HgQbFjuMLWCaJeGyfrv8FErWSHz82vr",
178
+ "value": "100000000"
179
+ }
180
+ }
181
+ ```
182
+
183
+ Best practices:
91
184
 
92
- Any transaction by hash, not only the ones you got a webhook for:
185
+ - **Verify against the raw body.** Parsing and re-serializing the JSON changes the bytes and breaks the signature.
186
+ - **Respond quickly.** Return a 2xx status within 15 seconds; otherwise the webhook is retried after 10 seconds,
187
+ 1 minute and 5 minutes.
188
+ - **Process idempotently.** A webhook may be delivered more than once — deduplicate with `webhookIdempotencyKey(event)`.
189
+ - **Check the direction.** `type` is `TOPUP` for both directions; compare `from` and `to` with your addresses.
190
+ - **Wait for finality on large amounts.** Webhooks are sent as soon as a transfer is included in a block — see
191
+ [Transactions and finality](#transactions-and-finality).
192
+ - **Ignore test webhooks** — `isTestWebhook(event)` is `true` for them.
193
+
194
+ Send a test webhook to check your endpoint:
93
195
 
94
196
  ```ts
95
- const tx = await monitoring.transactions.get('tron', event.tx.id)
96
- tx.status // 'success' | 'failed' | 'pending'
97
- tx.confirmations // from the current head of the network
98
- tx.final // cannot be reverted: TRON — solidified (~1 min), Ethereum — finalized (~13 min)
99
- tx.transfers // every transfer inside: native, tokens, TRON internal TRX transfers
100
- tx.watched // your watched addresses in this transaction
101
- tx.webhooks // webhooks we sent you for it
197
+ const { delivery, signature, body } = await monitoring.webhooks.sendTest({ asset: 'USDT' })
198
+ console.log(delivery.ok ? 'Delivered' : `Endpoint responded with ${delivery.status ?? delivery.error}`)
102
199
  ```
103
200
 
104
- ## Addresses and subscriptions
201
+ ## Transactions and finality
202
+
203
+ Look up any transaction on a supported network — not only the ones you were notified about.
105
204
 
106
205
  ```ts
107
- await monitoring.addresses.add(clientId, items, { assets: ['USDT'], direction: 'in' }) // more than 1000 — batched for you
108
- await monitoring.addresses.update(clientId, [{ network: 'tron', address: 'T…' }], { direction: 'both' })
109
- await monitoring.addresses.remove(clientId, [{ network: 'tron', address: 'T…' }])
206
+ const tx = await monitoring.transactions.get('tron', event.tx.id)
110
207
 
111
- for await (const a of monitoring.addresses.iterate(clientId, { network: 'tron' })) {
112
- console.log(a.address, a.assets ?? 'all assets', a.direction)
113
- }
208
+ tx.status // 'success' | 'failed' | 'pending'
209
+ tx.confirmations // blocks since inclusion
210
+ tx.final // the transaction can no longer be reverted
211
+ tx.fee // { asset: 'TRX', value: '6773500' }
212
+ tx.transfers // every transfer inside the transaction
213
+ tx.watched // your monitored addresses involved
214
+ tx.webhooks // webhooks sent to you for this transaction
114
215
  ```
115
216
 
116
- A subscription narrows what you are notified about: `assets` — symbols or contract addresses (`null` — all assets of
117
- the network, including ones added later), `direction` — `in`, `out` or `both`. EVM addresses are per network: watch
118
- one address on several networks with several items.
217
+ A transaction is final once its block is solidified on TRON (about 1 minute) or finalized on EVM networks (about
218
+ 13 minutes on Ethereum). Credit large amounts once `final` is `true`.
119
219
 
120
- ## Webhook history
220
+ ## Delivery history
221
+
222
+ Every webhook sent to you is recorded with its status, attempts and your endpoint's response, and kept for 90 days.
121
223
 
122
224
  ```ts
123
- for await (const d of monitoring.deliveries.iterate(clientId, { status: 'failed', since: new Date(Date.now() - 86_400_000) })) {
124
- console.log(d.txId, d.attempts, d.lastHttpStatus ?? d.lastError)
225
+ for await (const delivery of monitoring.deliveries.iterate({ status: 'failed', since: new Date(Date.now() - 86_400_000) })) {
226
+ console.log(delivery.txId, delivery.attempts, delivery.lastHttpStatus ?? delivery.lastError)
125
227
  }
126
- const detail = await monitoring.deliveries.get(clientId, id) // exact body and URL
228
+
229
+ const detail = await monitoring.deliveries.get(deliveryId) // includes the exact request body
127
230
  ```
128
231
 
129
- ## Your client
232
+ Filter by `status` (`delivered`, `retrying`, `failed`), `network`, `asset`, `tx`, `address`, `since` and `until`.
130
233
 
131
- Owner and admin of a client (session or personal key):
234
+ ## Networks and assets
132
235
 
133
236
  ```ts
134
- await monitoring.clients.update(clientId, { webhookUrl: 'https://example.com/webhooks/monitoring' })
135
- const { secretKey } = await monitoring.clients.rotateSecret(clientId) // the old secret stops working at once
136
- const { key } = await monitoring.clients.keys.create(clientId, { name: 'backend', expiresInDays: 365 })
137
- const result = await monitoring.clients.sendTestWebhook(clientId, { asset: 'USDT' }) // result.delivery.ok
237
+ const networks = await monitoring.networks.list()
238
+ const assets = await monitoring.assets.list({ network: 'tron' })
138
239
  ```
139
240
 
241
+ You are notified about transfers of enabled assets of at least the asset's `minAmount`.
242
+
140
243
  ## Amounts
141
244
 
142
- Amounts are strings in minimal units (sun, wei; USDT has 6 decimals). Convert without losing precision:
245
+ Amounts are strings in the asset's smallest unit (sun, wei; USDT has 6 decimals). Convert them without losing
246
+ precision:
143
247
 
144
248
  ```ts
145
249
  import { formatUnits, parseUnits } from '@v3finance/monitoring-sdk'
@@ -148,101 +252,72 @@ formatUnits('100000000', 6) // '100'
148
252
  parseUnits('1.5', 6) // '1500000'
149
253
  ```
150
254
 
151
- Decimals of every asset: `monitoring.assets.list()`.
255
+ ## Error handling
152
256
 
153
- ## Errors, retries, timeouts
257
+ All errors extend `MonitoringError`.
258
+
259
+ | Error | When |
260
+ |---|---|
261
+ | `MonitoringApiError` | The API responded with an error. Has `status`, `code`, `details` and `requestId`. |
262
+ | `MonitoringConnectionError` | The request failed to reach the API. |
263
+ | `MonitoringTimeoutError` | The request exceeded `timeoutMs`. |
264
+ | `WebhookSignatureError` | A webhook signature does not match. |
154
265
 
155
266
  ```ts
156
- import { MonitoringApiError, MonitoringConnectionError } from '@v3finance/monitoring-sdk'
267
+ import { MonitoringApiError } from '@v3finance/monitoring-sdk'
157
268
 
158
269
  try {
159
- await monitoring.addresses.add(clientId, items)
160
- } catch (e) {
161
- if (e instanceof MonitoringApiError) {
162
- e.status // 400
163
- e.code // 'invalid_request'
164
- e.details // [{ index: 3, message: 'not a valid TRON address' }]
165
- e.requestId // send it to support
270
+ await monitoring.addresses.add(items)
271
+ } catch (error) {
272
+ if (error instanceof MonitoringApiError && error.status === 400) {
273
+ for (const { index, message } of error.details) console.error(`Item ${index}: ${message}`)
274
+ } else {
275
+ throw error
166
276
  }
167
277
  }
168
278
  ```
169
279
 
170
- - `429` and `503` are retried with the server's `Retry-After` or exponential backoff (`maxRetries`, default 2).
171
- Network errors are retried only for requests that are safe to repeat.
172
- - Every request has a timeout (`timeoutMs`, default 30 s) and accepts an `AbortSignal`:
173
- `monitoring.addresses.list(clientId, {}, { signal })`.
174
- - All errors extend `MonitoringError`.
175
-
176
- ## API reference
177
-
178
- - Interactive reference: https://monitoring.v3.finance/docs
179
- - OpenAPI 3.1: https://monitoring.v3.finance/openapi.json
180
- - All request and response types are exported: `import type { Transaction, WebhookPayload } from '@v3finance/monitoring-sdk'`.
181
-
182
- ## Versioning
183
-
184
- [SemVer](https://semver.org). While the version is `0.x`, minor releases may contain breaking changes; they are listed in
185
- [CHANGELOG.md](./CHANGELOG.md).
186
-
187
- ---
280
+ ## Retries, timeouts and cancellation
188
281
 
189
- ## По-русски
190
-
191
- Официальный SDK API мониторинга адресов V3 Finance: адреса в TRON и EVM-сетях, подписанные вебхуки о переводах,
192
- история доставок, транзакции с подтверждениями и финальностью. Подсказки в редакторе — по-русски.
193
-
194
- ```bash
195
- npm install @v3finance/monitoring-sdk
196
- ```
197
-
198
- **Только для сервера** — ключ в браузере увидит любой. Node.js 20+, Bun, Deno, Cloudflare Workers; ESM и CommonJS.
282
+ Rate-limited (`429`) and temporarily unavailable (`503`) requests are retried automatically with exponential backoff,
283
+ honoring `Retry-After`. Network errors are retried only for requests that are safe to repeat. Configure this with
284
+ `maxRetries` and `timeoutMs`, globally or per request:
199
285
 
200
286
  ```ts
201
- import { MonitoringClient, parseWebhook, isTestWebhook, webhookIdempotencyKey } from '@v3finance/monitoring-sdk'
287
+ const controller = new AbortController()
202
288
 
203
- const monitoring = new MonitoringClient({ apiKey: process.env.MONITORING_API_KEY }) // ключ клиента ce_…
204
- const clientId = (await monitoring.account.me()).actor.clientId!
289
+ await monitoring.addresses.list({ network: 'tron' }, { timeoutMs: 5_000, maxRetries: 0, signal: controller.signal })
290
+ ```
205
291
 
206
- // депозитные адреса: только входящие USDT
207
- await monitoring.addresses.add(clientId, [{ network: 'tron', address: 'T…', label: 'user-42' }], { assets: ['USDT'], direction: 'in' })
292
+ ## TypeScript
208
293
 
209
- // приём вебхука: подпись — по сырому телу
210
- const event = await parseWebhook(rawBody, headers, process.env.MONITORING_WEBHOOK_SECRET!)
211
- if (!isTestWebhook(event)) await creditOnce(webhookIdempotencyKey(event), event.tx)
294
+ The SDK is written in TypeScript and ships its own type declarations. All request and response types are exported:
212
295
 
213
- // перед зачислением крупной суммы — финальность
214
- const tx = await monitoring.transactions.get('tron', event.tx.id)
215
- if (tx.status === 'success' && tx.final) { /* зачислить */ }
296
+ ```ts
297
+ import type { Address, Delivery, Transaction, WebhookPayload } from '@v3finance/monitoring-sdk'
216
298
  ```
217
299
 
218
- Главное при приёме вебхуков:
300
+ ## Requirements
301
+
302
+ - Node.js 20 or later, Bun, Deno or Cloudflare Workers.
303
+ - ESM (`import`) and CommonJS (`require`) are both supported.
219
304
 
220
- - отвечайте **2xx за 15 секунд**, иначе повторы через 10 с, 1 мин и 5 мин;
221
- - один вебхук может прийти повторно — обрабатывайте идемпотентно по `webhookIdempotencyKey(event)`;
222
- - `type` всегда `TOPUP` — направление определяйте по `from` и `to`;
223
- - вебхук уходит сразу, как перевод попал в блок, до финальности: крупные суммы зачисляйте после `final`;
224
- - тестовые вебхуки (`isTestWebhook`, заголовок `x-webhook-test: 1`) не зачислять.
305
+ ## Security
225
306
 
226
- Ключи: **ключ клиента** `ce_…` — адреса, история и транзакции своего клиента; **личный ключ** `ce_user_…` — всё, что вы
227
- можете в панели (URL вебхука, секрет, ключи клиента, тестовый вебхук). Ошибки — `MonitoringApiError` со статусом, кодом
228
- и ошибками по элементам (`details`); повторы при 429 и 503, таймауты и отмена через `AbortSignal` — встроены.
229
- Суммы — строки в минимальных единицах: `formatUnits('100000000', 6) === '100'`.
307
+ - Use the SDK on your servers only. Never expose your API key or webhook secret to browsers or mobile apps.
308
+ - Keep credentials in environment variables or a secrets manager, not in source code.
309
+ - Always verify webhook signatures before processing a webhook.
230
310
 
231
- Справочник API: https://monitoring.v3.finance/docs.
311
+ ## Versioning
232
312
 
233
- ## Development
313
+ This package follows [Semantic Versioning](https://semver.org). Changes are listed in [CHANGELOG.md](./CHANGELOG.md).
234
314
 
235
- ```bash
236
- npm install
237
- npm run spec:update # snapshot of https://monitoring.v3.finance/openapi.json → openapi/openapi.json
238
- npm run generate # → src/generated/types.ts
239
- npm run typecheck && npm test && npm run build
240
- npm run build && MONITORING_API_KEY=ce_… node scripts/smoke.ts # against the real API, with a client key
241
- ```
315
+ ## Support
242
316
 
243
- Releases: bump `version` in `package.json` and `src/version.ts`, update `CHANGELOG.md`, publish a GitHub release
244
- `vX.Y.Z` — the `publish` workflow publishes to npm with Trusted Publishing.
317
+ - API reference: [monitoring.v3.finance/docs](https://monitoring.v3.finance/docs)
318
+ - OpenAPI specification: [monitoring.v3.finance/openapi.json](https://monitoring.v3.finance/openapi.json)
319
+ - For access and support, contact your V3 Finance account manager.
245
320
 
246
321
  ## License
247
322
 
248
- [MIT](./LICENSE)
323
+ [MIT](./LICENSE) © V3 Finance
@@ -1,65 +1,46 @@
1
- import { type ClientOptions, type RequestOptions } from './core/http.js';
2
- import { AccountResource, AuthResource, type SignInResult } from './resources/account.js';
1
+ import { type ClientOptions } from './core/http.js';
2
+ import { AccountResource } from './resources/account.js';
3
3
  import { AddressesResource } from './resources/addresses.js';
4
4
  import { AssetsResource, NetworksResource } from './resources/catalog.js';
5
- import { ClientsResource } from './resources/clients.js';
6
5
  import { DeliveriesResource } from './resources/deliveries.js';
7
6
  import { TransactionsResource } from './resources/transactions.js';
7
+ import { WebhooksResource } from './resources/webhooks.js';
8
8
  /**
9
- * Клиент API мониторинга адресов V3 Finance: адреса и подписки, история вебхуков, транзакции, ваш клиент и ключи.
10
- * Только для сервера: ключ в браузере увидит любой.
9
+ * Client for the V3 Finance Monitoring API.
11
10
  *
12
- * @example С ключом клиента — для бэкенда
11
+ * Use it on the server only: an API key in a browser is visible to anyone.
12
+ *
13
+ * @example
13
14
  * ```ts
14
15
  * import { MonitoringClient } from '@v3finance/monitoring-sdk'
15
16
  *
16
- * const monitoring = new MonitoringClient({ apiKey: process.env.MONITORING_API_KEY })
17
- * await monitoring.addresses.add(clientId, [{ network: 'tron', address: 'T…' }], { assets: ['USDT'], direction: 'in' })
18
- * ```
17
+ * const monitoring = new MonitoringClient({ apiKey: process.env.MONITORING_API_KEY! })
19
18
  *
20
- * @example По паролю — для скриптов, которым нужны права пользователя
21
- * ```ts
22
- * const { client } = await MonitoringClient.signIn({ email, password })
23
- * const { key } = await client.account.keys.create({ name: 'ci' })
19
+ * await monitoring.addresses.add([{ network: 'tron', address: 'TA8Hg…' }], { assets: ['USDT'], direction: 'in' })
24
20
  * ```
25
21
  */
26
22
  export declare class MonitoringClient {
27
23
  #private;
28
- /** Кто вы и ваши личные ключи */
24
+ /** Your client: the account your API key belongs to. */
29
25
  readonly account: AccountResource;
30
- /** Выход и смена пароля (для клиента, вошедшего по паролю) */
31
- readonly auth: AuthResource;
32
- /** Сети */
33
- readonly networks: NetworksResource;
34
- /** Нативные монеты и токены */
35
- readonly assets: AssetsResource;
36
- /** Ваш клиент: URL вебхука, секрет, ключи, участники, тестовый вебхук */
37
- readonly clients: ClientsResource;
38
- /** Адреса на мониторинге и подписка */
26
+ /** Addresses you monitor and their subscriptions. */
39
27
  readonly addresses: AddressesResource;
40
- /** История вебхуков */
28
+ /** Test your webhook endpoint. */
29
+ readonly webhooks: WebhooksResource;
30
+ /** History of webhooks sent to you. */
41
31
  readonly deliveries: DeliveriesResource;
42
- /** Транзакция по хешу: статус, подтверждения, финальность */
32
+ /** Any transaction by hash, with confirmations and finality. */
43
33
  readonly transactions: TransactionsResource;
34
+ /** Supported networks. */
35
+ readonly networks: NetworksResource;
36
+ /** Supported native coins and tokens. */
37
+ readonly assets: AssetsResource;
44
38
  /**
45
- * @param options - ключ (`apiKey`) или токен сессии (`sessionToken`), адрес API, таймаут, повторы
46
- * @throws {@link MonitoringError} переданы и ключ, и токен; нет `fetch`
39
+ * @param options - API key and optional settings.
40
+ * @throws {@link MonitoringError} when `apiKey` is missing or `fetch` is not available.
47
41
  */
48
- constructor(options?: ClientOptions);
49
- /** Адрес API, с которым работает клиент */
42
+ constructor(options: ClientOptions);
43
+ /** API base URL this client sends requests to. */
50
44
  get baseUrl(): string;
51
- /**
52
- * Вход по email и паролю: возвращает клиента с токеном сессии. Регистрации нет — пользователей заводит
53
- * администратор сервиса. Не больше 3 попыток за 10 секунд с одного IP.
54
- *
55
- * @param options - настройки клиента, кроме учётных данных
56
- * @throws {@link MonitoringApiError} 401 — неверный email или пароль
57
- */
58
- static signIn(credentials: {
59
- email: string;
60
- password: string;
61
- }, options?: Omit<ClientOptions, 'apiKey' | 'sessionToken'>, requestOptions?: RequestOptions): Promise<SignInResult & {
62
- client: MonitoringClient;
63
- }>;
64
45
  }
65
46
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpF,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,wBAAwB,CAAA;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAGlE;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,gBAAgB;;IAC3B,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;IACjC,8DAA8D;IAC9D,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,WAAW;IACX,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAA;IACnC,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;IACjC,uCAAuC;IACvC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAA;IACrC,uBAAuB;IACvB,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAA;IACvC,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAA;IAI3C;;;OAGG;IACH,YAAY,OAAO,GAAE,aAAkB,EAUtC;IAED,2CAA2C;IAC3C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED;;;;;;OAMG;IACH,OAAa,MAAM,CACjB,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAChD,OAAO,GAAE,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,cAAc,CAAM,EAC5D,cAAc,CAAC,EAAE,cAAc,GAC9B,OAAO,CAAC,YAAY,GAAG;QAAE,MAAM,EAAE,gBAAgB,CAAA;KAAE,CAAC,CAYtD;CACF"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAG1D;;;;;;;;;;;;;GAaG;AACH,qBAAa,gBAAgB;;IAC3B,wDAAwD;IACxD,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;IACjC,qDAAqD;IACrD,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAA;IACrC,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAA;IACnC,uCAAuC;IACvC,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAA;IACvC,gEAAgE;IAChE,QAAQ,CAAC,YAAY,EAAE,oBAAoB,CAAA;IAC3C,0BAA0B;IAC1B,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAA;IACnC,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;IAK/B;;;OAGG;IACH,YAAY,OAAO,EAAE,aAAa,EAWjC;IAED,kDAAkD;IAClD,IAAI,OAAO,IAAI,MAAM,CAEpB;CAiBF"}