@decentrys/dri-sdk 0.1.1 → 0.1.2
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 +167 -41
- package/dist/browser/decentrys-dri.js +1 -1
- package/dist/browser/decentrys-dri.mjs +1 -1
- package/dist/client.d.ts +8 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +14 -6
- package/dist/client.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +14 -6
package/README.md
CHANGED
|
@@ -9,10 +9,10 @@ a court — becomes reachable.
|
|
|
9
9
|
|
|
10
10
|
## What this is not
|
|
11
11
|
|
|
12
|
-
- Decentrys **never takes custody** of assets, and does not freeze, seize, transmit or return anything.
|
|
12
|
+
- Decentrys **never takes custody** of assets, and does not freeze, seize, transmit or return anything. Nothing in this package can be called to move value.
|
|
13
13
|
- It is **not a law firm, law enforcement agency, or licensed recovery agent.** Nothing here is legal advice.
|
|
14
14
|
- The **Recovery Index is an analytical estimate** from a versioned model. Not a prediction, guarantee, or promised recovery rate.
|
|
15
|
-
- Attribution beyond a mixer is **inference, and labelled as inference
|
|
15
|
+
- Attribution beyond a mixer is **inference, and labelled as inference** — `observedPath: false` on every point that reaches you through obfuscation.
|
|
16
16
|
- Sold to organisations. Not a consumer service.
|
|
17
17
|
|
|
18
18
|
## Install
|
|
@@ -21,92 +21,218 @@ a court — becomes reachable.
|
|
|
21
21
|
npm install @decentrys/dri-sdk
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
+
Zero runtime dependencies. Node 18+. Types included.
|
|
25
|
+
|
|
24
26
|
## Getting an API key
|
|
25
27
|
|
|
26
28
|
Sign in at [decentrys.com/developers](https://decentrys.com/developers) and create a key.
|
|
27
29
|
|
|
28
|
-
There are two kinds, and picking the wrong one is the mistake that matters:
|
|
29
|
-
|
|
30
30
|
| Prefix | Where it belongs | Why |
|
|
31
31
|
|---|---|---|
|
|
32
32
|
| `dk_pub_live_…` | **Publishable.** Ships inside a wallet, extension or mobile app. | Bounded to the origins you register and to read-only Protect endpoints. Anyone can extract it from your bundle; that's expected, and it's why it can't do anything dangerous. |
|
|
33
33
|
| `dk_live_…` | **Secret.** Server-side only. | Full scope access. If this ends up in a client bundle it is a leaked credential the moment it ships. |
|
|
34
34
|
|
|
35
|
-
**Secret key only
|
|
35
|
+
**Secret key only.** A key beginning `dk_pub_` throws at construction — an
|
|
36
|
+
investigation names third parties, and that must never run behind a credential
|
|
37
|
+
anyone who downloads your app can read.
|
|
36
38
|
|
|
37
39
|
## Quick start
|
|
38
40
|
|
|
39
41
|
```ts
|
|
40
|
-
import { DecentrysDri,
|
|
42
|
+
import { DecentrysDri, custodialPoints, inferredPoints } from '@decentrys/dri-sdk';
|
|
41
43
|
|
|
42
|
-
const dri = new DecentrysDri({ apiKey:
|
|
44
|
+
const dri = new DecentrysDri({ apiKey: process.env.DECENTRYS_API_KEY! });
|
|
43
45
|
|
|
44
|
-
// 1.
|
|
45
|
-
|
|
46
|
+
// 1. Open the case, seeded on where the funds went. Nothing is traced yet —
|
|
47
|
+
// the seed node exists so the graph has a root even if a provider is down.
|
|
48
|
+
const graph = await dri.createInvestigation({
|
|
46
49
|
title: 'Vault drain 2026-09-04',
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
maxHops: 4,
|
|
50
|
+
chain: 'ethereum',
|
|
51
|
+
address: '0xattacker…',
|
|
52
|
+
maxHops: 4, // 1-4
|
|
50
53
|
});
|
|
51
54
|
|
|
52
|
-
//
|
|
53
|
-
|
|
55
|
+
graph.investigationId // ← the handle every other call takes
|
|
56
|
+
graph.caseRef
|
|
57
|
+
graph.recoveryCaseId // string | null — null means no tranche ledger yet
|
|
58
|
+
graph.nodes // FlowNode[]
|
|
59
|
+
graph.edges // FlowEdge[]
|
|
60
|
+
graph.notes // caveats that ship with the result
|
|
61
|
+
|
|
62
|
+
// 2. Follow the value. One address, one hop, per call.
|
|
63
|
+
const trace = await dri.traceFunds({ investigationId: graph.investigationId });
|
|
64
|
+
|
|
65
|
+
trace.fromNodeId // which address was expanded
|
|
66
|
+
trace.addressesDiscovered
|
|
67
|
+
trace.transfersRecorded
|
|
68
|
+
trace.coverage?.truncated // true when the trace stopped short of the frontier
|
|
69
|
+
trace.graph // the graph as it now stands
|
|
54
70
|
|
|
55
71
|
// 3. Where can someone act?
|
|
56
|
-
const
|
|
72
|
+
const analysis = await dri.identifyInterventionPoints(graph.investigationId);
|
|
57
73
|
```
|
|
58
74
|
|
|
75
|
+
`createInvestigation` takes `chain` and `address` — not `seedChain`/
|
|
76
|
+
`seedAddress` — and returns a `FlowGraph` whose id field is
|
|
77
|
+
**`investigationId`**, not `id`.
|
|
78
|
+
|
|
59
79
|
Tracing is one hop at a time on purpose. Public RPC endpoints are rate-limited,
|
|
60
80
|
and an exhausted quota reads as *"the funds vanished"* rather than *"we ran out
|
|
61
|
-
of budget"*.
|
|
62
|
-
|
|
63
|
-
## Intervention points
|
|
81
|
+
of budget"*. Call it in a loop for depth, and read `coverage.truncated` each
|
|
82
|
+
time:
|
|
64
83
|
|
|
65
84
|
```ts
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
85
|
+
for (let i = 0; i < 20; i += 1) {
|
|
86
|
+
const step = await dri.traceFunds({ investigationId: graph.investigationId });
|
|
87
|
+
if (step.coverage?.truncated) {
|
|
88
|
+
console.warn(step.coverage.truncationReason);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
if (step.addressesDiscovered === 0) break;
|
|
92
|
+
}
|
|
69
93
|
```
|
|
70
94
|
|
|
71
|
-
|
|
95
|
+
Pass `fromNodeId` to choose the address yourself. Omit it and the shallowest
|
|
96
|
+
unexpanded node is taken, which keeps the graph anchored in what was directly
|
|
97
|
+
traced.
|
|
72
98
|
|
|
73
|
-
##
|
|
99
|
+
## Intervention points
|
|
100
|
+
|
|
101
|
+
`identifyInterventionPoints` returns an `InterventionAnalysis` with three
|
|
102
|
+
lists — not `custodial`/`crossChain`/`obfuscation` properties. The
|
|
103
|
+
custodial/cross-chain split lives on each point's `kind`:
|
|
74
104
|
|
|
75
105
|
```ts
|
|
76
|
-
|
|
106
|
+
// A party HOLDS the value — contactable, serveable, subpoenable.
|
|
107
|
+
for (const point of custodialPoints(analysis)) { // kind === 'CUSTODIAL'
|
|
108
|
+
point.entityName ?? point.label;
|
|
109
|
+
point.address;
|
|
110
|
+
point.hop;
|
|
111
|
+
point.basis; // why it is on the list, in the terms it may be stated
|
|
112
|
+
point.observedPath; // false ⇒ the link runs through mixing: inference
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// A bridge operator holds RECORDS of value that has already moved on.
|
|
116
|
+
const crossChain = analysis.interventionPoints.filter((p) => p.kind === 'CROSS_CHAIN');
|
|
117
|
+
|
|
118
|
+
// Where provable attribution stops. Mixing and privacy infrastructure.
|
|
119
|
+
analysis.attributionLimits; // [{ nodeId, chain, address, nodeType, hop, reason }]
|
|
120
|
+
|
|
121
|
+
// Frontier addresses nobody has looked past yet.
|
|
122
|
+
analysis.unexplored;
|
|
77
123
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
index.analyticalOnly // always true
|
|
81
|
-
index.disclaimer // must be shown wherever the score is
|
|
124
|
+
// The points connected to this case by inference rather than an observed transfer.
|
|
125
|
+
inferredPoints(analysis); // observedPath === false
|
|
82
126
|
```
|
|
83
127
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
128
|
+
Collapsing custodial and cross-chain sends legal budget after a paper trail. A
|
|
129
|
+
case that reaches an attribution limit has established an answer, not failed.
|
|
130
|
+
|
|
131
|
+
## Recovery Index
|
|
132
|
+
|
|
133
|
+
`getRecoveryIndex` takes a **`recoveryCaseId`**, which you get from
|
|
134
|
+
`listCases()` or from `graph.recoveryCaseId`.
|
|
88
135
|
|
|
89
136
|
```ts
|
|
137
|
+
import { MissingDisclosureError } from '@decentrys/dri-sdk';
|
|
138
|
+
|
|
139
|
+
const [openCase] = await dri.listCases();
|
|
140
|
+
|
|
90
141
|
try {
|
|
91
|
-
const index = await dri.getRecoveryIndex(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
142
|
+
const index = await dri.getRecoveryIndex(openCase.recoveryCaseId);
|
|
143
|
+
|
|
144
|
+
index.score; // 0-100
|
|
145
|
+
index.band; // 'HIGH' | 'MODERATE' | 'LOW' | 'VERY_LOW'
|
|
146
|
+
index.bandMeaning; // stated as a situation, never as a likelihood
|
|
147
|
+
index.factors; // [{ factor, contribution, note }] — the number, explained
|
|
148
|
+
index.funnel; // located / at-intervention-point / frozen / recovered / …
|
|
149
|
+
index.analyticalOnly; // always true
|
|
150
|
+
index.disclaimer; // must be shown wherever the score is
|
|
151
|
+
index.modelVersion;
|
|
152
|
+
index.inputsHash; // with modelVersion, makes any figure reproducible
|
|
153
|
+
|
|
154
|
+
render(index.score, index.band, index.disclaimer); // never a score without its caveat
|
|
155
|
+
} catch (error) {
|
|
156
|
+
if (error instanceof MissingDisclosureError) {
|
|
157
|
+
// The score arrived unlabelled. Do not render a bare number.
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
throw error;
|
|
95
161
|
}
|
|
96
162
|
```
|
|
97
163
|
|
|
164
|
+
The client refuses a Recovery Index that arrives without `analyticalOnly: true`
|
|
165
|
+
and a non-empty `disclaimer` — `assertAnalyticalDisclosure` is exported if you
|
|
166
|
+
want to apply the same check to a payload of your own.
|
|
167
|
+
`MissingDisclosureError` is a distinct class from `DriError`, so a
|
|
168
|
+
retry-on-transport-error loop can't swallow it. A dashboard renders whatever
|
|
169
|
+
arrives, and "58 — MODERATE" beside the word *recovery* is read as a rate.
|
|
170
|
+
|
|
98
171
|
## Evidence packages
|
|
99
172
|
|
|
173
|
+
**Prepared, not sent.** Decentrys does not contact counterparties on your
|
|
174
|
+
behalf unless instructed.
|
|
175
|
+
|
|
100
176
|
```ts
|
|
101
|
-
const pkg = await dri.generateEvidencePackage(
|
|
102
|
-
|
|
177
|
+
const pkg = await dri.generateEvidencePackage({
|
|
178
|
+
recoveryCaseId: openCase.recoveryCaseId,
|
|
179
|
+
recipientType: 'EXCHANGE', // 'EXCHANGE' | 'ISSUER' | 'LAW_ENFORCEMENT' | 'COUNSEL'
|
|
180
|
+
recipientName: 'Example Exchange Ltd',
|
|
181
|
+
// recoveryLeadId: '…' // narrows the package to one destination
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
pkg.content; // the document, as plain text
|
|
185
|
+
pkg.contentHash; // SHA-256 of content — quote it back to verify what a recipient holds
|
|
186
|
+
pkg.authorityNotice; // the standing non-authority statement on the face of the document
|
|
187
|
+
pkg.transmitted; // always false on a package this SDK created
|
|
103
188
|
```
|
|
104
189
|
|
|
190
|
+
The document is frozen and hashed at generation, so a reader months later can
|
|
191
|
+
confirm they hold what was produced. A later version is a new document, not a
|
|
192
|
+
revision of this one.
|
|
193
|
+
|
|
105
194
|
## Every method
|
|
106
195
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
`
|
|
196
|
+
| Method | Returns |
|
|
197
|
+
|---|---|
|
|
198
|
+
| `createInvestigation({title, chain, address, incidentId?, maxHops?})` | `FlowGraph` |
|
|
199
|
+
| `listInvestigations(limit?)` | `InvestigationSummary[]` |
|
|
200
|
+
| `traceFunds({investigationId, fromNodeId?})` | `TraceResult` |
|
|
201
|
+
| `getFlowGraph(investigationId)` | `FlowGraph` |
|
|
202
|
+
| `identifyInterventionPoints(investigationId)` | `InterventionAnalysis` |
|
|
203
|
+
| `getInvestigationTimeline(investigationId, limit?)` | `InvestigationTimeline` |
|
|
204
|
+
| `listCases(limit?)` | `RecoveryCaseSummary[]` |
|
|
205
|
+
| `getRecoveryIndex(recoveryCaseId)` | `RecoveryIndex` |
|
|
206
|
+
| `generateEvidencePackage({recoveryCaseId, recipientType, recipientName, recoveryLeadId?})` | `EvidencePackage` |
|
|
207
|
+
|
|
208
|
+
Helpers: `custodialPoints(analysis)` · `inferredPoints(analysis)` ·
|
|
209
|
+
`assertAnalyticalDisclosure(index)` · `RECOVERY_BANDS`.
|
|
210
|
+
|
|
211
|
+
Every timeline entry carries `actorParty` as a required field. An entry saying
|
|
212
|
+
value "became frozen" with no named actor would be an implied claim of standing
|
|
213
|
+
Decentrys does not have.
|
|
214
|
+
|
|
215
|
+
## It throws
|
|
216
|
+
|
|
217
|
+
Nothing here is on a signing path. A trace that quietly returned an empty graph
|
|
218
|
+
when the service was unreachable would tell a responder the value had vanished
|
|
219
|
+
at the moment it was still moving — a failure invisible by construction.
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
import { DriError } from '@decentrys/dri-sdk';
|
|
223
|
+
|
|
224
|
+
try {
|
|
225
|
+
await dri.traceFunds({ investigationId });
|
|
226
|
+
} catch (error) {
|
|
227
|
+
if (error instanceof DriError) console.error(error.status, error.code, error.message);
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
`DriError` carries `status` (`0` for a timeout or network failure) and the
|
|
232
|
+
API's own `code` and `message`. The default deadline is 30 seconds — a trace
|
|
233
|
+
expands one address against rate-limited public endpoints, and the graph is
|
|
234
|
+
persisted server-side, so a timed-out trace is re-readable rather than lost.
|
|
235
|
+
Configure with `new DecentrysDri({ apiKey, timeoutMs, baseUrl, fetch })`.
|
|
110
236
|
|
|
111
237
|
## The rest of the SDK
|
|
112
238
|
|
package/dist/client.d.ts
CHANGED
|
@@ -32,7 +32,14 @@
|
|
|
32
32
|
* law-enforcement agency or a licensed recovery agent.
|
|
33
33
|
*/
|
|
34
34
|
import { type EvidencePackage, type EvidenceRecipientType, type FlowGraph, type InterventionAnalysis, type InvestigationSummary, type InvestigationTimeline, type RecoveryCaseSummary, type RecoveryIndex, type TraceResult } from './model';
|
|
35
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Sent in the user-agent on every request.
|
|
37
|
+
*
|
|
38
|
+
* Kept in step with package.json by hand — it drifted once already, and a
|
|
39
|
+
* stale value here silently under-reports the real version in server-side
|
|
40
|
+
* telemetry rather than failing in any visible way.
|
|
41
|
+
*/
|
|
42
|
+
export declare const SDK_VERSION = "0.1.2";
|
|
36
43
|
export type FetchLike = (url: string, init: {
|
|
37
44
|
method: string;
|
|
38
45
|
headers: Record<string, string>;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -35,14 +35,22 @@
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.DecentrysDri = exports.DriError = exports.SDK_VERSION = void 0;
|
|
37
37
|
const model_1 = require("./model");
|
|
38
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Sent in the user-agent on every request.
|
|
40
|
+
*
|
|
41
|
+
* Kept in step with package.json by hand — it drifted once already, and a
|
|
42
|
+
* stale value here silently under-reports the real version in server-side
|
|
43
|
+
* telemetry rather than failing in any visible way.
|
|
44
|
+
*/
|
|
45
|
+
exports.SDK_VERSION = '0.1.2';
|
|
39
46
|
const DEFAULT_BASE_URL = 'https://api.decentrys.com';
|
|
40
47
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
48
|
+
* Thirty seconds — deliberately longer than the other clients.
|
|
49
|
+
*
|
|
50
|
+
* A trace expands one address against rate-limited public endpoints, so it is
|
|
51
|
+
* the slowest call here by some margin. A client that waits indefinitely is a
|
|
52
|
+
* client that hangs, and the graph is persisted server-side either way, so a
|
|
53
|
+
* timed-out trace is re-readable rather than lost.
|
|
46
54
|
*/
|
|
47
55
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
48
56
|
class DriError extends Error {
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;;;AAEH,mCAKiB;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decentrys/dri-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Digital Recovery Intelligence: fund tracing, attribution, intervention points and evidence packages. Analytical only — Decentrys never takes custody of assets.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Decentrys Labs",
|
package/src/client.ts
CHANGED
|
@@ -39,16 +39,24 @@ import {
|
|
|
39
39
|
type RecoveryIndex, type TraceResult,
|
|
40
40
|
} from './model';
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Sent in the user-agent on every request.
|
|
44
|
+
*
|
|
45
|
+
* Kept in step with package.json by hand — it drifted once already, and a
|
|
46
|
+
* stale value here silently under-reports the real version in server-side
|
|
47
|
+
* telemetry rather than failing in any visible way.
|
|
48
|
+
*/
|
|
49
|
+
export const SDK_VERSION = '0.1.2';
|
|
43
50
|
|
|
44
51
|
const DEFAULT_BASE_URL = 'https://api.decentrys.com';
|
|
45
52
|
|
|
46
53
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
54
|
+
* Thirty seconds — deliberately longer than the other clients.
|
|
55
|
+
*
|
|
56
|
+
* A trace expands one address against rate-limited public endpoints, so it is
|
|
57
|
+
* the slowest call here by some margin. A client that waits indefinitely is a
|
|
58
|
+
* client that hangs, and the graph is persisted server-side either way, so a
|
|
59
|
+
* timed-out trace is re-readable rather than lost.
|
|
52
60
|
*/
|
|
53
61
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
54
62
|
|