@decentrys/dri-sdk 0.1.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.
@@ -0,0 +1,183 @@
1
+ /**
2
+ * The DRI client — Digital Recovery Intelligence.
3
+ *
4
+ * Fund tracing, attribution, intervention-point identification and evidence
5
+ * packages, for the organisation whose value was taken.
6
+ *
7
+ * **This client throws**, like Sentinel and Risk and unlike Protect. Protect
8
+ * sits between a user and a signing screen, so a bad minute must never cost
9
+ * someone their transaction. Nothing here is on a signing path: a trace that
10
+ * quietly returned an empty graph when the service was unreachable would tell
11
+ * a responder the value had vanished at exactly the moment it was still
12
+ * moving, and that failure is invisible by construction. Better a loud error.
13
+ *
14
+ * **A publishable key is refused at construction.** An investigation names
15
+ * third parties who are, so far as the record shows, uninvolved businesses.
16
+ * That must never run behind a credential shipped inside a client artifact,
17
+ * where anyone who downloads it can read it and start naming people. The
18
+ * server refuses one too — `dri:investigate` is not a publishable scope and
19
+ * `/v1/dri/` is not a publishable path — but a clear error here beats a 403
20
+ * three weeks into an integration.
21
+ *
22
+ * What this client cannot do, at all, and by design:
23
+ *
24
+ * - It cannot freeze, seize, hold, transmit or return anything. Decentrys
25
+ * never takes custody of recovered value; it moves between the parties
26
+ * entitled to it and never through us.
27
+ * - It cannot record that a custodian, an issuer, a court or an agency acted.
28
+ * Those states name the party who acted and are written by staff, because
29
+ * an audit trail that says Decentrys did something it did not is worse than
30
+ * no trail.
31
+ * - It cannot give legal advice. Decentrys is not a law firm, a
32
+ * law-enforcement agency or a licensed recovery agent.
33
+ */
34
+ import { type EvidencePackage, type EvidenceRecipientType, type FlowGraph, type InterventionAnalysis, type InvestigationSummary, type InvestigationTimeline, type RecoveryCaseSummary, type RecoveryIndex, type TraceResult } from './model';
35
+ export declare const SDK_VERSION = "0.1.0";
36
+ export type FetchLike = (url: string, init: {
37
+ method: string;
38
+ headers: Record<string, string>;
39
+ body?: string;
40
+ signal?: AbortSignal;
41
+ }) => Promise<{
42
+ ok: boolean;
43
+ status: number;
44
+ text: () => Promise<string>;
45
+ }>;
46
+ export declare class DriError extends Error {
47
+ readonly status: number;
48
+ readonly code?: string | undefined;
49
+ constructor(status: number, message: string, code?: string | undefined);
50
+ }
51
+ export interface DriConfig {
52
+ apiKey: string;
53
+ baseUrl?: string;
54
+ timeoutMs?: number;
55
+ fetch?: FetchLike;
56
+ }
57
+ export interface CreateInvestigationInput {
58
+ /** What this case is, in a form a reader will recognise months later. */
59
+ title: string;
60
+ chain: string;
61
+ /** The seed: the victim contract, or the first attacker wallet. */
62
+ address: string;
63
+ /** Links the case to a declared incident of your own organisation. */
64
+ incidentId?: string;
65
+ /** 1-4. The graph will not be expanded past this distance from the seed. */
66
+ maxHops?: number;
67
+ }
68
+ export interface TraceFundsInput {
69
+ investigationId: string;
70
+ /**
71
+ * Which address to follow. Omit to take the shallowest one nobody has looked
72
+ * past yet, which is the ordering that keeps a graph anchored in what was
73
+ * directly traced.
74
+ */
75
+ fromNodeId?: string;
76
+ }
77
+ export interface EvidencePackageInput {
78
+ recoveryCaseId: string;
79
+ recipientType: EvidenceRecipientType;
80
+ recipientName: string;
81
+ /** Narrows the package to one identified destination, when there is one. */
82
+ recoveryLeadId?: string;
83
+ }
84
+ export declare class DecentrysDri {
85
+ private readonly baseUrl;
86
+ private readonly apiKey;
87
+ private readonly timeoutMs;
88
+ private readonly fetchImpl;
89
+ constructor(config: DriConfig);
90
+ /**
91
+ * Open an investigation seeded on one address.
92
+ *
93
+ * Nothing is traced yet. The seed node exists so the graph has a root before
94
+ * any chain call is made, which means a case can be opened and worked on
95
+ * even while a provider is unreachable.
96
+ */
97
+ createInvestigation(input: CreateInvestigationInput): Promise<FlowGraph>;
98
+ listInvestigations(limit?: number): Promise<InvestigationSummary[]>;
99
+ /**
100
+ * Follow the value one address further.
101
+ *
102
+ * One address, one hop, per call — and that is a deliberate limit rather
103
+ * than an unfinished feature. The public endpoints a trace reads are rate
104
+ * limited, and an unattended crawl to four hops exhausts them; the result
105
+ * then reads as "the funds vanished" rather than "we ran out of quota",
106
+ * which on this product is the worst possible way to be wrong. Call it in a
107
+ * loop if you want depth, and read `coverage.truncated` on each result.
108
+ */
109
+ traceFunds(input: TraceFundsInput): Promise<TraceResult>;
110
+ /** The graph as it stands: every address reached, and how it was reached. */
111
+ getFlowGraph(investigationId: string): Promise<FlowGraph>;
112
+ /**
113
+ * Where a third party could act, and where attribution stops.
114
+ *
115
+ * Read both halves. An intervention point is a party who holds value and can
116
+ * be contacted, served or subpoenaed — whether it does anything is a matter
117
+ * for it, its regulators and any legal process, never for Decentrys. An
118
+ * attribution limit is where the trail stops being provable, and a case that
119
+ * reaches one has established an answer rather than failed.
120
+ *
121
+ * Every point carries `observedPath`. False means the connection to this
122
+ * case runs through mixing or privacy infrastructure and is therefore
123
+ * inference — an observation about a counterparty, never an accusation about
124
+ * a person. `inferredPoints()` isolates them.
125
+ */
126
+ identifyInterventionPoints(investigationId: string): Promise<InterventionAnalysis>;
127
+ /**
128
+ * What happened on this case, oldest first, with the acting party on every
129
+ * entry.
130
+ *
131
+ * Merges the recovery record in when the incident behind the investigation
132
+ * has a case. Entries attributed to anyone other than Decentrys are recorded
133
+ * as reported by that party — Decentrys did not perform them and does not
134
+ * verify them.
135
+ */
136
+ getInvestigationTimeline(investigationId: string, limit?: number): Promise<InvestigationTimeline>;
137
+ /**
138
+ * The recovery cases of your organisation.
139
+ *
140
+ * A case is opened as part of an engagement, against a declared incident and
141
+ * a stated loss; the tranche ledger behind it is analyst work, so it is not
142
+ * something an API call brings into existence. This is how you find the
143
+ * `recoveryCaseId` that `getRecoveryIndex` and `generateEvidencePackage`
144
+ * take — and `getFlowGraph` reports it too, for an investigation attached to
145
+ * one.
146
+ */
147
+ listCases(limit?: number): Promise<RecoveryCaseSummary[]>;
148
+ /**
149
+ * The Recovery Index for a case.
150
+ *
151
+ * An **analytical estimate** of the current evidentiary and custodial
152
+ * position, produced by a versioned model from the evidence recorded in the
153
+ * case. It is not a probability, not a forecast, and not a representation
154
+ * that any value will be recovered. `modelVersion` and `inputsHash` come
155
+ * back with it so any figure shown to a client can be reproduced exactly
156
+ * from the record it was computed from.
157
+ *
158
+ * The disclaimer travels in the payload, and this method **refuses a
159
+ * response that does not carry it** rather than returning a bare number.
160
+ * That check is deliberately duplicated from the server: an integrator's
161
+ * dashboard renders whatever arrives, and "58 — MODERATE" beside the word
162
+ * recovery is read as a rate by everyone who sees it. If the caveat ever
163
+ * stops arriving, failing here is the only outcome that keeps the score
164
+ * honest.
165
+ */
166
+ getRecoveryIndex(recoveryCaseId: string): Promise<RecoveryIndex>;
167
+ /**
168
+ * Prepare an evidence package for a recipient.
169
+ *
170
+ * **Prepared, not sent.** The package goes to you and, at your direction, to
171
+ * your counsel, your insurer or a law-enforcement agency. Decentrys does not
172
+ * contact counterparties on your behalf unless instructed, and recording
173
+ * that a package was transmitted is a separate act that names who sent it.
174
+ *
175
+ * The document is frozen and hashed at generation, because third parties
176
+ * make freezing decisions on the strength of these and one that could be
177
+ * regenerated differently afterwards would be worth nothing. Quote
178
+ * `contentHash` back to a recipient so they can verify what they hold.
179
+ */
180
+ generateEvidencePackage(input: EvidencePackageInput): Promise<EvidencePackage>;
181
+ private request;
182
+ }
183
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAEL,KAAK,eAAe,EAAE,KAAK,qBAAqB,EAAE,KAAK,SAAS,EAAE,KAAK,oBAAoB,EAC3F,KAAK,oBAAoB,EAAE,KAAK,qBAAqB,EAAE,KAAK,mBAAmB,EAC/E,KAAK,aAAa,EAAE,KAAK,WAAW,EACrC,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,WAAW,UAAU,CAAC;AAanC,MAAM,MAAM,SAAS,GAAG,CACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,KAC3F,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAE3E,qBAAa,QAAS,SAAQ,KAAK;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM;IAAmB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM;gBAAvD,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAW,IAAI,CAAC,EAAE,MAAM,YAAA;CAI7E;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB;IACvC,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,qBAAqB,CAAC;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;gBAE1B,MAAM,EAAE,SAAS;IAoB7B;;;;;;OAMG;IACH,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,SAAS,CAAC;IAUxE,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAOnE;;;;;;;;;OASG;IACH,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC;IAMxD,6EAA6E;IAC7E,YAAY,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAIzD;;;;;;;;;;;;;OAaG;IACH,0BAA0B,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAMlF;;;;;;;;OAQG;IACH,wBAAwB,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IASjG;;;;;;;;;OASG;IACH,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAMzD;;;;;;;;;;;;;;;;;OAiBG;IACH,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAKhE;;;;;;;;;;;;OAYG;IACH,uBAAuB,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,eAAe,CAAC;YAahE,OAAO;CA4CtB"}
package/dist/client.js ADDED
@@ -0,0 +1,269 @@
1
+ "use strict";
2
+ /**
3
+ * The DRI client — Digital Recovery Intelligence.
4
+ *
5
+ * Fund tracing, attribution, intervention-point identification and evidence
6
+ * packages, for the organisation whose value was taken.
7
+ *
8
+ * **This client throws**, like Sentinel and Risk and unlike Protect. Protect
9
+ * sits between a user and a signing screen, so a bad minute must never cost
10
+ * someone their transaction. Nothing here is on a signing path: a trace that
11
+ * quietly returned an empty graph when the service was unreachable would tell
12
+ * a responder the value had vanished at exactly the moment it was still
13
+ * moving, and that failure is invisible by construction. Better a loud error.
14
+ *
15
+ * **A publishable key is refused at construction.** An investigation names
16
+ * third parties who are, so far as the record shows, uninvolved businesses.
17
+ * That must never run behind a credential shipped inside a client artifact,
18
+ * where anyone who downloads it can read it and start naming people. The
19
+ * server refuses one too — `dri:investigate` is not a publishable scope and
20
+ * `/v1/dri/` is not a publishable path — but a clear error here beats a 403
21
+ * three weeks into an integration.
22
+ *
23
+ * What this client cannot do, at all, and by design:
24
+ *
25
+ * - It cannot freeze, seize, hold, transmit or return anything. Decentrys
26
+ * never takes custody of recovered value; it moves between the parties
27
+ * entitled to it and never through us.
28
+ * - It cannot record that a custodian, an issuer, a court or an agency acted.
29
+ * Those states name the party who acted and are written by staff, because
30
+ * an audit trail that says Decentrys did something it did not is worse than
31
+ * no trail.
32
+ * - It cannot give legal advice. Decentrys is not a law firm, a
33
+ * law-enforcement agency or a licensed recovery agent.
34
+ */
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DecentrysDri = exports.DriError = exports.SDK_VERSION = void 0;
37
+ const model_1 = require("./model");
38
+ exports.SDK_VERSION = '0.1.0';
39
+ const DEFAULT_BASE_URL = 'https://api.decentrys.com';
40
+ /**
41
+ * Ten seconds, as elsewhere. A trace expands one address against rate-limited
42
+ * public endpoints, so it is the slowest call here by some margin — but a
43
+ * client that waits indefinitely is a client that hangs, and the graph is
44
+ * persisted server-side either way, so a timed-out trace is re-readable rather
45
+ * than lost.
46
+ */
47
+ const DEFAULT_TIMEOUT_MS = 30_000;
48
+ class DriError extends Error {
49
+ status;
50
+ code;
51
+ constructor(status, message, code) {
52
+ super(message);
53
+ this.status = status;
54
+ this.code = code;
55
+ this.name = 'DriError';
56
+ }
57
+ }
58
+ exports.DriError = DriError;
59
+ class DecentrysDri {
60
+ baseUrl;
61
+ apiKey;
62
+ timeoutMs;
63
+ fetchImpl;
64
+ constructor(config) {
65
+ if (!config.apiKey?.trim()) {
66
+ throw new Error('DRI: an apiKey is required. Create one at https://decentrys.com/developers.');
67
+ }
68
+ if (config.apiKey.startsWith('dk_pub_')) {
69
+ throw new Error('DRI: that is a publishable key. An investigation names third parties, and that must never run behind a '
70
+ + 'credential shipped inside a client where anyone who downloads it can read it. Use a secret key, '
71
+ + 'server-side.');
72
+ }
73
+ this.apiKey = config.apiKey;
74
+ this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, '');
75
+ this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
76
+ this.fetchImpl = config.fetch ?? resolveFetch();
77
+ }
78
+ // --- Investigations ------------------------------------------------------
79
+ /**
80
+ * Open an investigation seeded on one address.
81
+ *
82
+ * Nothing is traced yet. The seed node exists so the graph has a root before
83
+ * any chain call is made, which means a case can be opened and worked on
84
+ * even while a provider is unreachable.
85
+ */
86
+ createInvestigation(input) {
87
+ return this.request('POST', '/v1/dri/investigations', {
88
+ title: input.title,
89
+ chain: input.chain,
90
+ address: input.address,
91
+ ...(input.incidentId ? { incidentId: input.incidentId } : {}),
92
+ ...(input.maxHops === undefined ? {} : { maxHops: input.maxHops }),
93
+ });
94
+ }
95
+ listInvestigations(limit) {
96
+ const query = limit === undefined ? '' : `?limit=${encodeURIComponent(String(limit))}`;
97
+ return this.request('GET', `/v1/dri/investigations${query}`).then((body) => body.investigations);
98
+ }
99
+ /**
100
+ * Follow the value one address further.
101
+ *
102
+ * One address, one hop, per call — and that is a deliberate limit rather
103
+ * than an unfinished feature. The public endpoints a trace reads are rate
104
+ * limited, and an unattended crawl to four hops exhausts them; the result
105
+ * then reads as "the funds vanished" rather than "we ran out of quota",
106
+ * which on this product is the worst possible way to be wrong. Call it in a
107
+ * loop if you want depth, and read `coverage.truncated` on each result.
108
+ */
109
+ traceFunds(input) {
110
+ return this.request('POST', `/v1/dri/investigations/${encode(input.investigationId)}/trace`, {
111
+ ...(input.fromNodeId ? { fromNodeId: input.fromNodeId } : {}),
112
+ });
113
+ }
114
+ /** The graph as it stands: every address reached, and how it was reached. */
115
+ getFlowGraph(investigationId) {
116
+ return this.request('GET', `/v1/dri/investigations/${encode(investigationId)}`);
117
+ }
118
+ /**
119
+ * Where a third party could act, and where attribution stops.
120
+ *
121
+ * Read both halves. An intervention point is a party who holds value and can
122
+ * be contacted, served or subpoenaed — whether it does anything is a matter
123
+ * for it, its regulators and any legal process, never for Decentrys. An
124
+ * attribution limit is where the trail stops being provable, and a case that
125
+ * reaches one has established an answer rather than failed.
126
+ *
127
+ * Every point carries `observedPath`. False means the connection to this
128
+ * case runs through mixing or privacy infrastructure and is therefore
129
+ * inference — an observation about a counterparty, never an accusation about
130
+ * a person. `inferredPoints()` isolates them.
131
+ */
132
+ identifyInterventionPoints(investigationId) {
133
+ return this.request('GET', `/v1/dri/investigations/${encode(investigationId)}/intervention-points`);
134
+ }
135
+ /**
136
+ * What happened on this case, oldest first, with the acting party on every
137
+ * entry.
138
+ *
139
+ * Merges the recovery record in when the incident behind the investigation
140
+ * has a case. Entries attributed to anyone other than Decentrys are recorded
141
+ * as reported by that party — Decentrys did not perform them and does not
142
+ * verify them.
143
+ */
144
+ getInvestigationTimeline(investigationId, limit) {
145
+ const query = limit === undefined ? '' : `?limit=${encodeURIComponent(String(limit))}`;
146
+ return this.request('GET', `/v1/dri/investigations/${encode(investigationId)}/timeline${query}`);
147
+ }
148
+ // --- Recovery cases ------------------------------------------------------
149
+ /**
150
+ * The recovery cases of your organisation.
151
+ *
152
+ * A case is opened as part of an engagement, against a declared incident and
153
+ * a stated loss; the tranche ledger behind it is analyst work, so it is not
154
+ * something an API call brings into existence. This is how you find the
155
+ * `recoveryCaseId` that `getRecoveryIndex` and `generateEvidencePackage`
156
+ * take — and `getFlowGraph` reports it too, for an investigation attached to
157
+ * one.
158
+ */
159
+ listCases(limit) {
160
+ const query = limit === undefined ? '' : `?limit=${encodeURIComponent(String(limit))}`;
161
+ return this.request('GET', `/v1/dri/cases${query}`)
162
+ .then((body) => body.cases);
163
+ }
164
+ /**
165
+ * The Recovery Index for a case.
166
+ *
167
+ * An **analytical estimate** of the current evidentiary and custodial
168
+ * position, produced by a versioned model from the evidence recorded in the
169
+ * case. It is not a probability, not a forecast, and not a representation
170
+ * that any value will be recovered. `modelVersion` and `inputsHash` come
171
+ * back with it so any figure shown to a client can be reproduced exactly
172
+ * from the record it was computed from.
173
+ *
174
+ * The disclaimer travels in the payload, and this method **refuses a
175
+ * response that does not carry it** rather than returning a bare number.
176
+ * That check is deliberately duplicated from the server: an integrator's
177
+ * dashboard renders whatever arrives, and "58 — MODERATE" beside the word
178
+ * recovery is read as a rate by everyone who sees it. If the caveat ever
179
+ * stops arriving, failing here is the only outcome that keeps the score
180
+ * honest.
181
+ */
182
+ getRecoveryIndex(recoveryCaseId) {
183
+ return this.request('GET', `/v1/dri/cases/${encode(recoveryCaseId)}/recovery-index`)
184
+ .then(model_1.assertAnalyticalDisclosure);
185
+ }
186
+ /**
187
+ * Prepare an evidence package for a recipient.
188
+ *
189
+ * **Prepared, not sent.** The package goes to you and, at your direction, to
190
+ * your counsel, your insurer or a law-enforcement agency. Decentrys does not
191
+ * contact counterparties on your behalf unless instructed, and recording
192
+ * that a package was transmitted is a separate act that names who sent it.
193
+ *
194
+ * The document is frozen and hashed at generation, because third parties
195
+ * make freezing decisions on the strength of these and one that could be
196
+ * regenerated differently afterwards would be worth nothing. Quote
197
+ * `contentHash` back to a recipient so they can verify what they hold.
198
+ */
199
+ generateEvidencePackage(input) {
200
+ return this.request('POST', `/v1/dri/cases/${encode(input.recoveryCaseId)}/evidence-package`, {
201
+ recipientType: input.recipientType,
202
+ recipientName: input.recipientName,
203
+ ...(input.recoveryLeadId ? { recoveryLeadId: input.recoveryLeadId } : {}),
204
+ });
205
+ }
206
+ // --- transport -----------------------------------------------------------
207
+ async request(method, path, body) {
208
+ const controller = new AbortController();
209
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
210
+ try {
211
+ const response = await this.fetchImpl(`${this.baseUrl}${path}`, {
212
+ method,
213
+ headers: {
214
+ 'content-type': 'application/json',
215
+ 'x-api-key': this.apiKey,
216
+ 'user-agent': `decentrys-dri/${exports.SDK_VERSION}`,
217
+ },
218
+ ...(body === undefined ? {} : { body: JSON.stringify(body) }),
219
+ signal: controller.signal,
220
+ });
221
+ const text = await response.text();
222
+ if (!response.ok) {
223
+ const parsed = safeParse(text);
224
+ throw new DriError(response.status, typeof parsed?.message === 'string' ? parsed.message : `Decentrys returned HTTP ${response.status}.`, typeof parsed?.code === 'string' ? parsed.code : undefined);
225
+ }
226
+ if (!text)
227
+ return undefined;
228
+ const parsed = safeParse(text);
229
+ if (parsed === null)
230
+ throw new DriError(response.status, 'The response was not valid JSON.');
231
+ return ('data' in parsed ? parsed.data : parsed);
232
+ }
233
+ catch (error) {
234
+ if (error instanceof DriError)
235
+ throw error;
236
+ // A disclosure failure is not a transport failure and must not be
237
+ // rewritten as one — it is thrown by `assertAnalyticalDisclosure`
238
+ // downstream of this promise, but a caller wrapping the whole call in a
239
+ // retry would otherwise treat it as a blip and try again forever.
240
+ if (controller.signal.aborted)
241
+ throw new DriError(0, `No response within ${this.timeoutMs}ms.`);
242
+ throw new DriError(0, error instanceof Error ? error.message : 'Request failed.');
243
+ }
244
+ finally {
245
+ clearTimeout(timer);
246
+ }
247
+ }
248
+ }
249
+ exports.DecentrysDri = DecentrysDri;
250
+ function encode(segment) {
251
+ return encodeURIComponent(segment);
252
+ }
253
+ function safeParse(text) {
254
+ try {
255
+ const parsed = JSON.parse(text);
256
+ return typeof parsed === 'object' && parsed !== null ? parsed : null;
257
+ }
258
+ catch {
259
+ return null;
260
+ }
261
+ }
262
+ function resolveFetch() {
263
+ const candidate = globalThis.fetch;
264
+ if (typeof candidate !== 'function') {
265
+ throw new Error('DRI: no global fetch was found. Pass one via `new DecentrysDri({ fetch })`.');
266
+ }
267
+ return candidate.bind(globalThis);
268
+ }
269
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from './model';
2
+ export * from './client';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./model"), exports);
18
+ __exportStar(require("./client"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,2CAAyB"}