@avenlabs/halal-trace-sdk 0.1.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/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # SDK Package
2
+
3
+ TypeScript SDK for Halal Trace API.
4
+
5
+ ## Install
6
+
7
+ ```
8
+ pnpm add @halal-trace/sdk
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```ts
14
+ import { ApiClient } from "@halal-trace/sdk";
15
+
16
+ const client = new ApiClient({
17
+ baseUrl: "http://localhost:4000",
18
+ auth: { token: "<bearer>" },
19
+ allowInsecure: true,
20
+ retry: { maxRetries: 2 },
21
+ });
22
+
23
+ const health = await client.health.get();
24
+ ```
25
+
26
+ Response includes `requestId`:
27
+
28
+ ```ts
29
+ const org = await client.orgs.create({ orgId: "ORG-1" }, { idempotencyKey: "org-ORG-1" });
30
+ console.log(org.requestId);
31
+ ```
32
+
33
+ ## Auth strategies
34
+
35
+ - Static token:
36
+
37
+ ```ts
38
+ auth: { token: "<token>" }
39
+ ```
40
+
41
+ - Async provider:
42
+
43
+ ```ts
44
+ auth: { getToken: async () => "<token>" }
45
+ ```
46
+
47
+ ## Auth endpoints
48
+
49
+ ```ts
50
+ const signup = await client.auth.signUpEmail({
51
+ name: "Admin",
52
+ email: "admin@company.com",
53
+ password: "StrongPass123!",
54
+ });
55
+
56
+ const login = await client.auth.signInEmail({
57
+ email: "admin@company.com",
58
+ password: "StrongPass123!",
59
+ });
60
+
61
+ const token = login.token;
62
+ ```
63
+
64
+ ## Org management
65
+
66
+ ```ts
67
+ await client.orgs.addMember("ORG-001", { userId: "USER-1", role: "qa" });
68
+ await client.orgs.addPermission("ORG-001", { action: "batch:create", role: "qa" });
69
+ const lookup = await client.orgs.lookupUserByEmail("ORG-001", "qa@company.com");
70
+ ```
71
+
72
+ ## Idempotency
73
+
74
+ For create/mutate methods, pass `idempotencyKey` to enable safe retries.
75
+
76
+ ```ts
77
+ await client.batches.create(
78
+ { batchId: "B-01", orgId: "ORG-01", productId: "PROD-01" },
79
+ { idempotencyKey: "batch-B-01" },
80
+ );
81
+ ```
82
+
83
+ ## Observability hooks
84
+
85
+ ```ts
86
+ const client = new ApiClient({
87
+ baseUrl: "http://localhost:4000",
88
+ allowInsecure: true,
89
+ hooks: {
90
+ onRequest: ({ method, url, requestId }) => console.log("REQ", requestId, method, url),
91
+ onResponse: ({ status, requestId, durationMs }) => console.log("RES", requestId, status, durationMs),
92
+ onError: ({ error, requestId }) => console.error("ERR", requestId, error.message),
93
+ },
94
+ });
95
+ ```
96
+
97
+ ## List all relayer jobs
98
+
99
+ ```ts
100
+ for await (const job of client.relayerJobs.listAll("ORG-001")) {
101
+ console.log(job.status, job.txHash);
102
+ }
103
+ ```
104
+
105
+ ## System endpoints
106
+
107
+ ```ts
108
+ const docsHtml = await client.system.docs();
109
+ const openApi = await client.system.openApi();
110
+ const metrics = await client.system.metrics();
111
+ const inviteHtml = await client.system.inviteLanding("ORG-001", "token");
112
+ ```
113
+
114
+ ## Commands
115
+
116
+ ```
117
+ pnpm build
118
+ ```
@@ -0,0 +1,442 @@
1
+ import type { Anchor, AuditLog, AuditPack, AuditPackManifest, AuthResult, Batch, CertificationRecord, Device, DocumentAnchor, EventDepartment, HealthResponse, Hologram, HologramVerification, Invite, Member, Org, OrgInviteResult, OrgUserLookup, Permission, PublicAttribute, RelayerJobSummary, SignatureRecord, TraceEvent } from "./types.js";
2
+ import { ApiError, type AuthOptions, type ClientHooks, type RequestOptions, type RetryOptions } from "./http.js";
3
+ type BaseClientOptions = {
4
+ baseUrl: string;
5
+ timeoutMs?: number;
6
+ headers?: Record<string, string>;
7
+ auth?: AuthOptions;
8
+ retry?: RetryOptions;
9
+ allowInsecure?: boolean;
10
+ onAuthError?: (error: ApiError) => void | Promise<void>;
11
+ hooks?: ClientHooks;
12
+ userAgent?: string;
13
+ clientVersion?: string;
14
+ signingHook?: RequestOptions["signingHook"];
15
+ };
16
+ type RequestConfig = Omit<RequestOptions, "sdkHeaders" | "hooks" | "signingHook"> & {
17
+ auth?: AuthOptions;
18
+ timeoutMs?: number;
19
+ retry?: RetryOptions;
20
+ allowInsecure?: boolean;
21
+ onAuthError?: (error: ApiError) => void | Promise<void>;
22
+ };
23
+ export declare class ApiClient {
24
+ baseUrl: string;
25
+ timeoutMs?: number;
26
+ headers?: Record<string, string>;
27
+ authOptions?: AuthOptions;
28
+ retry?: RetryOptions;
29
+ allowInsecure?: boolean;
30
+ onAuthError?: (error: ApiError) => void | Promise<void>;
31
+ hooks?: ClientHooks;
32
+ userAgent?: string;
33
+ clientVersion?: string;
34
+ signingHook?: RequestOptions["signingHook"];
35
+ constructor(options: BaseClientOptions);
36
+ request<T>(method: string, path: string, options?: RequestConfig): Promise<{
37
+ body: {
38
+ requestId: string;
39
+ status: import("./types.js").ApiStatus;
40
+ data?: T | undefined;
41
+ relayerJob?: RelayerJobSummary | null;
42
+ };
43
+ requestId: string;
44
+ }>;
45
+ health: {
46
+ get: () => Promise<HealthResponse>;
47
+ live: () => Promise<HealthResponse>;
48
+ ready: () => Promise<HealthResponse>;
49
+ };
50
+ system: {
51
+ docs: () => Promise<string>;
52
+ openApi: () => Promise<unknown>;
53
+ metrics: () => Promise<string>;
54
+ inviteLanding: (orgId: string, token: string) => Promise<string>;
55
+ };
56
+ auth: {
57
+ signUpEmail: (payload: {
58
+ name: string;
59
+ email: string;
60
+ password: string;
61
+ callbackURL?: string;
62
+ }, options?: RequestConfig) => Promise<AuthResult>;
63
+ signInEmail: (payload: {
64
+ email: string;
65
+ password: string;
66
+ }, options?: RequestConfig) => Promise<AuthResult>;
67
+ verifyEmail: (token: string, callbackURL?: string) => Promise<AuthResult>;
68
+ requestPasswordReset: (payload: {
69
+ email: string;
70
+ }) => Promise<AuthResult>;
71
+ resetPassword: (payload: {
72
+ token: string;
73
+ newPassword: string;
74
+ }) => Promise<AuthResult>;
75
+ };
76
+ orgs: {
77
+ create: (payload: {
78
+ orgId: string;
79
+ name?: string;
80
+ }, options?: RequestConfig) => Promise<{
81
+ requestId: string;
82
+ status: import("./types.js").ApiStatus;
83
+ data?: Org | undefined;
84
+ relayerJob?: RelayerJobSummary | null;
85
+ }>;
86
+ addMember: (orgId: string, payload: {
87
+ userId: string;
88
+ role: string;
89
+ department?: string;
90
+ }, options?: RequestConfig) => Promise<{
91
+ requestId: string;
92
+ status: import("./types.js").ApiStatus;
93
+ data?: Member | undefined;
94
+ relayerJob?: RelayerJobSummary | null;
95
+ }>;
96
+ updateMember: (orgId: string, userId: string, payload: {
97
+ role?: string;
98
+ department?: string;
99
+ }) => Promise<{
100
+ requestId: string;
101
+ status: import("./types.js").ApiStatus;
102
+ data?: Member | undefined;
103
+ relayerJob?: RelayerJobSummary | null;
104
+ }>;
105
+ removeMember: (orgId: string, userId: string) => Promise<{
106
+ requestId: string;
107
+ status: import("./types.js").ApiStatus;
108
+ data?: Member | undefined;
109
+ relayerJob?: RelayerJobSummary | null;
110
+ }>;
111
+ listMembers: (orgId: string) => Promise<{
112
+ requestId: string;
113
+ status: import("./types.js").ApiStatus;
114
+ data?: Member[] | undefined;
115
+ relayerJob?: RelayerJobSummary | null;
116
+ }>;
117
+ listMembersAll: (orgId: string) => AsyncGenerator<Member, void, unknown>;
118
+ listAuditLogs: (orgId: string, query?: {
119
+ limit?: number;
120
+ offset?: number;
121
+ }) => Promise<{
122
+ requestId: string;
123
+ status: import("./types.js").ApiStatus;
124
+ data?: AuditLog[] | undefined;
125
+ relayerJob?: RelayerJobSummary | null;
126
+ }>;
127
+ listAuditLogsAll: (orgId: string, query?: {
128
+ limit?: number;
129
+ }) => AsyncGenerator<AuditLog, void, unknown>;
130
+ listRelayerJobs: (orgId: string, query?: {
131
+ status?: string;
132
+ jobType?: string;
133
+ batchId?: string;
134
+ requestId?: string;
135
+ limit?: number;
136
+ offset?: number;
137
+ }) => Promise<{
138
+ requestId: string;
139
+ status: import("./types.js").ApiStatus;
140
+ data?: RelayerJobSummary[] | undefined;
141
+ relayerJob?: RelayerJobSummary | null;
142
+ }>;
143
+ getRelayerJob: (orgId: string, jobId: number) => Promise<{
144
+ requestId: string;
145
+ status: import("./types.js").ApiStatus;
146
+ data?: RelayerJobSummary | undefined;
147
+ relayerJob?: RelayerJobSummary | null;
148
+ }>;
149
+ listDeadRelayerJobs: (orgId: string) => Promise<{
150
+ requestId: string;
151
+ status: import("./types.js").ApiStatus;
152
+ data?: RelayerJobSummary[] | undefined;
153
+ relayerJob?: RelayerJobSummary | null;
154
+ }>;
155
+ retryRelayerJob: (orgId: string, jobId: number) => Promise<{
156
+ requestId: string;
157
+ status: import("./types.js").ApiStatus;
158
+ data?: RelayerJobSummary | undefined;
159
+ relayerJob?: RelayerJobSummary | null;
160
+ }>;
161
+ backfillOrg: (orgId: string) => Promise<{
162
+ requestId: string;
163
+ status: import("./types.js").ApiStatus;
164
+ data?: RelayerJobSummary | undefined;
165
+ relayerJob?: RelayerJobSummary | null;
166
+ }>;
167
+ listInvites: (orgId: string, query?: {
168
+ status?: string;
169
+ }) => Promise<{
170
+ requestId: string;
171
+ status: import("./types.js").ApiStatus;
172
+ data?: Invite[] | undefined;
173
+ relayerJob?: RelayerJobSummary | null;
174
+ }>;
175
+ listInvitesAll: (orgId: string, query?: {
176
+ status?: string;
177
+ }) => AsyncGenerator<Invite, void, unknown>;
178
+ inviteMember: (orgId: string, payload: {
179
+ email: string;
180
+ role: string;
181
+ department?: string;
182
+ inviteUrl?: string;
183
+ }, options?: RequestConfig) => Promise<{
184
+ requestId: string;
185
+ status: import("./types.js").ApiStatus;
186
+ data?: OrgInviteResult | undefined;
187
+ relayerJob?: RelayerJobSummary | null;
188
+ }>;
189
+ acceptInvite: (orgId: string, token: string) => Promise<{
190
+ requestId: string;
191
+ status: import("./types.js").ApiStatus;
192
+ data?: {
193
+ invite: Invite;
194
+ member: Member;
195
+ } | undefined;
196
+ relayerJob?: RelayerJobSummary | null;
197
+ }>;
198
+ lookupUserByEmail: (orgId: string, email: string) => Promise<{
199
+ requestId: string;
200
+ status: import("./types.js").ApiStatus;
201
+ data?: OrgUserLookup | undefined;
202
+ relayerJob?: RelayerJobSummary | null;
203
+ }>;
204
+ listPermissions: (orgId: string) => Promise<{
205
+ requestId: string;
206
+ status: import("./types.js").ApiStatus;
207
+ data?: Permission[] | undefined;
208
+ relayerJob?: RelayerJobSummary | null;
209
+ }>;
210
+ addPermission: (orgId: string, payload: {
211
+ action: string;
212
+ role: string;
213
+ }) => Promise<{
214
+ requestId: string;
215
+ status: import("./types.js").ApiStatus;
216
+ data?: Permission | undefined;
217
+ relayerJob?: RelayerJobSummary | null;
218
+ }>;
219
+ removePermission: (orgId: string, payload: {
220
+ action: string;
221
+ role: string;
222
+ }) => Promise<{
223
+ requestId: string;
224
+ status: import("./types.js").ApiStatus;
225
+ data?: {
226
+ orgId: string;
227
+ action: string;
228
+ role: string;
229
+ } | undefined;
230
+ relayerJob?: RelayerJobSummary | null;
231
+ }>;
232
+ setEventDepartment: (orgId: string, payload: {
233
+ eventType: string;
234
+ department: string;
235
+ }) => Promise<{
236
+ requestId: string;
237
+ status: import("./types.js").ApiStatus;
238
+ data?: EventDepartment | undefined;
239
+ relayerJob?: RelayerJobSummary | null;
240
+ }>;
241
+ };
242
+ relayerJobs: {
243
+ listAll: (orgId: string, query?: {
244
+ status?: string;
245
+ jobType?: string;
246
+ batchId?: string;
247
+ limit?: number;
248
+ }) => AsyncGenerator<RelayerJobSummary, void, unknown>;
249
+ get: (orgId: string, jobId: number) => Promise<RelayerJobSummary | undefined>;
250
+ waitFor: (orgId: string, jobId: number, options?: {
251
+ timeoutMs?: number;
252
+ intervalMs?: number;
253
+ }) => Promise<RelayerJobSummary>;
254
+ waitForRequest: (orgId: string, requestId: string, options?: {
255
+ timeoutMs?: number;
256
+ intervalMs?: number;
257
+ }) => Promise<RelayerJobSummary>;
258
+ };
259
+ batches: {
260
+ create: (payload: {
261
+ batchId: string;
262
+ orgId: string;
263
+ productId: string;
264
+ facilityId?: string;
265
+ }, options?: RequestConfig) => Promise<{
266
+ requestId: string;
267
+ status: import("./types.js").ApiStatus;
268
+ data?: Batch | undefined;
269
+ relayerJob?: RelayerJobSummary | null;
270
+ }>;
271
+ addPublicAttribute: (batchId: string, payload: {
272
+ key: string;
273
+ value: string;
274
+ }, options?: RequestConfig) => Promise<{
275
+ requestId: string;
276
+ status: import("./types.js").ApiStatus;
277
+ data?: PublicAttribute | undefined;
278
+ relayerJob?: RelayerJobSummary | null;
279
+ }>;
280
+ addEvent: (batchId: string, payload: {
281
+ eventType: string;
282
+ metadataHash: string;
283
+ actorRole: string;
284
+ deviceId?: string;
285
+ }, options?: RequestConfig) => Promise<{
286
+ requestId: string;
287
+ status: import("./types.js").ApiStatus;
288
+ data?: TraceEvent | undefined;
289
+ relayerJob?: RelayerJobSummary | null;
290
+ }>;
291
+ addDocument: (batchId: string, payload: {
292
+ docHash: string;
293
+ docType: string;
294
+ uri: string;
295
+ }, options?: RequestConfig) => Promise<{
296
+ requestId: string;
297
+ status: import("./types.js").ApiStatus;
298
+ data?: DocumentAnchor | undefined;
299
+ relayerJob?: RelayerJobSummary | null;
300
+ }>;
301
+ addSignature: (batchId: string, payload: {
302
+ signatureHash: string;
303
+ signerRole: string;
304
+ signerIdHash: string;
305
+ }, options?: RequestConfig) => Promise<{
306
+ requestId: string;
307
+ status: import("./types.js").ApiStatus;
308
+ data?: SignatureRecord | undefined;
309
+ relayerJob?: RelayerJobSummary | null;
310
+ }>;
311
+ addCertification: (batchId: string, payload: {
312
+ status: "pending" | "approved" | "rejected";
313
+ decisionHash: string;
314
+ reviewerRole: string;
315
+ reviewerIdHash: string;
316
+ }, options?: RequestConfig) => Promise<{
317
+ requestId: string;
318
+ status: import("./types.js").ApiStatus;
319
+ data?: CertificationRecord | undefined;
320
+ relayerJob?: RelayerJobSummary | null;
321
+ }>;
322
+ getAuditPackManifest: (batchId: string) => Promise<{
323
+ requestId: string;
324
+ status: import("./types.js").ApiStatus;
325
+ data?: AuditPackManifest | undefined;
326
+ relayerJob?: RelayerJobSummary | null;
327
+ }>;
328
+ listRelayerJobs: (batchId: string, query?: {
329
+ status?: string;
330
+ jobType?: string;
331
+ limit?: number;
332
+ offset?: number;
333
+ }) => Promise<{
334
+ requestId: string;
335
+ status: import("./types.js").ApiStatus;
336
+ data?: RelayerJobSummary[] | undefined;
337
+ relayerJob?: RelayerJobSummary | null;
338
+ }>;
339
+ listRelayerJobsAll: (batchId: string, query?: {
340
+ status?: string;
341
+ jobType?: string;
342
+ limit?: number;
343
+ }) => AsyncGenerator<RelayerJobSummary, void, unknown>;
344
+ backfillBatch: (batchId: string) => Promise<{
345
+ requestId: string;
346
+ status: import("./types.js").ApiStatus;
347
+ data?: RelayerJobSummary | undefined;
348
+ relayerJob?: RelayerJobSummary | null;
349
+ }>;
350
+ };
351
+ devices: {
352
+ register: (payload: {
353
+ deviceId: string;
354
+ orgId: string;
355
+ deviceType: string;
356
+ label: string;
357
+ }, options?: RequestConfig) => Promise<{
358
+ requestId: string;
359
+ status: import("./types.js").ApiStatus;
360
+ data?: Device | undefined;
361
+ relayerJob?: RelayerJobSummary | null;
362
+ }>;
363
+ update: (deviceId: string, payload: {
364
+ deviceType: string;
365
+ label: string;
366
+ }, options?: RequestConfig) => Promise<{
367
+ requestId: string;
368
+ status: import("./types.js").ApiStatus;
369
+ data?: Device | undefined;
370
+ relayerJob?: RelayerJobSummary | null;
371
+ }>;
372
+ setStatus: (deviceId: string, payload: {
373
+ active: boolean;
374
+ }, options?: RequestConfig) => Promise<{
375
+ requestId: string;
376
+ status: import("./types.js").ApiStatus;
377
+ data?: Device | undefined;
378
+ relayerJob?: RelayerJobSummary | null;
379
+ }>;
380
+ };
381
+ anchors: {
382
+ create: (payload: {
383
+ orgId: string;
384
+ merkleRoot: string;
385
+ metadataHash: string;
386
+ periodStart: number;
387
+ periodEnd: number;
388
+ anchorChainId: number;
389
+ anchorTxHash: string;
390
+ }, options?: RequestConfig) => Promise<{
391
+ requestId: string;
392
+ status: import("./types.js").ApiStatus;
393
+ data?: Anchor | undefined;
394
+ relayerJob?: RelayerJobSummary | null;
395
+ }>;
396
+ };
397
+ auditPacks: {
398
+ create: (payload: {
399
+ batchId: string;
400
+ pdfHash: string;
401
+ jsonHash?: string;
402
+ packVersion: string;
403
+ pdfUri: string;
404
+ jsonUri?: string;
405
+ }, options?: RequestConfig) => Promise<{
406
+ requestId: string;
407
+ status: import("./types.js").ApiStatus;
408
+ data?: AuditPack | undefined;
409
+ relayerJob?: RelayerJobSummary | null;
410
+ }>;
411
+ downloadPdf: (pdfUri: string) => Promise<ArrayBuffer>;
412
+ downloadJson: (jsonUri: string) => Promise<string>;
413
+ };
414
+ holograms: {
415
+ issue: (payload: {
416
+ batchId: string;
417
+ hologramId: string;
418
+ metadataHash: string;
419
+ uri: string;
420
+ publicCode?: string;
421
+ }, options?: RequestConfig) => Promise<{
422
+ requestId: string;
423
+ status: import("./types.js").ApiStatus;
424
+ data?: Hologram | undefined;
425
+ relayerJob?: RelayerJobSummary | null;
426
+ }>;
427
+ revoke: (payload: {
428
+ hologramId: string;
429
+ reasonHash: string;
430
+ }, options?: RequestConfig) => Promise<{
431
+ requestId: string;
432
+ status: import("./types.js").ApiStatus;
433
+ data?: {
434
+ hologramId: string;
435
+ active: boolean;
436
+ } | undefined;
437
+ relayerJob?: RelayerJobSummary | null;
438
+ }>;
439
+ verify: (publicCode: string) => Promise<HologramVerification | null>;
440
+ };
441
+ }
442
+ export type { BaseClientOptions, RequestConfig };