@decentrys/protect 0.1.0 → 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.
Files changed (2) hide show
  1. package/README.md +153 -39
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,14 +1,18 @@
1
1
  # @decentrys/protect
2
2
 
3
- Evidence-based on-chain risk assessment for wallets and dapps.
3
+ **Tells a user what a transaction actually does, before they sign it — without calling every new project a scam.**
4
+
5
+ You give it a pending transaction, a contract, a token or an address. It returns
6
+ observed facts, what the code *can* do, any threat signals with the evidence
7
+ behind them, and an explicit list of what it could not determine. Your app
8
+ decides what to do with that.
4
9
 
5
10
  > **Lack of evidence is not evidence of malice.**
6
11
  >
7
12
  > A contract deployed two hours ago by an anonymous wallet with no audit and
8
- > thin liquidity is *unknown*, not dangerous. Scoring those facts as risk
9
- > produces a system that protects incumbents and taxes every new project a
10
- > gatekeeping product wearing a security product's clothes. Decentrys refuses
11
- > to do that, and there is no code path by which newness can raise a risk
13
+ > thin liquidity is *unknown*, not dangerous. Most tooling scores those facts as
14
+ > risk, which taxes every new project and protects incumbents. There is no code
15
+ > path in this package by which newness, anonymity or obscurity can raise a risk
12
16
  > level.
13
17
 
14
18
  ## Install
@@ -17,66 +21,176 @@ Evidence-based on-chain risk assessment for wallets and dapps.
17
21
  npm install @decentrys/protect
18
22
  ```
19
23
 
20
- ## Use
24
+ Zero dependencies. Works in Node 18+, browsers, extensions and React Native.
25
+
26
+ ## Getting an API key
27
+
28
+ Sign in at [decentrys.com/developers](https://decentrys.com/developers) and create a key.
29
+
30
+ There are two kinds, and picking the wrong one is the mistake that matters:
31
+
32
+ | Prefix | Where it belongs | Why |
33
+ |---|---|---|
34
+ | `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. |
35
+ | `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. |
36
+
37
+ ## Quick start
21
38
 
22
39
  ```ts
23
40
  import { Decentrys } from '@decentrys/protect';
24
41
 
25
- const decentrys = new Decentrys({ apiKey: 'dk_pub_live_...' });
42
+ const decentrys = new Decentrys({
43
+ apiKey: 'dk_pub_live_...',
44
+ failMode: 'warn', // what to do if Decentrys is unreachable
45
+ timeoutMs: 4000, // a deadline, not a target
46
+ });
26
47
 
27
- const { assessment, decision } = await decentrys.assessTransaction({
48
+ const result = await decentrys.assessTransaction({
28
49
  chain: 'ethereum',
29
50
  from: userAddress,
30
51
  to: contractAddress,
31
52
  data: calldata,
32
53
  });
54
+ ```
33
55
 
34
- assessment.riskLevel // 'CAUTION'
35
- assessment.explanation // why, in words you can show a user
36
- assessment.threatSignals // each with its evidence, confidence and hop distance
37
- assessment.facts // observed, never accusatory
38
- decision.action // what *your* policy says to do
56
+ ## What you get back
57
+
58
+ ```jsonc
59
+ {
60
+ "assessment": {
61
+ "riskLevel": "CAUTION",
62
+ "confirmedMalicious": false,
63
+ "confidence": 0.7,
64
+ "historyStatus": "LIMITED",
65
+
66
+ // Directly verifiable. Carry no accusation.
67
+ "facts": [
68
+ { "type": "DEPLOYED_AT", "statement": "The contract was deployed on 2026-09-04." }
69
+ ],
70
+
71
+ // What the code CAN do. A capability is not a vulnerability.
72
+ "capabilities": [
73
+ { "type": "UPGRADEABLE", "severity": "SIGNIFICANT",
74
+ "statement": "The contract is a proxy: whoever holds its upgrade rights can replace its logic after you approve it." }
75
+ ],
76
+
77
+ // The only thing that can raise a risk level. Each carries its evidence.
78
+ "threatSignals": [],
79
+
80
+ // Stated, never silently omitted.
81
+ "unknowns": [
82
+ { "field": "simulation", "reason": "INSUFFICIENT_DATA",
83
+ "statement": "The transaction was not simulated, so its effect on balances is not known here." }
84
+ ],
85
+
86
+ "explanation": ["The contract is a proxy: ...", "Little history is available yet. This is normal ..."]
87
+ },
88
+ "decision": { "action": "warn", "reason": "..." }
89
+ }
39
90
  ```
40
91
 
41
- ## Two properties worth knowing
92
+ ## Wiring it into a wallet
93
+
94
+ ```ts
95
+ // 1. Before showing the signing screen
96
+ const { assessment, decision } = await decentrys.assessTransaction(tx);
97
+
98
+ // 2. Show what it does, in words
99
+ const explained = await decentrys.explainTransaction(tx);
100
+ // explained.summary -> "Grant 0x1111… unlimited permission to spend the token at 0xabc… from your wallet."
101
+ // explained.exposure -> ["0x1111… will be able to move this token out of your wallet at any time, ..."]
102
+
103
+ // 3. Act on YOUR policy, not ours
104
+ switch (decision.action) {
105
+ case 'allow': return sign();
106
+ case 'inform': return showDetails(assessment);
107
+ case 'warn':
108
+ case 'warn_strong': return showWarning(assessment);
109
+ case 'require_confirmation': return showWarning(assessment, { requireTypedConfirm: true });
110
+ case 'block': return refuse(assessment);
111
+ }
112
+ ```
113
+
114
+ Render it with [`@decentrys/ui-sdk`](https://www.npmjs.com/package/@decentrys/ui-sdk) if you don't want to build the UI yourself.
115
+
116
+ ## Every method
117
+
118
+ | Method | Answers |
119
+ |---|---|
120
+ | `assessTransaction(tx)` | Is this transaction worth warning about? |
121
+ | `explainTransaction(tx)` | What does it actually do, in plain language? |
122
+ | `simulateTransaction(tx)` | What would change if I signed it? |
123
+ | `scanContract({chain,address})` | What can this contract do — upgrade, mint, pause, freeze? |
124
+ | `screenToken({chain,address})` | What is this token, and what powers does it hold? |
125
+ | `screenAddress({chain,address})` | What is known about this address? |
126
+ | `screenApproval({chain,owner,spender,token,amount})` | What am I granting, and to whom? |
127
+ | `assessDapp({origin})` | Is this site reported phishing infrastructure? |
128
+ | `getThreatSignals({chain,address})` | Signals only, for your own presentation. |
42
129
 
43
- **It never throws.** This runs between a user and a signing screen. A security
44
- service having a bad minute must not cost someone their transaction, so an
45
- unreachable Decentrys returns an assessment that says exactly that in its
46
- `unknowns` never a reassuring result it did not earn.
130
+ ## Two guarantees
131
+
132
+ **It never throws.** This runs between a user and a signing screen. If Decentrys
133
+ is unreachable you get an assessment saying exactly that in `unknowns`, with
134
+ `confidence: 0` — never a reassuring result it didn't earn, and never an
135
+ exception your wallet has to catch.
136
+
137
+ ```ts
138
+ const { assessment } = await decentrys.screenAddress({ chain: 'ethereum', address });
139
+ if (assessment.unknowns.some(u => u.reason === 'PROVIDER_UNAVAILABLE')) {
140
+ // Nothing was checked. Say so; don't show a green tick.
141
+ }
142
+ ```
47
143
 
48
144
  **It never blocks.** Decentrys returns intelligence; your policy decides. The
49
- default blocks only `KNOWN_MALICIOUS`, which requires analyst-verified
50
- evidence because it is the one output that accuses a third party.
145
+ default blocks only `KNOWN_MALICIOUS`, which requires analyst-verified evidence
146
+ because it's the one output that accuses a third party.
147
+
148
+ ```ts
149
+ new Decentrys({ apiKey, policy: { HIGH_RISK: 'block', CAUTION: 'inform' } });
150
+ ```
51
151
 
52
152
  ## Risk levels
53
153
 
54
- Seven, not safe/scam. `NO_CRITICAL_RISK_DETECTED` · `INFORMATIONAL` ·
55
- `CAUTION` · `ELEVATED_RISK` · `HIGH_RISK` · `CRITICAL_THREAT` ·
56
- `KNOWN_MALICIOUS`. Capabilities can reach `CAUTION`; only threat signals with
57
- evidence go past it.
154
+ `NO_CRITICAL_RISK_DETECTED` · `INFORMATIONAL` · `CAUTION` · `ELEVATED_RISK` ·
155
+ `HIGH_RISK` · `CRITICAL_THREAT` · `KNOWN_MALICIOUS`
58
156
 
59
- `historyStatus: 'LIMITED'` is the correct, expected state for anything
60
- recently deployed. It measures *our* coverage, never the subject's danger, and
61
- must not be rendered as a warning.
157
+ Capabilities can reach `CAUTION`. Only threat signals with evidence go past it.
158
+ `RISK_LEVEL_MEANING[level]` gives wording safe to show a user.
62
159
 
63
- ## Browser
160
+ **`historyStatus: 'LIMITED'` is not a warning.** It measures how much *Decentrys*
161
+ knows, never the subject's danger, and is the correct state for anything
162
+ recently deployed. Render it neutrally.
64
163
 
65
- Ships an ESM and an IIFE bundle with zero dependencies, for extensions and
66
- pages with a strict CSP: `@decentrys/protect/browser`, global
67
- `DecentrysProtect`.
164
+ ## Browsers and extensions
68
165
 
69
- ## The tests are part of the argument
166
+ ```html
167
+ <script src="node_modules/@decentrys/protect/dist/browser/decentrys-protect.js"></script>
168
+ <script>const d = new DecentrysProtect.Decentrys({ apiKey: 'dk_pub_live_...' });</script>
169
+ ```
170
+
171
+ ESM at `@decentrys/protect/browser`. Both bundles are dependency-free, for
172
+ pages with a strict CSP.
173
+
174
+ ## Read the tests
70
175
 
71
- `src/classify.test.ts` encodes the cases that must never regress — including
72
- that a brand-new unaudited contract with an anonymous deployer is
73
- `INFORMATIONAL`, not a threat. They ship with the package. Read them.
176
+ `src/classify.test.ts` ships with the package and encodes the cases that must
177
+ never regress — including that a brand-new unaudited contract from an anonymous
178
+ deployer is `INFORMATIONAL`, not a threat. You don't have to take the claim on
179
+ trust.
180
+
181
+ ## The rest of the SDK
182
+
183
+ | Package | For |
184
+ |---|---|
185
+ | [`@decentrys/protect`](https://www.npmjs.com/package/@decentrys/protect) | Pre-sign risk assessment for wallets and dapps |
186
+ | [`@decentrys/ui-sdk`](https://www.npmjs.com/package/@decentrys/ui-sdk) | React components that render Protect results |
187
+ | [`@decentrys/sentinel-sdk`](https://www.npmjs.com/package/@decentrys/sentinel-sdk) | Monitoring deployed contracts and treasuries |
188
+ | [`@decentrys/risk-sdk`](https://www.npmjs.com/package/@decentrys/risk-sdk) | Screening for exchanges and custodians |
189
+ | [`@decentrys/dri-sdk`](https://www.npmjs.com/package/@decentrys/dri-sdk) | Fund tracing and recovery intelligence |
190
+ | [`@decentrys/agent`](https://www.npmjs.com/package/@decentrys/agent) | Policy enforcement for autonomous agents |
74
191
 
75
192
  ## Licence
76
193
 
77
194
  MIT © Decentrys Labs
78
195
 
79
- ## Links
80
-
81
- - [decentrys.com](https://decentrys.com) · [SDK overview](https://decentrys.com/sdk) · [Developer API](https://decentrys.com/developers)
82
- - Source: [github.com/teamdecentrys-byte/Decentrys](https://github.com/teamdecentrys-byte/Decentrys)
196
+ [decentrys.com](https://decentrys.com) · [SDK overview](https://decentrys.com/sdk) · [Developer API](https://decentrys.com/developers) · [Source](https://github.com/teamdecentrys-byte/Decentrys)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decentrys/protect",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Evidence-based on-chain risk assessment for wallets and dapps. Unknown is neutral, risk requires evidence, and nothing is ever called a scam without one.",
5
5
  "license": "MIT",
6
6
  "author": "Decentrys Labs",