@marcohefti/request-network-api-client 0.5.1 → 0.5.6

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/README.md CHANGED
@@ -1,26 +1,33 @@
1
1
  # Request Network API Client (TypeScript)
2
2
 
3
- TypeScript client for the Request Network hosted REST API. It provides typed, ergonomic
4
- helpers for core API domains such as requests, payouts, payer/compliance, client IDs,
5
- currencies, and payments, with runtime validation and webhook utilities built in.
3
+ [![npm version](https://img.shields.io/npm/v/@marcohefti/request-network-api-client.svg)](https://www.npmjs.com/package/@marcohefti/request-network-api-client)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
5
+ [![Node.js CI](https://github.com/marcohefti/request-network-api-client-ts/actions/workflows/ci.yml/badge.svg)](https://github.com/marcohefti/request-network-api-client-ts/actions/workflows/ci.yml)
6
6
 
7
- This package targets the hosted REST API, not the protocol SDK.
7
+ TypeScript client for the Request Network hosted REST API. Provides typed, ergonomic helpers for requests, payouts, payer/compliance, client IDs, currencies, and payments, with runtime validation and webhook utilities built in.
8
8
 
9
- ## Installation
9
+ **Note**: This targets the hosted REST API, not the protocol SDK. See [SCOPE.md](docs/SCOPE.md) for when to use which.
10
10
 
11
- Install via npm or pnpm:
11
+ ## Installation
12
12
 
13
13
  ```bash
14
- # npm
15
14
  npm install @marcohefti/request-network-api-client
16
-
17
- # pnpm
15
+ # or
18
16
  pnpm add @marcohefti/request-network-api-client
17
+ # or
18
+ yarn add @marcohefti/request-network-api-client
19
19
  ```
20
20
 
21
- ## Quick start
21
+ ## Features
22
+
23
+ - **Typed API**: Full TypeScript support with types generated from OpenAPI spec
24
+ - **Runtime Validation**: Zod schemas validate requests/responses (configurable)
25
+ - **Webhook Helpers**: Signature verification, middleware, and event dispatchers
26
+ - **Error Handling**: Consistent error model with retry/backoff
27
+ - **Tree-Shakable**: Subpath exports for minimal bundle size
28
+ - **Universal**: Works in Node 20+, browsers, and edge runtimes
22
29
 
23
- Node (API key) – tested on Node 20.x–24.x with the built‑in `fetch`:
30
+ ## Quick Start
24
31
 
25
32
  ```ts
26
33
  import {
@@ -34,64 +41,225 @@ const client = createRequestClient({
34
41
  apiKey: process.env.REQUEST_API_KEY!,
35
42
  });
36
43
 
37
- async function main() {
38
- try {
39
- const tokens = await client.currencies.list({ network: 'sepolia' });
40
- console.log('Currencies:', tokens.length);
41
- } catch (err) {
42
- if (isRequestApiError(err)) {
43
- console.error('API error', err.status, err.code, err.requestId, err.toJSON());
44
- } else {
45
- console.error(err);
46
- }
44
+ // Create a request
45
+ const request = await client.requests.create({
46
+ amount: '12.5',
47
+ invoiceCurrency: 'USD',
48
+ paymentCurrency: 'USDC-sepolia',
49
+ });
50
+
51
+ // List currencies
52
+ const tokens = await client.currencies.list({ network: 'sepolia' });
53
+
54
+ // Error handling
55
+ try {
56
+ await client.payments.search({ walletAddress: '0xabc' });
57
+ } catch (err) {
58
+ if (isRequestApiError(err)) {
59
+ console.error('API error', err.status, err.code, err.requestId);
47
60
  }
48
61
  }
62
+ ```
63
+
64
+ ## Documentation
65
+
66
+ - **[Quick Start](docs/QUICK-START.md)** - Installation, environment setup, common recipes
67
+ - **[Domains](docs/DOMAINS.md)** - API reference for all domains (requests, payouts, payer, payments, currencies, client IDs)
68
+ - **[HTTP & Errors](docs/HTTP-AND-ERRORS.md)** - HTTP client configuration, error handling, retry behavior
69
+ - **[Webhooks](docs/WEBHOOKS.md)** - Signature verification, middleware, event handlers, local dev setup
70
+ - **[Scope](docs/SCOPE.md)** - When to use this client vs the protocol SDK
71
+ - **[Architecture](docs/ARCHITECTURE.md)** - System design and internals
72
+ - **[Testing](docs/TESTING.md)** - Test strategy, commands, and coverage
73
+ - **[Publishing](docs/PUBLISHING.md)** - Release checklist
74
+ - **[Endpoints](docs/ENDPOINTS.md)** - API endpoint reference
75
+
76
+ ## Compatibility
77
+
78
+ | Runtime | Versions |
79
+ |---------|----------|
80
+ | Node.js | 20.x, 22.x, 24.x |
81
+ | Browsers | Modern browsers with Fetch API |
82
+ | Edge Runtimes | Cloudflare Workers, Vercel Edge, Deno, Bun |
83
+
84
+ **Package Manager**: pnpm 10.17.1 recommended (`corepack enable pnpm@10.17.1`)
85
+
86
+ ## Versioning
87
+
88
+ This package follows SemVer. While on `0.x`, minor/patch releases may include breaking changes as the API surface stabilizes. Once `1.0.0` is reached, breaking changes will require a major version bump.
49
89
 
50
- main();
90
+ See [CHANGELOG.md](CHANGELOG.md) for release history.
91
+
92
+ ## Troubleshooting
93
+
94
+ ### Common Issues
95
+
96
+ #### API Key Problems
97
+
98
+ **Error: 401 Unauthorized**
99
+ - Ensure `REQUEST_API_KEY` is set correctly in your environment
100
+ - Verify your API key is active in the Request API Portal
101
+ - Test with a simple call: `await client.currencies.list({ network: 'sepolia' })`
102
+ - Check for extra whitespace or quotes in your environment variable
103
+
104
+ ```bash
105
+ # Verify your API key is set
106
+ echo $REQUEST_API_KEY
107
+
108
+ # Test with a simple command
109
+ node -e "import('@marcohefti/request-network-api-client').then(m => m.createRequestClient({apiKey: process.env.REQUEST_API_KEY}).currencies.list()).then(console.log)"
51
110
  ```
52
111
 
53
- From env:
112
+ #### CORS Errors (Browser)
54
113
 
55
- ```ts
56
- import { createRequestClientFromEnv } from '@marcohefti/request-network-api-client';
114
+ **Error: CORS policy blocks request**
115
+ - Ensure you're using a Client ID, not an API key (API keys are server-only)
116
+ - Verify your domain is in the `allowedDomains` list for your Client ID
117
+ - Check the domain matches exactly (including protocol and port)
118
+ - For localhost development, use `http://localhost:3000` format
57
119
 
58
- const client = createRequestClientFromEnv();
59
- // Reads REQUEST_API_URL, REQUEST_API_KEY, REQUEST_CLIENT_ID (with legacy REQUEST_SDK_* fallbacks)
120
+ ```typescript
121
+ // Wrong - Using API key in browser
122
+ const client = createRequestClient({
123
+ apiKey: 'rk_live_...' // This will fail with CORS
124
+ });
125
+
126
+ // ✅ Correct - Using Client ID in browser
127
+ const client = createRequestClient({
128
+ clientId: 'client_live_...'
129
+ });
60
130
  ```
61
131
 
62
- ## What this client covers
132
+ #### Module Not Found Errors
63
133
 
64
- - REST v2 domains: requests, payouts, payer/compliance, payments, client IDs, currencies.
65
- - Legacy v1 routes where needed (via `client.<domain>.legacy` or versioned barrels).
66
- - Webhook helpers: signature verification, parser, dispatcher, and testing utilities.
67
- - Runtime validation via Zod schemas generated from the Request OpenAPI spec.
134
+ **Error: Cannot find module '@marcohefti/request-network-api-client'**
135
+ - Run `pnpm install` or `npm install`
136
+ - Clear node_modules and reinstall: `rm -rf node_modules && pnpm install`
137
+ - Check package.json includes the dependency
138
+ - For local development, run `pnpm build` in the package directory
68
139
 
69
- For deeper details (HTTP client options, domain facades, webhooks, error model), see:
140
+ **Error: Cannot find module '@marcohefti/request-network-api-client/requests'**
141
+ - Ensure you're using the correct import path
142
+ - Check package.json `exports` field matches your import
143
+ - Update to the latest version: `pnpm update @marcohefti/request-network-api-client`
70
144
 
71
- - Architecture: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
72
- - Endpoints & behaviour notes: [`docs/ENDPOINTS.md`](docs/ENDPOINTS.md)
73
- - Testing & live suites: [`docs/TESTING.md`](docs/TESTING.md)
74
- - Publishing checklist: [`docs/PUBLISHING.md`](docs/PUBLISHING.md)
75
- - Docs site (VitePress): `docs-site/` (see `pnpm docs:dev` and `pnpm docs:build`)
145
+ #### Type Errors
76
146
 
77
- ## Compatibility
147
+ **Error: Property does not exist on type**
148
+ - Ensure you're using the latest version of the client
149
+ - Run `pnpm update @marcohefti/request-network-api-client`
150
+ - Check your TypeScript version is >= 5.0
151
+ - Clear TypeScript cache: `rm -rf node_modules/.cache`
152
+
153
+ #### Runtime Validation Errors
78
154
 
79
- - Node.js: 20 / 22 / 24
80
- - Package manager: pnpm 10.17.1 (recommended via `corepack enable pnpm@10.17.1`)
155
+ **Error: ValidationError - Response validation failed**
156
+ - The API response didn't match the expected schema
157
+ - This usually means the API has changed or there's a bug
158
+ - Update to the latest client version: `pnpm update @marcohefti/request-network-api-client`
159
+ - Temporarily disable validation to debug: `runtimeValidation: false`
160
+ - Report the issue with the full error message
81
161
 
82
- ## Versioning & support
162
+ ```typescript
163
+ // Debug validation errors
164
+ const client = createRequestClient({
165
+ apiKey: process.env.REQUEST_API_KEY,
166
+ runtimeValidation: false, // Temporarily disable
167
+ });
168
+ ```
169
+
170
+ #### Timeout Issues
171
+
172
+ **Error: Request timeout / AbortError**
173
+ - Increase timeout for slow operations: `{ timeoutMs: 30_000 }`
174
+ - Check your network connection
175
+ - Verify the API is accessible: `curl https://api.request.network/v2/currencies`
176
+ - Try with a different network/endpoint
177
+
178
+ ```typescript
179
+ // Increase timeout for slow endpoints
180
+ await client.requests.create(
181
+ { /* ... */ },
182
+ { timeoutMs: 30_000 } // 30 seconds
183
+ );
184
+ ```
185
+
186
+ #### Rate Limiting (429)
187
+
188
+ **Error: Rate limit exceeded**
189
+ - The client auto-retries with exponential backoff
190
+ - Check `err.retryAfterMs` for when to retry
191
+ - Reduce request frequency in your application
192
+ - Consider caching responses for repeated queries
193
+
194
+ ```typescript
195
+ try {
196
+ await client.currencies.list();
197
+ } catch (err) {
198
+ if (isRequestApiError(err) && err.status === 429) {
199
+ console.log(`Rate limited. Retry after ${err.retryAfterMs}ms`);
200
+ // Client will automatically retry
201
+ }
202
+ }
203
+ ```
204
+
205
+ #### Network/Connection Errors
206
+
207
+ **Error: fetch failed / ECONNREFUSED**
208
+ - Check your internet connection
209
+ - Verify API endpoint is accessible
210
+ - Check for proxy/firewall blocking requests
211
+ - Try setting a custom base URL: `baseUrl: 'https://api.request.network'`
212
+
213
+ ### Getting Help
83
214
 
84
- - Versioning: this package follows SemVer, but while the major version is `0.x`, minor and patch releases may include breaking changes as the surface stabilises.
85
- - Support & issues: report bugs or request features via GitHub issues on [`marcohefti/request-network-api-client-ts`](https://github.com/marcohefti/request-network-api-client-ts).
215
+ If you're still stuck:
216
+
217
+ 1. Check the [examples](examples/) directory for working code
218
+ 2. Review [HTTP-AND-ERRORS.md](docs/HTTP-AND-ERRORS.md) for detailed error handling
219
+ 3. Search [existing issues](https://github.com/marcohefti/request-network-api-client-ts/issues)
220
+ 4. Create a new issue with:
221
+ - Client version (`@marcohefti/request-network-api-client@x.x.x`)
222
+ - Node.js version (`node --version`)
223
+ - Minimal code sample that reproduces the issue
224
+ - Full error message and stack trace
225
+ - Request ID from error (if available)
226
+
227
+ ## Support & Security
228
+
229
+ - **Issues**: Report bugs or request features via [GitHub Issues](https://github.com/marcohefti/request-network-api-client-ts/issues)
230
+ - **Security**: See [SECURITY.md](SECURITY.md) for disclosure policy
231
+ - **Contributing**: See [CONTRIBUTING.md](CONTRIBUTING.md) for development guidelines
86
232
 
87
233
  ## Development
88
234
 
89
- Common commands:
235
+ **Prerequisites**: Node 20/22/24, pnpm 10.17.1
236
+
237
+ ```bash
238
+ # Install dependencies
239
+ pnpm install
240
+
241
+ # Type-check
242
+ pnpm typecheck
243
+
244
+ # Lint
245
+ pnpm lint
246
+
247
+ # Run tests
248
+ pnpm test
249
+
250
+ # Build
251
+ pnpm build
252
+ ```
253
+
254
+ **Full validation** (before submitting PRs):
255
+
256
+ ```bash
257
+ pnpm coverage:matrix # Node 20/22/24 coverage matrix
258
+ pnpm build # Verify packaging
259
+ ```
260
+
261
+ See [TESTING.md](docs/TESTING.md) for test strategy and [CONTRIBUTING.md](CONTRIBUTING.md) for coding guidelines.
90
262
 
91
- - `pnpm lint` – lint the source and tests.
92
- - `pnpm typecheck` – run TypeScript diagnostics (`tsc`).
93
- - `pnpm test` – run the Vitest suite (MSW + OpenAPI parity guards).
94
- - `pnpm build` – build CJS/ESM + types into `dist/`.
263
+ ## License
95
264
 
96
- See [`docs/TESTING.md`](docs/TESTING.md) for the full test/coverage matrix and live integration setup, and
97
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the HTTP pipeline and domain layout.
265
+ MIT - See [LICENSE](LICENSE) for details.
package/dist/cjs/index.js CHANGED
@@ -2310,13 +2310,6 @@ function createRequestClient(options) {
2310
2310
  pay: createPayApi(http)
2311
2311
  };
2312
2312
  }
2313
- function createRequestClientFromEnv(options) {
2314
- const env = options?.env ?? process.env;
2315
- const baseUrl = env.REQUEST_API_URL ?? env.REQUEST_SDK_BASE_URL;
2316
- const apiKey = env.REQUEST_API_KEY ?? env.REQUEST_SDK_API_KEY;
2317
- const clientId = env.REQUEST_CLIENT_ID ?? env.REQUEST_SDK_CLIENT_ID;
2318
- return createRequestClient({ baseUrl, apiKey, clientId });
2319
- }
2320
2313
 
2321
2314
  // src/core/config/request-environment.config.ts
2322
2315
  var RequestEnvironment = {
@@ -3385,8 +3378,8 @@ function isAgreementRejected(payload) {
3385
3378
  }
3386
3379
  function complianceStatusSummary(payload) {
3387
3380
  const parts = [];
3388
- const kyc = payload.kycStatus ? String(payload.kycStatus).replace(/_/g, " ") : "unknown";
3389
- const agreement = payload.agreementStatus ? String(payload.agreementStatus).replace(/_/g, " ") : "unknown";
3381
+ const kyc = payload.kycStatus ? payload.kycStatus.replace(/_/g, " ") : "unknown";
3382
+ const agreement = payload.agreementStatus ? payload.agreementStatus.replace(/_/g, " ") : "unknown";
3390
3383
  parts.push(`KYC: ${kyc}`);
3391
3384
  parts.push(`Agreement: ${agreement}`);
3392
3385
  if (payload.clientUserId) {
@@ -3443,7 +3436,6 @@ exports.clientIds = client_ids_exports;
3443
3436
  exports.computeRetryDelay = computeRetryDelay;
3444
3437
  exports.createHttpClient = createHttpClient;
3445
3438
  exports.createRequestClient = createRequestClient;
3446
- exports.createRequestClientFromEnv = createRequestClientFromEnv;
3447
3439
  exports.currencies = currencies_exports;
3448
3440
  exports.currenciesV1 = v1_exports;
3449
3441
  exports.isRequestApiError = isRequestApiError;