@ethitrust/sdk 1.0.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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +177 -0
  3. package/dist/client.d.ts +42 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +45 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/errors.d.ts +66 -0
  8. package/dist/errors.d.ts.map +1 -0
  9. package/dist/errors.js +115 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/http.d.ts +49 -0
  12. package/dist/http.d.ts.map +1 -0
  13. package/dist/http.js +193 -0
  14. package/dist/http.js.map +1 -0
  15. package/dist/index.d.ts +10 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +7 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/resources/orgEscrows.d.ts +53 -0
  20. package/dist/resources/orgEscrows.d.ts.map +1 -0
  21. package/dist/resources/orgEscrows.js +168 -0
  22. package/dist/resources/orgEscrows.js.map +1 -0
  23. package/dist/types.d.ts +229 -0
  24. package/dist/types.d.ts.map +1 -0
  25. package/dist/types.js +6 -0
  26. package/dist/types.js.map +1 -0
  27. package/dist/utils/idempotency.d.ts +9 -0
  28. package/dist/utils/idempotency.d.ts.map +1 -0
  29. package/dist/utils/idempotency.js +25 -0
  30. package/dist/utils/idempotency.js.map +1 -0
  31. package/dist/utils/query.d.ts +8 -0
  32. package/dist/utils/query.d.ts.map +1 -0
  33. package/dist/utils/query.js +35 -0
  34. package/dist/utils/query.js.map +1 -0
  35. package/package.json +51 -0
  36. package/src/client.ts +69 -0
  37. package/src/errors.ts +140 -0
  38. package/src/http.ts +246 -0
  39. package/src/index.ts +23 -0
  40. package/src/resources/orgEscrows.ts +246 -0
  41. package/src/types.ts +286 -0
  42. package/src/utils/idempotency.ts +23 -0
  43. package/src/utils/query.ts +31 -0
package/src/types.ts ADDED
@@ -0,0 +1,286 @@
1
+ /**
2
+ * Typed models for the Ethitrust org-escrows API.
3
+ * Generated by hand from the OpenAPI spec (ethi-mono v0.1.0).
4
+ */
5
+
6
+ // ───── Enums ─────────────────────────────────────────────────────────────────
7
+
8
+ export type EscrowType = 'onetime' | 'milestone' | 'recurring';
9
+
10
+ export type EscrowStatus =
11
+ | 'invited'
12
+ | 'counter_pending_initiator'
13
+ | 'counter_pending_counterparty'
14
+ | 'rejected'
15
+ | 'expired'
16
+ | 'pending'
17
+ | 'active'
18
+ | 'submitted'
19
+ | 'in_review'
20
+ | 'completed'
21
+ | 'disputed'
22
+ | 'cancelled'
23
+ | 'refunded';
24
+
25
+ export type InitiatorActorType = 'user' | 'organization';
26
+ export type InitiatorRole = 'buyer' | 'seller';
27
+ export type FeePayer = 'buyer' | 'seller' | 'split';
28
+ export type CounterStatus =
29
+ | 'none'
30
+ | 'awaiting_initiator'
31
+ | 'awaiting_counterparty'
32
+ | 'accepted'
33
+ | 'rejected';
34
+ export type RiskSeverity = 'low' | 'medium' | 'high';
35
+ export type MilestoneStatus =
36
+ | 'pending'
37
+ | 'in_progress'
38
+ | 'delivered'
39
+ | 'completed'
40
+ | 'disputed';
41
+
42
+ // ───── Shared sub-types ──────────────────────────────────────────────────────
43
+
44
+ export interface RiskFlag {
45
+ code: string;
46
+ message: string;
47
+ severity: RiskSeverity;
48
+ }
49
+
50
+ export interface LatestEvent {
51
+ event_type: string;
52
+ actor: string;
53
+ timestamp: string;
54
+ metadata?: Record<string, unknown> | null;
55
+ }
56
+
57
+ export interface EscrowVolumePoint {
58
+ date: string;
59
+ count: number;
60
+ total_amount: number;
61
+ }
62
+
63
+ export interface MilestoneRequest {
64
+ title: string;
65
+ description?: string | null;
66
+ amount: number;
67
+ due_date?: string | null;
68
+ /** Defaults to 48 on the server. */
69
+ inspection_hrs?: number;
70
+ }
71
+
72
+ export interface MilestoneResponse {
73
+ id: string;
74
+ escrow_id: string;
75
+ title: string;
76
+ description: string | null;
77
+ amount: number;
78
+ due_date: string | null;
79
+ inspection_hrs: number;
80
+ status: MilestoneStatus;
81
+ delivered_at: string | null;
82
+ completed_at: string | null;
83
+ sort_order: number;
84
+ }
85
+
86
+ // ───── Requests ──────────────────────────────────────────────────────────────
87
+
88
+ export interface OrganizationInitializeEscrowRequest {
89
+ invitee_email: string;
90
+ /** Defaults to 'onetime'. */
91
+ escrow_type?: EscrowType;
92
+ title: string;
93
+ description?: string | null;
94
+ /** Defaults to 'ETB'. */
95
+ currency?: string;
96
+ amount: number;
97
+ acceptance_criteria?: string | null;
98
+ /** Hours. Defaults to 48. */
99
+ inspection_period?: number;
100
+ delivery_date?: string | null;
101
+ /** Hours. Defaults to 72. */
102
+ dispute_window?: number;
103
+ /** Defaults to 'buyer'. */
104
+ who_pays_fees?: FeePayer;
105
+ milestones?: MilestoneRequest[] | null;
106
+ }
107
+
108
+ export interface ListOrgEscrowsParams {
109
+ status?: string;
110
+ is_active?: boolean;
111
+ /** ISO 8601 date-time. */
112
+ date_from?: string | Date;
113
+ /** ISO 8601 date-time. */
114
+ date_to?: string | Date;
115
+ search?: string;
116
+ page?: number;
117
+ page_size?: number;
118
+ }
119
+
120
+ export interface OrgEscrowReportParams {
121
+ /** ISO 8601 date-time. */
122
+ date_from?: string | Date;
123
+ /** ISO 8601 date-time. */
124
+ date_to?: string | Date;
125
+ }
126
+
127
+ // ───── Responses ─────────────────────────────────────────────────────────────
128
+
129
+ export interface InitializeEscrowResponse {
130
+ id: string;
131
+ escrow_type: EscrowType;
132
+ status: EscrowStatus;
133
+ initiator_actor_type: InitiatorActorType;
134
+ initiator_id: string | null;
135
+ initiator_org_id: string | null;
136
+ receiver_id: string | null;
137
+ receiver_email: string | null;
138
+ initiator_role: InitiatorRole;
139
+ title: string;
140
+ description: string | null;
141
+ currency: string;
142
+ amount: number;
143
+ fee_amount: number;
144
+ acceptance_criteria: string | null;
145
+ inspection_period: number;
146
+ delivery_date: string | null;
147
+ dispute_window: number;
148
+ who_pays_fees: FeePayer;
149
+ org_id: string | null;
150
+ offer_version: number;
151
+ counter_status: CounterStatus;
152
+ active_counter_offer_version: number | null;
153
+ created_at: string;
154
+ updated_at: string;
155
+ invitation_sent?: boolean;
156
+ }
157
+
158
+ export interface OrgEscrowCancelResponse extends InitializeEscrowResponse {
159
+ refunded?: boolean;
160
+ }
161
+
162
+ export interface OrgEscrowListItem {
163
+ escrow_id: string;
164
+ organization_id: string | null;
165
+ title: string;
166
+ status: string;
167
+ is_active: boolean;
168
+ amount: number;
169
+ currency: string;
170
+ receiver_email?: string | null;
171
+ funded_amount: number;
172
+ created_at: string;
173
+ updated_at: string;
174
+ expires_at?: string | null;
175
+ }
176
+
177
+ export interface OrgEscrowListResponse {
178
+ items: OrgEscrowListItem[];
179
+ page: number;
180
+ page_size: number;
181
+ total: number;
182
+ total_pages: number;
183
+ }
184
+
185
+ export interface OrgEscrowStatusResponse {
186
+ escrow_id: string;
187
+ organization_id: string | null;
188
+ status: string;
189
+ is_active: boolean;
190
+ can_cancel: boolean;
191
+ can_resend_invite: boolean;
192
+ can_accept: boolean;
193
+ expires_at: string | null;
194
+ funded_amount: number;
195
+ currency: string;
196
+ amount: number;
197
+ updated_at: string;
198
+ }
199
+
200
+ export interface OrgEscrowDetailResponse extends OrgEscrowStatusResponse {
201
+ title: string;
202
+ description?: string | null;
203
+ escrow_type: string;
204
+ initiator_role: string;
205
+ receiver_email?: string | null;
206
+ receiver_id?: string | null;
207
+ fee_amount: number;
208
+ who_pays_fees: string;
209
+ created_at: string;
210
+ /** 0-100. */
211
+ progress_percentage: number;
212
+ current_phase: string;
213
+ next_action?: string | null;
214
+ risk_flags?: RiskFlag[];
215
+ latest_event?: LatestEvent | null;
216
+ }
217
+
218
+ export interface OrgEscrowHealthResponse {
219
+ escrow_id: string;
220
+ is_active: boolean;
221
+ is_expired: boolean;
222
+ is_fundable: boolean;
223
+ is_cancellable: boolean;
224
+ is_disputable: boolean;
225
+ is_settled: boolean;
226
+ }
227
+
228
+ export interface OrgEscrowReportResponse {
229
+ organization_id: string;
230
+ period_from: string;
231
+ period_to: string;
232
+ total_escrows: number;
233
+ active_escrow_count: number;
234
+ completion_rate: number;
235
+ dispute_rate: number;
236
+ avg_settlement_time_hours?: number | null;
237
+ volume_over_time?: EscrowVolumePoint[];
238
+ }
239
+
240
+ export interface OrgEscrowAuditEvent {
241
+ event_id: string;
242
+ escrow_id: string;
243
+ actor: string;
244
+ action: string;
245
+ timestamp: string;
246
+ metadata?: Record<string, unknown> | null;
247
+ }
248
+
249
+ export interface OrgEscrowAuditTrailResponse {
250
+ escrow_id: string;
251
+ events: OrgEscrowAuditEvent[];
252
+ total: number;
253
+ }
254
+
255
+ export interface WebhookLogEntry {
256
+ id: string;
257
+ event_type: string;
258
+ target_url: string;
259
+ http_status: number | null;
260
+ attempt: number;
261
+ delivery_status: string;
262
+ error_message?: string | null;
263
+ created_at: string;
264
+ next_retry_at?: string | null;
265
+ }
266
+
267
+ export interface WebhookTestResponse {
268
+ success: boolean;
269
+ http_status?: number | null;
270
+ error?: string | null;
271
+ target_url?: string | null;
272
+ }
273
+
274
+ // ───── Validation error envelope ─────────────────────────────────────────────
275
+
276
+ export interface ValidationErrorItem {
277
+ loc: Array<string | number>;
278
+ msg: string;
279
+ type: string;
280
+ input?: unknown;
281
+ ctx?: Record<string, unknown>;
282
+ }
283
+
284
+ export interface HTTPValidationError {
285
+ detail?: ValidationErrorItem[];
286
+ }
@@ -0,0 +1,23 @@
1
+ import { randomUUID, randomBytes } from 'node:crypto';
2
+
3
+ /**
4
+ * Generate a RFC-4122 v4 idempotency key suitable for the
5
+ * `X-Idempotency-Key` header.
6
+ *
7
+ * Falls back to the Web Crypto API when `node:crypto` is unavailable
8
+ * (e.g. edge runtimes).
9
+ */
10
+ export function generateIdempotencyKey(prefix?: string): string {
11
+ let id: string;
12
+ try {
13
+ id = randomUUID();
14
+ } catch {
15
+ const g = globalThis as { crypto?: { randomUUID?: () => string } };
16
+ if (g.crypto?.randomUUID) {
17
+ id = g.crypto.randomUUID();
18
+ } else {
19
+ id = randomBytes(16).toString('hex');
20
+ }
21
+ }
22
+ return prefix ? `${prefix}_${id}` : id;
23
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Serialise a flat record to a URLSearchParams instance.
3
+ * - `undefined` / `null` values are skipped.
4
+ * - `Date` objects are serialised to ISO 8601.
5
+ * - Arrays are repeated as `?key=a&key=b`.
6
+ */
7
+ export function toQueryString(
8
+ params: Record<string, unknown> | undefined,
9
+ ): string {
10
+ if (!params) return '';
11
+ const usp = new URLSearchParams();
12
+ for (const [k, v] of Object.entries(params)) {
13
+ if (v === undefined || v === null) continue;
14
+ if (Array.isArray(v)) {
15
+ for (const item of v) {
16
+ if (item === undefined || item === null) continue;
17
+ usp.append(k, serialiseScalar(item));
18
+ }
19
+ } else {
20
+ usp.append(k, serialiseScalar(v));
21
+ }
22
+ }
23
+ const s = usp.toString();
24
+ return s ? `?${s}` : '';
25
+ }
26
+
27
+ function serialiseScalar(v: unknown): string {
28
+ if (v instanceof Date) return v.toISOString();
29
+ if (typeof v === 'boolean') return v ? 'true' : 'false';
30
+ return String(v);
31
+ }