@txnod/sdk 1.0.1
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.
- package/AGENTS.md +29 -0
- package/CHANGELOG.md +22 -0
- package/LICENSE +21 -0
- package/README.md +434 -0
- package/dist/_shared/index.d.ts +68 -0
- package/dist/client-sandbox.d.ts +396 -0
- package/dist/client-sandbox.d.ts.map +1 -0
- package/dist/client-sandbox.js +448 -0
- package/dist/client-sandbox.js.map +1 -0
- package/dist/client.d.ts +429 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +588 -0
- package/dist/client.js.map +1 -0
- package/dist/env.d.ts +29 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +44 -0
- package/dist/env.js.map +1 -0
- package/dist/errors.d.ts +1887 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +2107 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/internals/error-ctor-map.d.ts +11 -0
- package/dist/internals/error-ctor-map.d.ts.map +1 -0
- package/dist/internals/error-ctor-map.js +75 -0
- package/dist/internals/error-ctor-map.js.map +1 -0
- package/dist/internals/fetch-with-retry.d.ts +34 -0
- package/dist/internals/fetch-with-retry.d.ts.map +1 -0
- package/dist/internals/fetch-with-retry.js +233 -0
- package/dist/internals/fetch-with-retry.js.map +1 -0
- package/dist/internals/hmac.d.ts +2 -0
- package/dist/internals/hmac.d.ts.map +1 -0
- package/dist/internals/hmac.js +10 -0
- package/dist/internals/hmac.js.map +1 -0
- package/dist/internals/logger.d.ts +9 -0
- package/dist/internals/logger.d.ts.map +1 -0
- package/dist/internals/logger.js +16 -0
- package/dist/internals/logger.js.map +1 -0
- package/dist/internals/parse-problem-details.d.ts +3 -0
- package/dist/internals/parse-problem-details.d.ts.map +1 -0
- package/dist/internals/parse-problem-details.js +76 -0
- package/dist/internals/parse-problem-details.js.map +1 -0
- package/dist/internals/synthetic-details.d.ts +12 -0
- package/dist/internals/synthetic-details.d.ts.map +1 -0
- package/dist/internals/synthetic-details.js +19 -0
- package/dist/internals/synthetic-details.js.map +1 -0
- package/dist/verify/chains/bsc.d.ts +17 -0
- package/dist/verify/chains/bsc.d.ts.map +1 -0
- package/dist/verify/chains/bsc.js +15 -0
- package/dist/verify/chains/bsc.js.map +1 -0
- package/dist/verify/chains/btc.d.ts +22 -0
- package/dist/verify/chains/btc.d.ts.map +1 -0
- package/dist/verify/chains/btc.js +55 -0
- package/dist/verify/chains/btc.js.map +1 -0
- package/dist/verify/chains/cardano.d.ts +73 -0
- package/dist/verify/chains/cardano.d.ts.map +1 -0
- package/dist/verify/chains/cardano.js +175 -0
- package/dist/verify/chains/cardano.js.map +1 -0
- package/dist/verify/chains/evm.d.ts +21 -0
- package/dist/verify/chains/evm.d.ts.map +1 -0
- package/dist/verify/chains/evm.js +46 -0
- package/dist/verify/chains/evm.js.map +1 -0
- package/dist/verify/chains/polygon.d.ts +17 -0
- package/dist/verify/chains/polygon.d.ts.map +1 -0
- package/dist/verify/chains/polygon.js +15 -0
- package/dist/verify/chains/polygon.js.map +1 -0
- package/dist/verify/chains/secp256k1-bip32.d.ts +20 -0
- package/dist/verify/chains/secp256k1-bip32.d.ts.map +1 -0
- package/dist/verify/chains/secp256k1-bip32.js +88 -0
- package/dist/verify/chains/secp256k1-bip32.js.map +1 -0
- package/dist/verify/chains/ton-cell.d.ts +179 -0
- package/dist/verify/chains/ton-cell.d.ts.map +1 -0
- package/dist/verify/chains/ton-cell.js +614 -0
- package/dist/verify/chains/ton-cell.js.map +1 -0
- package/dist/verify/chains/ton.d.ts +84 -0
- package/dist/verify/chains/ton.d.ts.map +1 -0
- package/dist/verify/chains/ton.js +131 -0
- package/dist/verify/chains/ton.js.map +1 -0
- package/dist/verify/chains/tron.d.ts +21 -0
- package/dist/verify/chains/tron.d.ts.map +1 -0
- package/dist/verify/chains/tron.js +42 -0
- package/dist/verify/chains/tron.js.map +1 -0
- package/dist/verify/config.d.ts +41 -0
- package/dist/verify/config.d.ts.map +1 -0
- package/dist/verify/config.js +120 -0
- package/dist/verify/config.js.map +1 -0
- package/dist/verify/errors.d.ts +56 -0
- package/dist/verify/errors.d.ts.map +1 -0
- package/dist/verify/errors.js +58 -0
- package/dist/verify/errors.js.map +1 -0
- package/dist/verify/index.d.ts +119 -0
- package/dist/verify/index.d.ts.map +1 -0
- package/dist/verify/index.js +166 -0
- package/dist/verify/index.js.map +1 -0
- package/dist/verify/xpub-safety.d.ts +33 -0
- package/dist/verify/xpub-safety.d.ts.map +1 -0
- package/dist/verify/xpub-safety.js +54 -0
- package/dist/verify/xpub-safety.js.map +1 -0
- package/dist/verify-webhook-signature.d.ts +30 -0
- package/dist/verify-webhook-signature.d.ts.map +1 -0
- package/dist/verify-webhook-signature.js +84 -0
- package/dist/verify-webhook-signature.js.map +1 -0
- package/docs/00-getting-started.md +135 -0
- package/docs/01-authentication.md +114 -0
- package/docs/02-invoices.md +216 -0
- package/docs/03-rates-and-quotes.md +82 -0
- package/docs/04-webhooks.md +126 -0
- package/docs/05-errors.md +199 -0
- package/docs/05-sandbox.md +159 -0
- package/docs/06-idempotency.md +132 -0
- package/docs/examples/express-webhook-receiver.md +97 -0
- package/docs/examples/nextjs-route-handler.md +206 -0
- package/docs/examples/sandbox-vitest-suite.md +263 -0
- package/docs/index.md +66 -0
- package/docs/reference/client.md +392 -0
- package/docs/reference/errors.md +161 -0
- package/docs/reference/types.md +400 -0
- package/package.json +53 -0
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin HTTP-wrapper class for the 14 sandbox-mode endpoints introduced by
|
|
3
|
+
* Story 37.2. Constructed lazily by `TxnodClient.sandbox` so unused sandbox
|
|
4
|
+
* code is dead-code-eliminated by the bundler. Methods sign requests with the
|
|
5
|
+
* underlying HMAC scheme, parse RFC 7807 errors into typed sandbox-* error
|
|
6
|
+
* classes, and return JSON-decoded result envelopes.
|
|
7
|
+
*
|
|
8
|
+
* **Do not instantiate this class directly.** Always go through
|
|
9
|
+
* `client.sandbox` so the client's HMAC + retry + telemetry pipeline is
|
|
10
|
+
* preserved.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
15
|
+
*
|
|
16
|
+
* const client = new TxnodClient({
|
|
17
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
18
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
19
|
+
* environment: 'non-production',
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Lazy access — TxnodClientSandbox is constructed on first use.
|
|
23
|
+
* const result = await client.sandbox.simulatePaid(
|
|
24
|
+
* '01HK8MAR2QEXAMPLE000000000',
|
|
25
|
+
* );
|
|
26
|
+
* console.log(result.event_id, result.status);
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export class TxnodClientSandbox {
|
|
30
|
+
#request;
|
|
31
|
+
constructor(request) {
|
|
32
|
+
this.#request = request;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* `POST /api/v1/sandbox/invoices/{invoiceId}/simulate-detect` — synthesize
|
|
36
|
+
* an `invoice.detected` event (status `pending` → `detected`) and write a
|
|
37
|
+
* synthetic `invoice_transactions` row whose `confirmations=0` is the
|
|
38
|
+
* starting point for subsequent `clockAdvance` calls.
|
|
39
|
+
*
|
|
40
|
+
* Throws `TxnodSandboxInvoiceTransitionInvalidError` when the invoice is
|
|
41
|
+
* not in `pending` status, `TxnodSandboxInvoiceNotFoundError` when the
|
|
42
|
+
* invoice does not belong to the project, and `TxnodSandboxRateLimitExceededError`
|
|
43
|
+
* when the per-project rate cap is hit.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
48
|
+
*
|
|
49
|
+
* const client = new TxnodClient({
|
|
50
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
51
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
52
|
+
* environment: 'non-production',
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* const result = await client.sandbox.simulateDetect(
|
|
56
|
+
* '01HK8MAR2QEXAMPLE000000000',
|
|
57
|
+
* { seed: 'order-42' },
|
|
58
|
+
* );
|
|
59
|
+
* console.log(result.event_id, result.status);
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
simulateDetect(invoiceId, opts) {
|
|
63
|
+
return this.#request({
|
|
64
|
+
method: 'POST',
|
|
65
|
+
path: `/api/v1/sandbox/invoices/${invoiceId}/simulate-detect`,
|
|
66
|
+
body: opts?.seed !== undefined ? { seed: opts.seed } : {},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* `POST /api/v1/sandbox/invoices/{invoiceId}/simulate-paid` — finalise
|
|
71
|
+
* a `detected` invoice into `paid` and emit `invoice.paid`.
|
|
72
|
+
*
|
|
73
|
+
* Throws `TxnodSandboxInvoiceTransitionInvalidError` if the invoice is not
|
|
74
|
+
* in `detected` status.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
79
|
+
*
|
|
80
|
+
* const client = new TxnodClient({
|
|
81
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
82
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
83
|
+
* environment: 'non-production',
|
|
84
|
+
* });
|
|
85
|
+
*
|
|
86
|
+
* await client.sandbox.simulateDetect('01HK8MAR2QEXAMPLE000000000');
|
|
87
|
+
* const paid = await client.sandbox.simulatePaid(
|
|
88
|
+
* '01HK8MAR2QEXAMPLE000000000',
|
|
89
|
+
* );
|
|
90
|
+
* console.log(paid.status);
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
simulatePaid(invoiceId, opts) {
|
|
94
|
+
return this.#request({
|
|
95
|
+
method: 'POST',
|
|
96
|
+
path: `/api/v1/sandbox/invoices/${invoiceId}/simulate-paid`,
|
|
97
|
+
body: opts?.seed !== undefined ? { seed: opts.seed } : {},
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* `POST /api/v1/sandbox/invoices/{invoiceId}/simulate-overpaid` — finalise
|
|
102
|
+
* a `detected` invoice into `overpaid` with an overpayment (>amount_crypto)
|
|
103
|
+
* and emit `invoice.overpaid`. Provide either `multiplier` (× the configured
|
|
104
|
+
* amount) or `extraUnits` (added on top of the configured amount).
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```ts
|
|
108
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
109
|
+
*
|
|
110
|
+
* const client = new TxnodClient({
|
|
111
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
112
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
113
|
+
* environment: 'non-production',
|
|
114
|
+
* });
|
|
115
|
+
*
|
|
116
|
+
* await client.sandbox.simulateDetect('01HK8MAR2QEXAMPLE000000000');
|
|
117
|
+
* const r = await client.sandbox.simulateOverpaid(
|
|
118
|
+
* '01HK8MAR2QEXAMPLE000000000',
|
|
119
|
+
* { multiplier: 1.5 },
|
|
120
|
+
* );
|
|
121
|
+
* console.log(r.status);
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
simulateOverpaid(invoiceId, params) {
|
|
125
|
+
return this.#request({
|
|
126
|
+
method: 'POST',
|
|
127
|
+
path: `/api/v1/sandbox/invoices/${invoiceId}/simulate-overpaid`,
|
|
128
|
+
body: params,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* `POST /api/v1/sandbox/invoices/{invoiceId}/simulate-partial` — emit
|
|
133
|
+
* `invoice.partial` with a sub-amount receipt; invoice stays open. Provide
|
|
134
|
+
* either `fraction` (0 < fraction < 1) or `amountUnits` (a positive integer
|
|
135
|
+
* less than amount_crypto).
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```ts
|
|
139
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
140
|
+
*
|
|
141
|
+
* const client = new TxnodClient({
|
|
142
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
143
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
144
|
+
* environment: 'non-production',
|
|
145
|
+
* });
|
|
146
|
+
*
|
|
147
|
+
* const r = await client.sandbox.simulatePartial(
|
|
148
|
+
* '01HK8MAR2QEXAMPLE000000000',
|
|
149
|
+
* { fraction: 0.5 },
|
|
150
|
+
* );
|
|
151
|
+
* console.log(r.status);
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
simulatePartial(invoiceId, params) {
|
|
155
|
+
return this.#request({
|
|
156
|
+
method: 'POST',
|
|
157
|
+
path: `/api/v1/sandbox/invoices/${invoiceId}/simulate-partial`,
|
|
158
|
+
body: params,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* `POST /api/v1/sandbox/invoices/{invoiceId}/simulate-expire` — transition
|
|
163
|
+
* a non-paid invoice into `expired` and emit `invoice.expired`.
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```ts
|
|
167
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
168
|
+
*
|
|
169
|
+
* const client = new TxnodClient({
|
|
170
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
171
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
172
|
+
* environment: 'non-production',
|
|
173
|
+
* });
|
|
174
|
+
*
|
|
175
|
+
* const r = await client.sandbox.simulateExpire(
|
|
176
|
+
* '01HK8MAR2QEXAMPLE000000000',
|
|
177
|
+
* );
|
|
178
|
+
* console.log(r.status);
|
|
179
|
+
* ```
|
|
180
|
+
*/
|
|
181
|
+
simulateExpire(invoiceId) {
|
|
182
|
+
return this.#request({
|
|
183
|
+
method: 'POST',
|
|
184
|
+
path: `/api/v1/sandbox/invoices/${invoiceId}/simulate-expire`,
|
|
185
|
+
body: {},
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* `POST /api/v1/sandbox/invoices/{invoiceId}/simulate-late-payment` —
|
|
190
|
+
* transition an `expired` invoice to `expired_paid_late` and emit
|
|
191
|
+
* `invoice.expired_paid_late`. Optional `amountUnits` overrides the
|
|
192
|
+
* payment size; default mirrors the invoice's configured amount.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```ts
|
|
196
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
197
|
+
*
|
|
198
|
+
* const client = new TxnodClient({
|
|
199
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
200
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
201
|
+
* environment: 'non-production',
|
|
202
|
+
* });
|
|
203
|
+
*
|
|
204
|
+
* await client.sandbox.simulateExpire('01HK8MAR2QEXAMPLE000000000');
|
|
205
|
+
* const r = await client.sandbox.simulateLatePayment(
|
|
206
|
+
* '01HK8MAR2QEXAMPLE000000000',
|
|
207
|
+
* );
|
|
208
|
+
* console.log(r.status);
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
simulateLatePayment(invoiceId, params) {
|
|
212
|
+
return this.#request({
|
|
213
|
+
method: 'POST',
|
|
214
|
+
path: `/api/v1/sandbox/invoices/${invoiceId}/simulate-late-payment`,
|
|
215
|
+
body: params ?? {},
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* `POST /api/v1/sandbox/invoices/{invoiceId}/simulate-reorg` — flip a
|
|
220
|
+
* `paid`/`overpaid` invoice to `reverted` and emit `invoice.reverted`.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```ts
|
|
224
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
225
|
+
*
|
|
226
|
+
* const client = new TxnodClient({
|
|
227
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
228
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
229
|
+
* environment: 'non-production',
|
|
230
|
+
* });
|
|
231
|
+
*
|
|
232
|
+
* const r = await client.sandbox.simulateReorg(
|
|
233
|
+
* '01HK8MAR2QEXAMPLE000000000',
|
|
234
|
+
* );
|
|
235
|
+
* console.log(r.status);
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
simulateReorg(invoiceId) {
|
|
239
|
+
return this.#request({
|
|
240
|
+
method: 'POST',
|
|
241
|
+
path: `/api/v1/sandbox/invoices/${invoiceId}/simulate-reorg`,
|
|
242
|
+
body: {},
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* `POST /api/v1/sandbox/invoices/{invoiceId}/simulate-reconfirm` — flip a
|
|
247
|
+
* `reverted` invoice back to `paid` and emit a re-confirmation
|
|
248
|
+
* `invoice.paid` (with a fresh `event_id` per spec).
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* ```ts
|
|
252
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
253
|
+
*
|
|
254
|
+
* const client = new TxnodClient({
|
|
255
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
256
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
257
|
+
* environment: 'non-production',
|
|
258
|
+
* });
|
|
259
|
+
*
|
|
260
|
+
* const r = await client.sandbox.simulateReconfirm(
|
|
261
|
+
* '01HK8MAR2QEXAMPLE000000000',
|
|
262
|
+
* );
|
|
263
|
+
* console.log(r.status);
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
simulateReconfirm(invoiceId) {
|
|
267
|
+
return this.#request({
|
|
268
|
+
method: 'POST',
|
|
269
|
+
path: `/api/v1/sandbox/invoices/${invoiceId}/simulate-reconfirm`,
|
|
270
|
+
body: {},
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* `POST /api/v1/sandbox/invoices/{invoiceId}/simulate-duplicate-delivery` —
|
|
275
|
+
* re-emit the most recent webhook event for the invoice with the same
|
|
276
|
+
* `event_id`, exercising the integrator's idempotency layer.
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* ```ts
|
|
280
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
281
|
+
*
|
|
282
|
+
* const client = new TxnodClient({
|
|
283
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
284
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
285
|
+
* environment: 'non-production',
|
|
286
|
+
* });
|
|
287
|
+
*
|
|
288
|
+
* const r = await client.sandbox.simulateDuplicateDelivery(
|
|
289
|
+
* '01HK8MAR2QEXAMPLE000000000',
|
|
290
|
+
* );
|
|
291
|
+
* console.log(r.status);
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
simulateDuplicateDelivery(invoiceId) {
|
|
295
|
+
return this.#request({
|
|
296
|
+
method: 'POST',
|
|
297
|
+
path: `/api/v1/sandbox/invoices/${invoiceId}/simulate-duplicate-delivery`,
|
|
298
|
+
body: {},
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* `POST /api/v1/sandbox/invoices/{invoiceId}/simulate-event` — emit any
|
|
303
|
+
* webhook event with caller-controlled fields. Use for negative testing
|
|
304
|
+
* (unexpected `event_type` for the current invoice status, custom
|
|
305
|
+
* `confirmations`, custom `block_height`, custom chain-specific payload).
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* ```ts
|
|
309
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
310
|
+
*
|
|
311
|
+
* const client = new TxnodClient({
|
|
312
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
313
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
314
|
+
* environment: 'non-production',
|
|
315
|
+
* });
|
|
316
|
+
*
|
|
317
|
+
* const r = await client.sandbox.simulateEvent(
|
|
318
|
+
* '01HK8MAR2QEXAMPLE000000000',
|
|
319
|
+
* {
|
|
320
|
+
* eventType: 'invoice.partial',
|
|
321
|
+
* amountUnits: '1000',
|
|
322
|
+
* confirmations: 1,
|
|
323
|
+
* blockHeight: 100,
|
|
324
|
+
* expectedCurrentStatus: 'detected',
|
|
325
|
+
* },
|
|
326
|
+
* );
|
|
327
|
+
* console.log(r.status);
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
simulateEvent(invoiceId, eventInput) {
|
|
331
|
+
return this.#request({
|
|
332
|
+
method: 'POST',
|
|
333
|
+
path: `/api/v1/sandbox/invoices/${invoiceId}/simulate-event`,
|
|
334
|
+
body: eventInput,
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* `POST /api/v1/sandbox/{projectId}/clock/advance` — bump the
|
|
339
|
+
* `confirmations` counter on every `detected` invoice for the given chain
|
|
340
|
+
* and finalise any whose `confirmations >= confirmation_threshold`. Throws
|
|
341
|
+
* `TxnodSandboxRateLimitExceededError` (10/min/project per spec §6.1).
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* ```ts
|
|
345
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
346
|
+
*
|
|
347
|
+
* const client = new TxnodClient({
|
|
348
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
349
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
350
|
+
* environment: 'non-production',
|
|
351
|
+
* });
|
|
352
|
+
*
|
|
353
|
+
* const r = await client.sandbox.clockAdvance(
|
|
354
|
+
* '01HK8MAR2QEXAMPLEPROJECT000',
|
|
355
|
+
* { chain: 'btc', blocks: 6 },
|
|
356
|
+
* );
|
|
357
|
+
* console.log('finalized', r.advanced, 'remaining', r.remaining);
|
|
358
|
+
* ```
|
|
359
|
+
*/
|
|
360
|
+
clockAdvance(projectId, params) {
|
|
361
|
+
return this.#request({
|
|
362
|
+
method: 'POST',
|
|
363
|
+
path: `/api/v1/sandbox/${projectId}/clock/advance`,
|
|
364
|
+
body: params,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* `POST /api/v1/sandbox/{projectId}/reset` — soft-purge the data tail of
|
|
369
|
+
* a sandbox project (invoices, transactions, outbox events, address pool)
|
|
370
|
+
* while preserving the project shell + xpubs + bindings + sandbox PAT +
|
|
371
|
+
* api_keys. Throws `TxnodSandboxResetFailedError` on internal failure.
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```ts
|
|
375
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
376
|
+
*
|
|
377
|
+
* const client = new TxnodClient({
|
|
378
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
379
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
380
|
+
* environment: 'non-production',
|
|
381
|
+
* });
|
|
382
|
+
*
|
|
383
|
+
* await client.sandbox.reset('01HK8MAR2QEXAMPLEPROJECT000');
|
|
384
|
+
* console.log('sandbox project reset');
|
|
385
|
+
* ```
|
|
386
|
+
*/
|
|
387
|
+
reset(projectId) {
|
|
388
|
+
return this.#request({
|
|
389
|
+
method: 'POST',
|
|
390
|
+
path: `/api/v1/sandbox/${projectId}/reset`,
|
|
391
|
+
body: {},
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* `DELETE /api/v1/sandbox/{projectId}` — full-delete the sandbox project
|
|
396
|
+
* (per F-20: dashboard owns the create flow, SDK + MCP own destructive
|
|
397
|
+
* lifecycle). Throws `TxnodSandboxDeleteFailedError` on internal failure.
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* ```ts
|
|
401
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
402
|
+
*
|
|
403
|
+
* const client = new TxnodClient({
|
|
404
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
405
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
406
|
+
* environment: 'non-production',
|
|
407
|
+
* });
|
|
408
|
+
*
|
|
409
|
+
* await client.sandbox.destroy('01HK8MAR2QEXAMPLEPROJECT000');
|
|
410
|
+
* console.log('sandbox project deleted');
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
413
|
+
destroy(projectId) {
|
|
414
|
+
return this.#request({
|
|
415
|
+
method: 'DELETE',
|
|
416
|
+
path: `/api/v1/sandbox/${projectId}`,
|
|
417
|
+
body: {},
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* `GET /api/v1/sandbox/{projectId}/wallets` — list the per-chain xpubs +
|
|
422
|
+
* derivation paths the sandbox project routes against. Useful for
|
|
423
|
+
* integrators wiring the sandbox into a derivation-aware test harness.
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```ts
|
|
427
|
+
* import { TxnodClient } from '@txnod/sdk';
|
|
428
|
+
*
|
|
429
|
+
* const client = new TxnodClient({
|
|
430
|
+
* projectId: process.env.TXNOD_PROJECT_ID!,
|
|
431
|
+
* apiSecret: process.env.TXNOD_API_SECRET!,
|
|
432
|
+
* environment: 'non-production',
|
|
433
|
+
* });
|
|
434
|
+
*
|
|
435
|
+
* const wallets = await client.sandbox.listWallets(
|
|
436
|
+
* '01HK8MAR2QEXAMPLEPROJECT000',
|
|
437
|
+
* );
|
|
438
|
+
* for (const w of wallets.items) console.log(w.chain, w.derivation_path);
|
|
439
|
+
* ```
|
|
440
|
+
*/
|
|
441
|
+
listWallets(projectId) {
|
|
442
|
+
return this.#request({
|
|
443
|
+
method: 'GET',
|
|
444
|
+
path: `/api/v1/sandbox/${projectId}/wallets`,
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
//# sourceMappingURL=client-sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-sandbox.js","sourceRoot":"","sources":["../src/client-sandbox.ts"],"names":[],"mappings":"AAwCA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,OAAO,kBAAkB;IACpB,QAAQ,CAAY;IAE7B,YAAY,OAAkB;QAC5B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,cAAc,CACZ,SAAiB,EACjB,IAAwB;QAExB,OAAO,IAAI,CAAC,QAAQ,CAAwB;YAC1C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,4BAA4B,SAAS,kBAAkB;YAC7D,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;SAC1D,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,YAAY,CACV,SAAiB,EACjB,IAAwB;QAExB,OAAO,IAAI,CAAC,QAAQ,CAAwB;YAC1C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,4BAA4B,SAAS,gBAAgB;YAC3D,IAAI,EAAE,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;SAC1D,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,gBAAgB,CACd,SAAiB,EACjB,MAAwB;QAExB,OAAO,IAAI,CAAC,QAAQ,CAAwB;YAC1C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,4BAA4B,SAAS,oBAAoB;YAC/D,IAAI,EAAE,MAAM;SACb,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,eAAe,CACb,SAAiB,EACjB,MAAuB;QAEvB,OAAO,IAAI,CAAC,QAAQ,CAAwB;YAC1C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,4BAA4B,SAAS,mBAAmB;YAC9D,IAAI,EAAE,MAAM;SACb,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,cAAc,CAAC,SAAiB;QAC9B,OAAO,IAAI,CAAC,QAAQ,CAAwB;YAC1C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,4BAA4B,SAAS,kBAAkB;YAC7D,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,mBAAmB,CACjB,SAAiB,EACjB,MAA4B;QAE5B,OAAO,IAAI,CAAC,QAAQ,CAAwB;YAC1C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,4BAA4B,SAAS,wBAAwB;YACnE,IAAI,EAAE,MAAM,IAAI,EAAE;SACnB,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,aAAa,CAAC,SAAiB;QAC7B,OAAO,IAAI,CAAC,QAAQ,CAAwB;YAC1C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,4BAA4B,SAAS,iBAAiB;YAC5D,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,iBAAiB,CAAC,SAAiB;QACjC,OAAO,IAAI,CAAC,QAAQ,CAAwB;YAC1C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,4BAA4B,SAAS,qBAAqB;YAChE,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,yBAAyB,CACvB,SAAiB;QAEjB,OAAO,IAAI,CAAC,QAAQ,CAAwB;YAC1C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,4BAA4B,SAAS,8BAA8B;YACzE,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,aAAa,CACX,SAAiB,EACjB,UAAyB;QAEzB,OAAO,IAAI,CAAC,QAAQ,CAAwB;YAC1C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,4BAA4B,SAAS,iBAAiB;YAC5D,IAAI,EAAE,UAAU;SACjB,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,YAAY,CACV,SAAiB,EACjB,MAAoB;QAEpB,OAAO,IAAI,CAAC,QAAQ,CAA4B;YAC9C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,mBAAmB,SAAS,gBAAgB;YAClD,IAAI,EAAE,MAAM;SACb,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,KAAK,CAAC,SAAiB;QACrB,OAAO,IAAI,CAAC,QAAQ,CAAyB;YAC3C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,mBAAmB,SAAS,QAAQ;YAC1C,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,SAAiB;QACvB,OAAO,IAAI,CAAC,QAAQ,CAAyB;YAC3C,MAAM,EAAE,QAAQ;YAChB,IAAI,EAAE,mBAAmB,SAAS,EAAE;YACpC,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,WAAW,CAAC,SAAiB;QAC3B,OAAO,IAAI,CAAC,QAAQ,CAAsB;YACxC,MAAM,EAAE,KAAK;YACb,IAAI,EAAE,mBAAmB,SAAS,UAAU;SAC7C,CAAC,CAAC;IACL,CAAC;CACF"}
|