@v3finance/monitoring-sdk 0.0.0-stage → 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 (149) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +21 -0
  3. package/README.md +322 -2
  4. package/dist/cjs/client.d.ts +46 -0
  5. package/dist/cjs/client.d.ts.map +1 -0
  6. package/dist/cjs/client.js +80 -0
  7. package/dist/cjs/client.js.map +1 -0
  8. package/dist/cjs/core/errors.d.ts +64 -0
  9. package/dist/cjs/core/errors.d.ts.map +1 -0
  10. package/dist/cjs/core/errors.js +95 -0
  11. package/dist/cjs/core/errors.js.map +1 -0
  12. package/dist/cjs/core/http.d.ts +58 -0
  13. package/dist/cjs/core/http.d.ts.map +1 -0
  14. package/dist/cjs/core/http.js +143 -0
  15. package/dist/cjs/core/http.js.map +1 -0
  16. package/dist/cjs/core/pagination.d.ts +12 -0
  17. package/dist/cjs/core/pagination.d.ts.map +1 -0
  18. package/dist/cjs/core/pagination.js +15 -0
  19. package/dist/cjs/core/pagination.js.map +1 -0
  20. package/dist/cjs/core/scope.d.ts +8 -0
  21. package/dist/cjs/core/scope.d.ts.map +1 -0
  22. package/dist/cjs/core/scope.js +3 -0
  23. package/dist/cjs/core/scope.js.map +1 -0
  24. package/dist/cjs/generated/types.d.ts +336 -0
  25. package/dist/cjs/generated/types.d.ts.map +1 -0
  26. package/dist/cjs/generated/types.js +5 -0
  27. package/dist/cjs/generated/types.js.map +1 -0
  28. package/dist/cjs/index.d.ts +23 -0
  29. package/dist/cjs/index.d.ts.map +1 -0
  30. package/dist/cjs/index.js +47 -0
  31. package/dist/cjs/index.js.map +1 -0
  32. package/dist/cjs/package.json +1 -0
  33. package/dist/cjs/resources/account.d.ts +22 -0
  34. package/dist/cjs/resources/account.d.ts.map +1 -0
  35. package/dist/cjs/resources/account.js +31 -0
  36. package/dist/cjs/resources/account.js.map +1 -0
  37. package/dist/cjs/resources/addresses.d.ts +93 -0
  38. package/dist/cjs/resources/addresses.d.ts.map +1 -0
  39. package/dist/cjs/resources/addresses.js +128 -0
  40. package/dist/cjs/resources/addresses.js.map +1 -0
  41. package/dist/cjs/resources/catalog.d.ts +37 -0
  42. package/dist/cjs/resources/catalog.d.ts.map +1 -0
  43. package/dist/cjs/resources/catalog.js +52 -0
  44. package/dist/cjs/resources/catalog.js.map +1 -0
  45. package/dist/cjs/resources/deliveries.d.ts +61 -0
  46. package/dist/cjs/resources/deliveries.d.ts.map +1 -0
  47. package/dist/cjs/resources/deliveries.js +53 -0
  48. package/dist/cjs/resources/deliveries.js.map +1 -0
  49. package/dist/cjs/resources/transactions.d.ts +28 -0
  50. package/dist/cjs/resources/transactions.d.ts.map +1 -0
  51. package/dist/cjs/resources/transactions.js +34 -0
  52. package/dist/cjs/resources/transactions.js.map +1 -0
  53. package/dist/cjs/resources/webhooks.d.ts +22 -0
  54. package/dist/cjs/resources/webhooks.d.ts.map +1 -0
  55. package/dist/cjs/resources/webhooks.js +35 -0
  56. package/dist/cjs/resources/webhooks.js.map +1 -0
  57. package/dist/cjs/units.d.ts +29 -0
  58. package/dist/cjs/units.d.ts.map +1 -0
  59. package/dist/cjs/units.js +62 -0
  60. package/dist/cjs/units.js.map +1 -0
  61. package/dist/cjs/version.d.ts +5 -0
  62. package/dist/cjs/version.d.ts.map +1 -0
  63. package/dist/cjs/version.js +8 -0
  64. package/dist/cjs/version.js.map +1 -0
  65. package/dist/cjs/webhooks.d.ts +82 -0
  66. package/dist/cjs/webhooks.d.ts.map +1 -0
  67. package/dist/cjs/webhooks.js +133 -0
  68. package/dist/cjs/webhooks.js.map +1 -0
  69. package/dist/esm/client.d.ts +46 -0
  70. package/dist/esm/client.d.ts.map +1 -0
  71. package/dist/esm/client.js +76 -0
  72. package/dist/esm/client.js.map +1 -0
  73. package/dist/esm/core/errors.d.ts +64 -0
  74. package/dist/esm/core/errors.d.ts.map +1 -0
  75. package/dist/esm/core/errors.js +86 -0
  76. package/dist/esm/core/errors.js.map +1 -0
  77. package/dist/esm/core/http.d.ts +58 -0
  78. package/dist/esm/core/http.d.ts.map +1 -0
  79. package/dist/esm/core/http.js +138 -0
  80. package/dist/esm/core/http.js.map +1 -0
  81. package/dist/esm/core/pagination.d.ts +12 -0
  82. package/dist/esm/core/pagination.d.ts.map +1 -0
  83. package/dist/esm/core/pagination.js +12 -0
  84. package/dist/esm/core/pagination.js.map +1 -0
  85. package/dist/esm/core/scope.d.ts +8 -0
  86. package/dist/esm/core/scope.d.ts.map +1 -0
  87. package/dist/esm/core/scope.js +2 -0
  88. package/dist/esm/core/scope.js.map +1 -0
  89. package/dist/esm/generated/types.d.ts +336 -0
  90. package/dist/esm/generated/types.d.ts.map +1 -0
  91. package/dist/esm/generated/types.js +4 -0
  92. package/dist/esm/generated/types.js.map +1 -0
  93. package/dist/esm/index.d.ts +23 -0
  94. package/dist/esm/index.d.ts.map +1 -0
  95. package/dist/esm/index.js +20 -0
  96. package/dist/esm/index.js.map +1 -0
  97. package/dist/esm/resources/account.d.ts +22 -0
  98. package/dist/esm/resources/account.d.ts.map +1 -0
  99. package/dist/esm/resources/account.js +27 -0
  100. package/dist/esm/resources/account.js.map +1 -0
  101. package/dist/esm/resources/addresses.d.ts +93 -0
  102. package/dist/esm/resources/addresses.d.ts.map +1 -0
  103. package/dist/esm/resources/addresses.js +124 -0
  104. package/dist/esm/resources/addresses.js.map +1 -0
  105. package/dist/esm/resources/catalog.d.ts +37 -0
  106. package/dist/esm/resources/catalog.d.ts.map +1 -0
  107. package/dist/esm/resources/catalog.js +47 -0
  108. package/dist/esm/resources/catalog.js.map +1 -0
  109. package/dist/esm/resources/deliveries.d.ts +61 -0
  110. package/dist/esm/resources/deliveries.d.ts.map +1 -0
  111. package/dist/esm/resources/deliveries.js +49 -0
  112. package/dist/esm/resources/deliveries.js.map +1 -0
  113. package/dist/esm/resources/transactions.d.ts +28 -0
  114. package/dist/esm/resources/transactions.d.ts.map +1 -0
  115. package/dist/esm/resources/transactions.js +30 -0
  116. package/dist/esm/resources/transactions.js.map +1 -0
  117. package/dist/esm/resources/webhooks.d.ts +22 -0
  118. package/dist/esm/resources/webhooks.d.ts.map +1 -0
  119. package/dist/esm/resources/webhooks.js +31 -0
  120. package/dist/esm/resources/webhooks.js.map +1 -0
  121. package/dist/esm/units.d.ts +29 -0
  122. package/dist/esm/units.d.ts.map +1 -0
  123. package/dist/esm/units.js +58 -0
  124. package/dist/esm/units.js.map +1 -0
  125. package/dist/esm/version.d.ts +5 -0
  126. package/dist/esm/version.d.ts.map +1 -0
  127. package/dist/esm/version.js +5 -0
  128. package/dist/esm/version.js.map +1 -0
  129. package/dist/esm/webhooks.d.ts +82 -0
  130. package/dist/esm/webhooks.d.ts.map +1 -0
  131. package/dist/esm/webhooks.js +125 -0
  132. package/dist/esm/webhooks.js.map +1 -0
  133. package/package.json +69 -4
  134. package/src/client.ts +83 -0
  135. package/src/core/errors.ts +99 -0
  136. package/src/core/http.ts +183 -0
  137. package/src/core/pagination.ts +20 -0
  138. package/src/core/scope.ts +8 -0
  139. package/src/generated/types.ts +369 -0
  140. package/src/index.ts +43 -0
  141. package/src/resources/account.ts +33 -0
  142. package/src/resources/addresses.ts +165 -0
  143. package/src/resources/catalog.ts +56 -0
  144. package/src/resources/deliveries.ts +82 -0
  145. package/src/resources/transactions.ts +34 -0
  146. package/src/resources/webhooks.ts +36 -0
  147. package/src/units.ts +56 -0
  148. package/src/version.ts +5 -0
  149. package/src/webhooks.ts +138 -0
@@ -0,0 +1,20 @@
1
+ /**
2
+ * A page of results. `next` is the cursor of the next page; `null` when there are no more pages.
3
+ *
4
+ * @typeParam T - Item type.
5
+ */
6
+ export interface Page<T> {
7
+ items: T[]
8
+ next: number | null
9
+ }
10
+
11
+ /** @internal Yields every item, fetching the next page only when the current one is exhausted. */
12
+ export async function* paginate<T>(fetchPage: (cursor: number | undefined) => Promise<Page<T>>): AsyncGenerator<T, void, undefined> {
13
+ let cursor: number | undefined
14
+ for (;;) {
15
+ const page = await fetchPage(cursor)
16
+ yield* page.items
17
+ if (page.next === null || page.next === undefined) return
18
+ cursor = page.next
19
+ }
20
+ }
@@ -0,0 +1,8 @@
1
+ import type { HttpClient } from './http.js'
2
+
3
+ /** @internal What resources share: the transport and the client ID of the API key. */
4
+ export interface Scope {
5
+ http: HttpClient
6
+ /** Path segment of the client: resolved from the API key once, then cached. */
7
+ clientPath: () => Promise<string>
8
+ }
@@ -0,0 +1,369 @@
1
+ // Generated from openapi/openapi.json by scripts/generate.ts — do not edit by hand.
2
+ // V3 Finance Monitoring API 1.0.0. Regenerate: npm run spec:update && npm run generate
3
+
4
+ export interface ApiErrorBody {
5
+ error: {
6
+ /**
7
+ * Machine-readable error code.
8
+ * @example "invalid_request"
9
+ */
10
+ code: string
11
+ /** Human-readable description. */
12
+ message: string
13
+ /** Per-item problems of a batch request. */
14
+ details?: Array<{
15
+ /** Index of the item in the request. */
16
+ index: number
17
+ message: string
18
+ }>
19
+ }
20
+ }
21
+
22
+ export interface User {
23
+ id: string
24
+ email: string
25
+ name: string
26
+ role?: "admin" | "user"
27
+ banned?: boolean
28
+ createdAt?: string
29
+ }
30
+
31
+ export interface Identity {
32
+ actor: {
33
+ /** `client-key` for a client API key. */
34
+ kind: "client-key" | "user" | "admin"
35
+ /** Your client ID (client API keys). */
36
+ clientId?: string
37
+ /** ID of the API key (client API keys). */
38
+ keyId?: string
39
+ userId?: string | null
40
+ via?: "session" | "api-key" | "token"
41
+ }
42
+ user: User | null
43
+ memberships: Array<{
44
+ clientId: string
45
+ role: "owner" | "admin" | "member"
46
+ }>
47
+ }
48
+
49
+ export interface Client {
50
+ /** Client ID. */
51
+ id: string
52
+ name: string | null
53
+ /** Where webhooks are sent. */
54
+ webhookUrl: string
55
+ /** `disabled` — webhooks are not sent. */
56
+ status: "active" | "disabled"
57
+ /** format: date-time */
58
+ createdAt: string
59
+ }
60
+
61
+ export interface Network {
62
+ id: number
63
+ /**
64
+ * Network identifier used across the API.
65
+ * @example "tron"
66
+ */
67
+ slug: string
68
+ /**
69
+ * CAIP-2 chain ID.
70
+ * @example "tron:0x2b6653dc"
71
+ */
72
+ caip2: string
73
+ chainId: number
74
+ name: string
75
+ shortName: string | null
76
+ /** 1 for L1 networks, 2 for L2 rollups. */
77
+ layer: 1 | 2
78
+ parent: string | null
79
+ l2Type: string | null
80
+ l2Stack: string | null
81
+ isTestnet: boolean
82
+ explorerUrl: string | null
83
+ /** Transfers on this network are monitored. */
84
+ enabled: boolean
85
+ }
86
+
87
+ export interface NetworkList {
88
+ items: Network[]
89
+ }
90
+
91
+ export interface Asset {
92
+ id: number
93
+ /** Network slug. */
94
+ network: string
95
+ /** CAIP-19 asset ID. */
96
+ caip19: string
97
+ standard: "native" | "erc20" | "trc20"
98
+ contract: string | null
99
+ /** @example "USDT" */
100
+ symbol: string
101
+ name: string
102
+ decimals: number
103
+ /** Smallest transfer you are notified about, in the smallest unit (inclusive). */
104
+ minAmount: string
105
+ /** Transfers of this asset are monitored. */
106
+ enabled: boolean
107
+ }
108
+
109
+ export interface AssetList {
110
+ items: Asset[]
111
+ }
112
+
113
+ /** `in` — the address receives, `out` — the address sends, `both` — either. */
114
+ export type Direction = "in" | "out" | "both"
115
+
116
+ /** Asset symbols (`USDT`) or contract addresses. `null` — all assets of the network, including ones added later. */
117
+ export type AssetSelection = string[] | null
118
+
119
+ export interface AddressInput {
120
+ /** Network slug or CAIP-2 ID. */
121
+ network: string
122
+ address: string
123
+ /**
124
+ * Your reference, e.g. a user or account ID.
125
+ *
126
+ * length: 0..200
127
+ */
128
+ label?: string
129
+ assets?: AssetSelection
130
+ direction?: Direction
131
+ }
132
+
133
+ export interface AddAddressesRequest {
134
+ /** items: 1..1000 */
135
+ addresses: AddressInput[]
136
+ assets?: AssetSelection
137
+ direction?: Direction
138
+ }
139
+
140
+ export interface AddAddressesResult {
141
+ /** Addresses that started being monitored. */
142
+ added: number
143
+ /** Addresses that were already monitored and left unchanged. */
144
+ alreadyWatched: number
145
+ }
146
+
147
+ export interface AddressUpdate {
148
+ network: string
149
+ address: string
150
+ assets?: AssetSelection
151
+ direction?: Direction
152
+ }
153
+
154
+ export interface UpdateAddressesRequest {
155
+ /** items: 1..1000 */
156
+ addresses: AddressUpdate[]
157
+ assets?: AssetSelection
158
+ direction?: Direction
159
+ }
160
+
161
+ export interface UpdateAddressesResult {
162
+ /** Addresses whose subscription was changed. */
163
+ updated: number
164
+ /** Addresses that are not monitored. */
165
+ notWatched: number
166
+ }
167
+
168
+ export interface AddressRef {
169
+ /** Network slug or CAIP-2 ID. */
170
+ network: string
171
+ address: string
172
+ }
173
+
174
+ export interface RemoveAddressesRequest {
175
+ /** items: 1..1000 */
176
+ addresses: AddressRef[]
177
+ }
178
+
179
+ export interface RemoveAddressesResult {
180
+ /** Addresses that stopped being monitored. */
181
+ removed: number
182
+ /** Addresses that were not monitored. */
183
+ notWatched: number
184
+ }
185
+
186
+ export interface Address {
187
+ id: number
188
+ network: string
189
+ /** CAIP-10 account ID. */
190
+ caip10: string
191
+ address: string
192
+ label: string | null
193
+ /** Subscribed asset symbols; `null` — all assets. */
194
+ assets: string[] | null
195
+ direction: Direction
196
+ /** format: date-time */
197
+ createdAt: string
198
+ }
199
+
200
+ /** A page of addresses. */
201
+ export interface AddressPage {
202
+ items: Address[]
203
+ /** Cursor for the next page — pass it as `after`. `null` when there are no more pages. */
204
+ next: number | null
205
+ }
206
+
207
+ /** `delivered` — you responded with 2xx; `retrying` — the last attempt failed and will be retried; `failed` — all attempts failed. */
208
+ export type DeliveryStatus = "delivered" | "retrying" | "failed"
209
+
210
+ export interface Delivery {
211
+ id: number
212
+ clientId: string
213
+ network: string
214
+ asset: string
215
+ contract: string
216
+ /** Transaction hash. */
217
+ txId: string
218
+ logIndex: number | null
219
+ block: number
220
+ /** Block time, milliseconds since epoch. */
221
+ blockTime: number
222
+ from: string
223
+ to: string
224
+ /** Amount in the smallest unit. */
225
+ value: string
226
+ status: DeliveryStatus
227
+ attempts: number
228
+ lastHttpStatus: number | null
229
+ lastError: string | null
230
+ lastDurationMs: number | null
231
+ /** format: date-time */
232
+ firstAttemptAt: string
233
+ /** format: date-time */
234
+ lastAttemptAt: string
235
+ deliveredAt: string | null
236
+ }
237
+
238
+ export type DeliveryDetail = Delivery & {
239
+ /** URL of the last attempt. */
240
+ url: string
241
+ /** Exact request body. */
242
+ body: string
243
+ }
244
+
245
+ /** A page of deliveries, newest first. */
246
+ export interface DeliveryPage {
247
+ items: Delivery[]
248
+ /** Cursor for the next page — pass it as `before`. `null` when there are no more pages. */
249
+ next: number | null
250
+ }
251
+
252
+ export interface TxTransfer {
253
+ /** `native` — sent by the transaction itself; `token` — a token Transfer event; `internal` — TRX sent by a contract; `trc10` — a TRC-10 token. */
254
+ kind: "native" | "token" | "internal" | "trc10"
255
+ asset: string | null
256
+ /** Token contract address, `native`, or the TRC-10 token ID. */
257
+ contract: string
258
+ from: string
259
+ to: string
260
+ /** Amount in the smallest unit. */
261
+ value: string
262
+ logIndex?: number
263
+ /** The asset is monitored: transfers of at least its `minAmount` are notified. */
264
+ tracked: boolean
265
+ }
266
+
267
+ export interface Transaction {
268
+ network: string
269
+ caip2: string
270
+ txId: string
271
+ /** `pending` — not yet included in a block. */
272
+ status: "success" | "failed" | "pending"
273
+ failure: string | null
274
+ block: number | null
275
+ blockTime: number | null
276
+ /** Blocks since inclusion, counting the block itself; `0` when pending. */
277
+ confirmations: number
278
+ /** The transaction can no longer be reverted. */
279
+ final: boolean
280
+ /** Signer of the transaction. */
281
+ from: string
282
+ to: string | null
283
+ /** TRON contract type (`TransferContract`, `TriggerSmartContract`, …) or, on EVM networks, `transfer`, `contract_call` or `contract_creation`. */
284
+ type: string
285
+ /** Native amount sent by the transaction itself. */
286
+ value: string
287
+ fee: {
288
+ asset: string
289
+ value: string
290
+ } | null
291
+ transfers: TxTransfer[]
292
+ /** Your monitored addresses involved in the transaction. */
293
+ watched: Array<{
294
+ clientId: string
295
+ address: string
296
+ direction: Direction
297
+ }>
298
+ /** Webhooks sent to you for this transaction. */
299
+ webhooks: Array<{
300
+ id: number
301
+ clientId: string
302
+ asset: string
303
+ value: string
304
+ status: DeliveryStatus
305
+ attempts: number
306
+ deliveredAt: string | null
307
+ }>
308
+ }
309
+
310
+ export interface WebhookTx {
311
+ /**
312
+ * Network slug in upper case.
313
+ * @example "TRON"
314
+ * @example "ETHEREUM"
315
+ */
316
+ network: string
317
+ /** @example "USDT" */
318
+ asset: string
319
+ /** Token contract address or `native`. */
320
+ contract: string
321
+ /** Always `TOPUP`, for both directions: compare `from` and `to` with your addresses. */
322
+ type: "TOPUP"
323
+ /** Transaction hash. */
324
+ id: string
325
+ block: number
326
+ /** Block time, milliseconds since epoch. */
327
+ timestamp: number
328
+ from: string
329
+ to: string
330
+ /** Amount in the smallest unit. */
331
+ value: string
332
+ /** Position of the transfer in the block, for EVM token transfers. */
333
+ logIndex?: number
334
+ }
335
+
336
+ export interface WebhookPayload {
337
+ tx: WebhookTx
338
+ /** Present on test webhooks only. */
339
+ test?: true
340
+ }
341
+
342
+ export interface TestWebhookRequest {
343
+ /** @defaultValue "USDT" */
344
+ asset?: "USDT" | "A7A5" | "TRX"
345
+ /** TRON address. */
346
+ from?: string
347
+ /** TRON address. */
348
+ to?: string
349
+ /** Amount in the smallest unit. */
350
+ value?: string
351
+ }
352
+
353
+ export interface TestDelivery {
354
+ /** Your endpoint responded with 2xx. */
355
+ ok: boolean
356
+ /** Status code of your response. */
357
+ status?: number
358
+ /** Connection error. */
359
+ error?: string
360
+ durationMs: number
361
+ }
362
+
363
+ export interface TestWebhookResult {
364
+ delivery: TestDelivery
365
+ /** Value of the `x-signature` header. */
366
+ signature: string
367
+ /** Exact request body. */
368
+ body: string
369
+ }
package/src/index.ts ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Official TypeScript SDK for the V3 Finance Monitoring API: monitor addresses on TRON and EVM networks and receive
3
+ * signed webhooks for every incoming and outgoing transfer.
4
+ *
5
+ * API reference: https://monitoring.v3.finance/docs
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+
10
+ export { MonitoringClient } from './client.js'
11
+ export type { ClientOptions, RequestOptions } from './core/http.js'
12
+ export type { Page } from './core/pagination.js'
13
+ export {
14
+ MonitoringApiError,
15
+ MonitoringConnectionError,
16
+ MonitoringError,
17
+ MonitoringTimeoutError,
18
+ WebhookSignatureError,
19
+ type ErrorDetail,
20
+ } from './core/errors.js'
21
+
22
+ export { AccountResource } from './resources/account.js'
23
+ export { ADDRESS_BATCH_SIZE, AddressesResource, type ListAddressesParams, type SubscriptionDefaults } from './resources/addresses.js'
24
+ export { AssetsResource, NetworksResource } from './resources/catalog.js'
25
+ export { DeliveriesResource, type DeliveryFilter, type ListDeliveriesParams } from './resources/deliveries.js'
26
+ export { TransactionsResource } from './resources/transactions.js'
27
+ export { WebhooksResource } from './resources/webhooks.js'
28
+
29
+ export {
30
+ isTestWebhook,
31
+ parseWebhook,
32
+ signWebhookBody,
33
+ verifyWebhookSignature,
34
+ WEBHOOK_HEADERS,
35
+ webhookIdempotencyKey,
36
+ type SignatureSource,
37
+ type WebhookBody,
38
+ } from './webhooks.js'
39
+ export { formatUnits, parseUnits } from './units.js'
40
+ export { DEFAULT_BASE_URL, SDK_VERSION } from './version.js'
41
+
42
+ // Request and response types, generated from the OpenAPI specification
43
+ export type * from './generated/types.js'
@@ -0,0 +1,33 @@
1
+ import type { RequestOptions } from '../core/http.js'
2
+ import type { Scope } from '../core/scope.js'
3
+ import type { Client } from '../generated/types.js'
4
+
5
+ /** Your client: the account your API key belongs to. */
6
+ export class AccountResource {
7
+ readonly #scope: Scope
8
+ readonly #resolveId: () => Promise<string>
9
+
10
+ /** @internal */
11
+ constructor(scope: Scope, resolveId: () => Promise<string>) {
12
+ this.#scope = scope
13
+ this.#resolveId = resolveId
14
+ }
15
+
16
+ /**
17
+ * Retrieves your client, including its webhook URL and status.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * const account = await monitoring.account.get()
22
+ * console.log(account.webhookUrl, account.status)
23
+ * ```
24
+ */
25
+ async get(options?: RequestOptions): Promise<Client> {
26
+ return this.#scope.http.request({ method: 'GET', path: await this.#scope.clientPath(), idempotent: true, options })
27
+ }
28
+
29
+ /** Returns your client ID — the value of the `x-client-id` header on every webhook. */
30
+ id(): Promise<string> {
31
+ return this.#resolveId()
32
+ }
33
+ }
@@ -0,0 +1,165 @@
1
+ import { MonitoringApiError } from '../core/errors.js'
2
+ import type { RequestOptions } from '../core/http.js'
3
+ import { paginate } from '../core/pagination.js'
4
+ import type { Scope } from '../core/scope.js'
5
+ import type {
6
+ AddAddressesResult,
7
+ Address,
8
+ AddressInput,
9
+ AddressPage,
10
+ AddressRef,
11
+ AddressUpdate,
12
+ AssetSelection,
13
+ Direction,
14
+ RemoveAddressesResult,
15
+ UpdateAddressesResult,
16
+ } from '../generated/types.js'
17
+
18
+ /** Maximum number of addresses the API accepts per request. Larger lists are split into batches automatically. */
19
+ export const ADDRESS_BATCH_SIZE = 1000
20
+
21
+ /**
22
+ * Default subscription for every address in a request that does not set its own. Without it, an address is notified
23
+ * about all assets of its network in both directions.
24
+ */
25
+ export interface SubscriptionDefaults {
26
+ /** Asset symbols (`USDT`) or contract addresses. `null` — all assets of the network, including ones added later. */
27
+ assets?: AssetSelection
28
+ /** `in` — incoming only, `out` — outgoing only, `both` — either. */
29
+ direction?: Direction
30
+ }
31
+
32
+ /** Parameters of {@link AddressesResource.list}. */
33
+ export interface ListAddressesParams {
34
+ /** Only addresses on this network. */
35
+ network?: string
36
+ /** Page size, up to 5000. Defaults to 500. */
37
+ limit?: number
38
+ /** Cursor: `next` of the previous page. */
39
+ after?: number
40
+ }
41
+
42
+ /** Addresses you monitor and their subscriptions: which assets and which direction you are notified about. */
43
+ export class AddressesResource {
44
+ readonly #scope: Scope
45
+
46
+ /** @internal */
47
+ constructor(scope: Scope) {
48
+ this.#scope = scope
49
+ }
50
+
51
+ /**
52
+ * Lists monitored addresses, one page at a time.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * const { items, next } = await monitoring.addresses.list({ network: 'tron' })
57
+ * ```
58
+ */
59
+ async list(params: ListAddressesParams = {}, options?: RequestOptions): Promise<AddressPage> {
60
+ return this.#scope.http.request({ method: 'GET', path: `${await this.#scope.clientPath()}/addresses`, query: { ...params }, idempotent: true, options })
61
+ }
62
+
63
+ /**
64
+ * Iterates over all monitored addresses, fetching pages as needed.
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * for await (const address of monitoring.addresses.iterate({ network: 'tron' })) {
69
+ * console.log(address.address, address.assets ?? 'all assets', address.direction)
70
+ * }
71
+ * ```
72
+ */
73
+ iterate(params: Omit<ListAddressesParams, 'after'> = {}, options?: RequestOptions): AsyncGenerator<Address, void, undefined> {
74
+ return paginate<Address>((after) => this.list({ ...params, after }, options))
75
+ }
76
+
77
+ /**
78
+ * Starts monitoring addresses. New addresses are picked up within seconds. Addresses that are already monitored are
79
+ * left unchanged — use {@link AddressesResource.update} to change their subscription.
80
+ *
81
+ * Each batch of up to {@link ADDRESS_BATCH_SIZE} addresses is validated as a whole: if any item is invalid, the
82
+ * batch is not applied. Larger lists are sent in batches, in order; if a batch fails, the previous batches have
83
+ * already been applied, and the indexes in `error.details` refer to your original list. Retrying is safe.
84
+ *
85
+ * @param addresses - Addresses to monitor. An EVM address is monitored per network: add it once per network.
86
+ * @param defaults - Subscription for addresses that do not set their own.
87
+ * @throws {@link MonitoringApiError} `400` with `details` when an address is invalid for its network or an asset
88
+ * is unknown.
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * // deposit addresses: incoming USDT only
93
+ * await monitoring.addresses.add([{ network: 'tron', address: 'TA8Hg…', label: 'user-42' }], {
94
+ * assets: ['USDT'],
95
+ * direction: 'in',
96
+ * })
97
+ * ```
98
+ */
99
+ async add(addresses: AddressInput[], defaults: SubscriptionDefaults = {}, options?: RequestOptions): Promise<AddAddressesResult> {
100
+ const total: AddAddressesResult = { added: 0, alreadyWatched: 0 }
101
+ await this.#batches(addresses, async (batch, path) => {
102
+ const r = await this.#scope.http.request<AddAddressesResult>({ method: 'POST', path: `${path}/addresses`, body: { ...defaults, addresses: batch }, idempotent: true, options })
103
+ total.added += r.added
104
+ total.alreadyWatched += r.alreadyWatched
105
+ })
106
+ return total
107
+ }
108
+
109
+ /**
110
+ * Changes the subscription of monitored addresses. Only the fields you pass are changed: omit `assets` to keep the
111
+ * current assets, or pass `null` to subscribe to all assets of the network.
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * await monitoring.addresses.update([{ network: 'tron', address: 'TA8Hg…' }], { direction: 'both' })
116
+ * ```
117
+ */
118
+ async update(addresses: AddressUpdate[], defaults: SubscriptionDefaults = {}, options?: RequestOptions): Promise<UpdateAddressesResult> {
119
+ const total: UpdateAddressesResult = { updated: 0, notWatched: 0 }
120
+ await this.#batches(addresses, async (batch, path) => {
121
+ const r = await this.#scope.http.request<UpdateAddressesResult>({ method: 'POST', path: `${path}/addresses/update`, body: { ...defaults, addresses: batch }, idempotent: true, options })
122
+ total.updated += r.updated
123
+ total.notWatched += r.notWatched
124
+ })
125
+ return total
126
+ }
127
+
128
+ /**
129
+ * Stops monitoring addresses.
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * await monitoring.addresses.remove([{ network: 'tron', address: 'TA8Hg…' }])
134
+ * ```
135
+ */
136
+ async remove(addresses: AddressRef[], options?: RequestOptions): Promise<RemoveAddressesResult> {
137
+ const total: RemoveAddressesResult = { removed: 0, notWatched: 0 }
138
+ await this.#batches(addresses, async (batch, path) => {
139
+ const r = await this.#scope.http.request<RemoveAddressesResult>({ method: 'POST', path: `${path}/addresses/remove`, body: { addresses: batch }, idempotent: true, options })
140
+ total.removed += r.removed
141
+ total.notWatched += r.notWatched
142
+ })
143
+ return total
144
+ }
145
+
146
+ /** Sends items in batches, in order; maps per-item error indexes back to the original list. */
147
+ async #batches<T>(items: T[], send: (batch: T[], clientPath: string) => Promise<void>): Promise<void> {
148
+ const path = await this.#scope.clientPath()
149
+ for (let offset = 0; offset < items.length; offset += ADDRESS_BATCH_SIZE) {
150
+ try {
151
+ await send(items.slice(offset, offset + ADDRESS_BATCH_SIZE), path)
152
+ } catch (error) {
153
+ if (!(error instanceof MonitoringApiError) || offset === 0) throw error
154
+ throw new MonitoringApiError({
155
+ status: error.status,
156
+ code: error.code,
157
+ message: `${error.message.replace(/ \(HTTP \d+, [\w-]+\)$/, '')}; addresses before index ${offset} were already applied`,
158
+ details: error.details.map((d) => ({ ...d, index: d.index + offset })),
159
+ requestId: error.requestId,
160
+ body: error.body,
161
+ })
162
+ }
163
+ }
164
+ }
165
+ }
@@ -0,0 +1,56 @@
1
+ import { seg, type RequestOptions } from '../core/http.js'
2
+ import type { Scope } from '../core/scope.js'
3
+ import type { Asset, AssetList, Network, NetworkList } from '../generated/types.js'
4
+
5
+ /** Supported networks. */
6
+ export class NetworksResource {
7
+ readonly #scope: Scope
8
+
9
+ /** @internal */
10
+ constructor(scope: Scope) {
11
+ this.#scope = scope
12
+ }
13
+
14
+ /** Lists all networks. Transfers are monitored on networks with `enabled: true`. */
15
+ async list(options?: RequestOptions): Promise<Network[]> {
16
+ const r = await this.#scope.http.request<NetworkList>({ method: 'GET', path: '/v1/networks', idempotent: true, options })
17
+ return r.items
18
+ }
19
+
20
+ /**
21
+ * Retrieves a network.
22
+ *
23
+ * @param network - Network slug (`tron`, `ethereum`) or CAIP-2 ID (`eip155:1`).
24
+ */
25
+ get(network: string, options?: RequestOptions): Promise<Network> {
26
+ return this.#scope.http.request({ method: 'GET', path: `/v1/networks/${seg(network)}`, idempotent: true, options })
27
+ }
28
+ }
29
+
30
+ /** Native coins and tokens. You are notified about transfers of enabled assets of at least `minAmount`. */
31
+ export class AssetsResource {
32
+ readonly #scope: Scope
33
+
34
+ /** @internal */
35
+ constructor(scope: Scope) {
36
+ this.#scope = scope
37
+ }
38
+
39
+ /**
40
+ * Lists assets, optionally of one network.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * const usdt = (await monitoring.assets.list({ network: 'tron' })).find((asset) => asset.symbol === 'USDT')
45
+ * ```
46
+ */
47
+ async list(params: { network?: string } = {}, options?: RequestOptions): Promise<Asset[]> {
48
+ const r = await this.#scope.http.request<AssetList>({ method: 'GET', path: '/v1/assets', query: params, idempotent: true, options })
49
+ return r.items
50
+ }
51
+
52
+ /** Retrieves an asset by ID. */
53
+ get(assetId: number, options?: RequestOptions): Promise<Asset> {
54
+ return this.#scope.http.request({ method: 'GET', path: `/v1/assets/${seg(assetId)}`, idempotent: true, options })
55
+ }
56
+ }