@decentrys/ui-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.
Files changed (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +51 -0
  3. package/dist/browser/decentrys-ui.js +1733 -0
  4. package/dist/browser/decentrys-ui.mjs +1681 -0
  5. package/dist/browser/react-dom-global.d.ts +6 -0
  6. package/dist/browser/react-dom-global.d.ts.map +1 -0
  7. package/dist/browser/react-dom-global.js +18 -0
  8. package/dist/browser/react-dom-global.js.map +1 -0
  9. package/dist/browser/react-global.d.ts +25 -0
  10. package/dist/browser/react-global.d.ts.map +1 -0
  11. package/dist/browser/react-global.js +39 -0
  12. package/dist/browser/react-global.js.map +1 -0
  13. package/dist/browser/react-jsx-runtime.d.ts +17 -0
  14. package/dist/browser/react-jsx-runtime.d.ts.map +1 -0
  15. package/dist/browser/react-jsx-runtime.js +27 -0
  16. package/dist/browser/react-jsx-runtime.js.map +1 -0
  17. package/dist/components/AddressRiskBadge.d.ts +39 -0
  18. package/dist/components/AddressRiskBadge.d.ts.map +1 -0
  19. package/dist/components/AddressRiskBadge.js +26 -0
  20. package/dist/components/AddressRiskBadge.js.map +1 -0
  21. package/dist/components/ApprovalWarning.d.ts +29 -0
  22. package/dist/components/ApprovalWarning.d.ts.map +1 -0
  23. package/dist/components/ApprovalWarning.js +18 -0
  24. package/dist/components/ApprovalWarning.js.map +1 -0
  25. package/dist/components/ContractFacts.d.ts +27 -0
  26. package/dist/components/ContractFacts.d.ts.map +1 -0
  27. package/dist/components/ContractFacts.js +15 -0
  28. package/dist/components/ContractFacts.js.map +1 -0
  29. package/dist/components/RiskDetailsModal.d.ts +35 -0
  30. package/dist/components/RiskDetailsModal.d.ts.map +1 -0
  31. package/dist/components/RiskDetailsModal.js +74 -0
  32. package/dist/components/RiskDetailsModal.js.map +1 -0
  33. package/dist/components/ThreatSignalList.d.ts +28 -0
  34. package/dist/components/ThreatSignalList.d.ts.map +1 -0
  35. package/dist/components/ThreatSignalList.js +28 -0
  36. package/dist/components/ThreatSignalList.js.map +1 -0
  37. package/dist/components/TokenSecurityPanel.d.ts +28 -0
  38. package/dist/components/TokenSecurityPanel.d.ts.map +1 -0
  39. package/dist/components/TokenSecurityPanel.js +26 -0
  40. package/dist/components/TokenSecurityPanel.js.map +1 -0
  41. package/dist/components/TransactionRiskBanner.d.ts +36 -0
  42. package/dist/components/TransactionRiskBanner.d.ts.map +1 -0
  43. package/dist/components/TransactionRiskBanner.js +20 -0
  44. package/dist/components/TransactionRiskBanner.js.map +1 -0
  45. package/dist/context.d.ts +51 -0
  46. package/dist/context.d.ts.map +1 -0
  47. package/dist/context.js +47 -0
  48. package/dist/context.js.map +1 -0
  49. package/dist/copy.d.ts +72 -0
  50. package/dist/copy.d.ts.map +1 -0
  51. package/dist/copy.js +77 -0
  52. package/dist/copy.js.map +1 -0
  53. package/dist/index.d.ts +57 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +107 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/presentation.d.ts +316 -0
  58. package/dist/presentation.d.ts.map +1 -0
  59. package/dist/presentation.js +533 -0
  60. package/dist/presentation.js.map +1 -0
  61. package/dist/primitives.d.ts +139 -0
  62. package/dist/primitives.d.ts.map +1 -0
  63. package/dist/primitives.js +150 -0
  64. package/dist/primitives.js.map +1 -0
  65. package/dist/styles.d.ts +15 -0
  66. package/dist/styles.d.ts.map +1 -0
  67. package/dist/styles.js +285 -0
  68. package/dist/styles.js.map +1 -0
  69. package/dist/theme.d.ts +52 -0
  70. package/dist/theme.d.ts.map +1 -0
  71. package/dist/theme.js +90 -0
  72. package/dist/theme.js.map +1 -0
  73. package/package.json +70 -0
  74. package/src/browser/react-dom-global.ts +20 -0
  75. package/src/browser/react-global.ts +42 -0
  76. package/src/browser/react-jsx-runtime.ts +23 -0
  77. package/src/components/AddressRiskBadge.tsx +94 -0
  78. package/src/components/ApprovalWarning.tsx +144 -0
  79. package/src/components/ContractFacts.tsx +119 -0
  80. package/src/components/RiskDetailsModal.tsx +229 -0
  81. package/src/components/ThreatSignalList.tsx +76 -0
  82. package/src/components/TokenSecurityPanel.tsx +168 -0
  83. package/src/components/TransactionRiskBanner.tsx +123 -0
  84. package/src/context.tsx +89 -0
  85. package/src/copy.test.ts +214 -0
  86. package/src/copy.ts +151 -0
  87. package/src/index.ts +84 -0
  88. package/src/presentation.test.ts +521 -0
  89. package/src/presentation.ts +846 -0
  90. package/src/primitives.tsx +384 -0
  91. package/src/styles.ts +281 -0
  92. package/src/theme.test.ts +105 -0
  93. package/src/theme.ts +117 -0
@@ -0,0 +1,533 @@
1
+ "use strict";
2
+ /**
3
+ * Where the risk model becomes words a person reads.
4
+ *
5
+ * This file is pure. It takes an `Assessment` and returns descriptions —
6
+ * labels, tones, statements, aria strings — and renders nothing. That split is
7
+ * deliberate: the rule
8
+ *
9
+ * Unknown is neutral. Risk requires evidence. Malicious requires stronger
10
+ * evidence. Users should be shown why.
11
+ *
12
+ * is broken in *presentation*, not in markup. A component that paints
13
+ * "deployed 3 days ago" the same amber as "attributed to a drainer family" has
14
+ * defeated the entire model while passing every classifier test. So the
15
+ * decisions that could do that live here, in functions a test can call
16
+ * directly, rather than being spread across seven components where they can
17
+ * only be checked by eye.
18
+ *
19
+ * Four load-bearing choices:
20
+ *
21
+ * - **Kinds have their own tone families.** `fact`, `capability` and
22
+ * `unknown` are not points on the risk scale. They cannot be rendered in a
23
+ * severity colour because they are never handed one.
24
+ * - **`HistoryPresentation.tone` is the literal type `'neutral'` and
25
+ * `isWarning` is the literal type `false`.** Limited history being drawn as
26
+ * a warning is not a bug this codebase can have; it does not compile.
27
+ * - **A signal that did not raise the level is toned `inactive`.** A stale or
28
+ * low-confidence signal is still shown — hiding an observation is its own
29
+ * failure — but it is not shown in the colour of one that counted.
30
+ * - **Anything above zero hops says so in a sentence**, not just a badge,
31
+ * because a hop is an inference about a counterparty and a badge reading
32
+ * "2" does not tell anyone that.
33
+ */
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.MIN_RAISING_CONFIDENCE = exports.RISK_LEVEL_LABEL = void 0;
36
+ exports.levelRank = levelRank;
37
+ exports.levelPresentation = levelPresentation;
38
+ exports.kindPresentation = kindPresentation;
39
+ exports.factPresentation = factPresentation;
40
+ exports.capabilityPresentation = capabilityPresentation;
41
+ exports.signalPresentation = signalPresentation;
42
+ exports.hopPresentation = hopPresentation;
43
+ exports.evidencePresentation = evidencePresentation;
44
+ exports.unknownPresentation = unknownPresentation;
45
+ exports.historyPresentation = historyPresentation;
46
+ exports.componentRows = componentRows;
47
+ exports.assessmentSections = assessmentSections;
48
+ exports.availabilityPresentation = availabilityPresentation;
49
+ exports.decisionPresentation = decisionPresentation;
50
+ exports.approvalPresentation = approvalPresentation;
51
+ exports.isUnlimitedAllowance = isUnlimitedAllowance;
52
+ exports.formatConfidence = formatConfidence;
53
+ exports.formatTimestamp = formatTimestamp;
54
+ exports.shortenAddress = shortenAddress;
55
+ exports.formatTokenAmount = formatTokenAmount;
56
+ exports.plural = plural;
57
+ const protect_1 = require("@decentrys/protect");
58
+ Object.defineProperty(exports, "MIN_RAISING_CONFIDENCE", { enumerable: true, get: function () { return protect_1.MIN_RAISING_CONFIDENCE; } });
59
+ // ---------------------------------------------------------------------------
60
+ // Risk levels
61
+ // ---------------------------------------------------------------------------
62
+ /**
63
+ * The labels already published to customers on the marketing site.
64
+ *
65
+ * They are copied rather than invented so that a user who read the pricing
66
+ * page and a user looking at a wallet see the same seven words. Overridable
67
+ * per component for translation; the meanings come from the model itself.
68
+ */
69
+ exports.RISK_LEVEL_LABEL = {
70
+ NO_CRITICAL_RISK_DETECTED: 'No critical risk detected',
71
+ INFORMATIONAL: 'Informational',
72
+ CAUTION: 'Caution',
73
+ ELEVATED_RISK: 'Elevated risk',
74
+ HIGH_RISK: 'High risk',
75
+ CRITICAL_THREAT: 'Critical threat',
76
+ KNOWN_MALICIOUS: 'Known malicious',
77
+ };
78
+ /**
79
+ * A colour-independent ordinal marker.
80
+ *
81
+ * Colour must never be the only thing separating these levels — for a
82
+ * colour-blind user it would be the only thing, and then "informational" and
83
+ * "critical threat" are the same badge. The glyph escalates monotonically and
84
+ * `KNOWN_MALICIOUS`, the one level that accuses, gets a different mark
85
+ * entirely rather than one more exclamation point.
86
+ */
87
+ const LEVEL_GLYPH = {
88
+ NO_CRITICAL_RISK_DETECTED: '·',
89
+ INFORMATIONAL: 'i',
90
+ CAUTION: '!',
91
+ ELEVATED_RISK: '!!',
92
+ HIGH_RISK: '!!!',
93
+ CRITICAL_THREAT: '!!!!',
94
+ KNOWN_MALICIOUS: '✕',
95
+ };
96
+ const LEVEL_TONE = {
97
+ // Neither of these two may look like a warning. Nothing in them indicates
98
+ // danger, and a new project landing on INFORMATIONAL is the common case.
99
+ NO_CRITICAL_RISK_DETECTED: 'neutral',
100
+ INFORMATIONAL: 'info',
101
+ CAUTION: 'caution',
102
+ ELEVATED_RISK: 'elevated',
103
+ HIGH_RISK: 'high',
104
+ CRITICAL_THREAT: 'critical',
105
+ KNOWN_MALICIOUS: 'critical',
106
+ };
107
+ const LEVEL_ORDER = [
108
+ 'NO_CRITICAL_RISK_DETECTED',
109
+ 'INFORMATIONAL',
110
+ 'CAUTION',
111
+ 'ELEVATED_RISK',
112
+ 'HIGH_RISK',
113
+ 'CRITICAL_THREAT',
114
+ 'KNOWN_MALICIOUS',
115
+ ];
116
+ function levelRank(level) {
117
+ return LEVEL_ORDER.indexOf(level);
118
+ }
119
+ function levelPresentation(level, options = {}) {
120
+ const label = options.labels?.[level] ?? exports.RISK_LEVEL_LABEL[level];
121
+ const meaning = protect_1.RISK_LEVEL_MEANING[level];
122
+ const evidenceBacked = levelRank(level) >= levelRank('ELEVATED_RISK');
123
+ return {
124
+ level,
125
+ label,
126
+ meaning,
127
+ tone: LEVEL_TONE[level],
128
+ glyph: LEVEL_GLYPH[level],
129
+ evidenceBacked,
130
+ accusatory: level === 'KNOWN_MALICIOUS',
131
+ liveRegionRole: evidenceBacked ? 'alert' : 'status',
132
+ ariaLabel: `Decentrys assessment: ${label}. ${meaning}`,
133
+ };
134
+ }
135
+ function kindPresentation(kind, copy) {
136
+ switch (kind) {
137
+ case 'fact':
138
+ return { kind, label: copy.factLabel, glyph: '·', tone: 'fact', rule: 'solid', ruleWidth: '2px' };
139
+ case 'capability':
140
+ return { kind, label: copy.capabilityLabel, glyph: '◇', tone: 'capability', rule: 'dashed', ruleWidth: '2px' };
141
+ case 'signal':
142
+ return { kind, label: copy.signalLabel, glyph: '▲', tone: 'critical', rule: 'solid', ruleWidth: '4px' };
143
+ case 'unknown':
144
+ return { kind, label: copy.unknownLabel, glyph: '?', tone: 'unknown', rule: 'dotted', ruleWidth: '2px' };
145
+ }
146
+ }
147
+ function factPresentation(fact) {
148
+ return {
149
+ kind: 'fact',
150
+ statement: fact.statement,
151
+ source: fact.source,
152
+ observedAt: formatTimestamp(fact.observedAt),
153
+ tone: 'fact',
154
+ };
155
+ }
156
+ // ---------------------------------------------------------------------------
157
+ // Capabilities
158
+ // ---------------------------------------------------------------------------
159
+ const CAPABILITY_SEVERITY_LABEL = {
160
+ INFO: 'Standard',
161
+ NOTABLE: 'Notable',
162
+ SIGNIFICANT: 'Significant',
163
+ };
164
+ function capabilityPresentation(capability) {
165
+ return {
166
+ kind: 'capability',
167
+ statement: capability.statement,
168
+ severity: capability.severity,
169
+ severityLabel: CAPABILITY_SEVERITY_LABEL[capability.severity],
170
+ grantedBy: capability.grantedBy,
171
+ tone: 'capability',
172
+ emphasis: capability.severity === 'SIGNIFICANT' ? 'strong' : 'normal',
173
+ };
174
+ }
175
+ const SEVERITY_LABEL = {
176
+ LOW: 'Low',
177
+ MEDIUM: 'Medium',
178
+ HIGH: 'High',
179
+ CRITICAL: 'Critical',
180
+ };
181
+ const SEVERITY_TONE = {
182
+ LOW: 'caution',
183
+ MEDIUM: 'elevated',
184
+ HIGH: 'high',
185
+ CRITICAL: 'critical',
186
+ };
187
+ const SIGNAL_STATUS_LABEL = {
188
+ ACTIVE: 'Active',
189
+ STALE: 'Stale',
190
+ RESOLVED: 'Resolved',
191
+ DISPUTED_FACT: 'Disputed',
192
+ REMOVED: 'Withdrawn',
193
+ };
194
+ function signalPresentation(signal, copy, options = {}) {
195
+ const subject = options.subjectNoun ?? 'address';
196
+ const active = signal.status === 'ACTIVE';
197
+ const raising = active && signal.confidence >= protect_1.MIN_RAISING_CONFIDENCE;
198
+ const statusLabel = SIGNAL_STATUS_LABEL[signal.status];
199
+ const analystConfirmed = signal.evidence.some((e) => e.analystVerified);
200
+ let inertStatement;
201
+ if (!active) {
202
+ inertStatement = `This signal is ${statusLabel.toLowerCase()} and did not affect this assessment.`;
203
+ }
204
+ else if (!raising) {
205
+ inertStatement =
206
+ `Reported at ${formatConfidence(signal.confidence)} confidence, which is too low to raise the risk `
207
+ + 'level on its own. It is shown because it was observed, not because it counted.';
208
+ }
209
+ const hop = hopPresentation(signal.hops, subject);
210
+ return {
211
+ kind: 'signal',
212
+ explanation: signal.explanation,
213
+ severity: signal.severity,
214
+ severityLabel: SEVERITY_LABEL[signal.severity],
215
+ tone: raising ? SEVERITY_TONE[signal.severity] : 'inactive',
216
+ status: signal.status,
217
+ statusLabel,
218
+ active,
219
+ raising,
220
+ inertStatement,
221
+ hops: signal.hops,
222
+ hopLabel: hop.label,
223
+ hopStatement: hop.statement,
224
+ indirect: hop.indirect,
225
+ confidence: signal.confidence,
226
+ confidenceLabel: formatConfidence(signal.confidence),
227
+ analystConfirmed,
228
+ attribution: analystConfirmed ? copy.analystConfirmed : copy.notAnalystConfirmed,
229
+ evidenceCount: signal.evidence.length,
230
+ ariaLabel: `${copy.signalLabel}, ${SEVERITY_LABEL[signal.severity].toLowerCase()} severity, `
231
+ + `${formatConfidence(signal.confidence)} confidence, ${hop.label.toLowerCase()}. ${signal.explanation}`,
232
+ };
233
+ }
234
+ /**
235
+ * Hop distance, in a sentence.
236
+ *
237
+ * Zero hops is an observation about the subject. Everything else is an
238
+ * observation about somebody the subject transacted with, and the further out
239
+ * it goes the weaker the inference — a badge reading "3" communicates none of
240
+ * that, so the wording carries it instead.
241
+ */
242
+ function hopPresentation(hops, subjectNoun = 'address') {
243
+ const n = Math.max(0, Math.trunc(hops));
244
+ if (n === 0) {
245
+ return {
246
+ hops: 0,
247
+ label: 'Direct',
248
+ statement: `Observed directly on this ${subjectNoun}.`,
249
+ indirect: false,
250
+ };
251
+ }
252
+ if (n === 1) {
253
+ return {
254
+ hops: 1,
255
+ label: '1 hop',
256
+ statement: `Observed one hop away. This is an inference about a counterparty of this ${subjectNoun}, `
257
+ + `not an observation about the ${subjectNoun} itself.`,
258
+ indirect: true,
259
+ };
260
+ }
261
+ return {
262
+ hops: n,
263
+ label: `${n} hops`,
264
+ statement: `Observed ${n} hops away. This is an inference about a counterparty ${n} steps removed from this `
265
+ + `${subjectNoun}, not an observation about the ${subjectNoun} itself.`,
266
+ indirect: true,
267
+ };
268
+ }
269
+ function evidencePresentation(evidence, copy) {
270
+ return {
271
+ id: evidence.id,
272
+ type: evidence.type,
273
+ source: evidence.source,
274
+ observedAt: formatTimestamp(evidence.observedAt),
275
+ confidenceLabel: formatConfidence(evidence.confidence),
276
+ analystConfirmed: evidence.analystVerified,
277
+ attribution: evidence.analystVerified ? copy.analystConfirmed : copy.notAnalystConfirmed,
278
+ reference: evidence.txHash ?? evidence.contract ?? evidence.address,
279
+ };
280
+ }
281
+ // ---------------------------------------------------------------------------
282
+ // Unknowns
283
+ // ---------------------------------------------------------------------------
284
+ const UNKNOWN_REASON_LABEL = {
285
+ UNKNOWN: 'Not known',
286
+ INSUFFICIENT_DATA: 'Not enough data',
287
+ PROVIDER_UNAVAILABLE: 'Could not be checked',
288
+ NOT_APPLICABLE: 'Not applicable',
289
+ };
290
+ function unknownPresentation(unknown) {
291
+ return {
292
+ kind: 'unknown',
293
+ field: unknown.field,
294
+ statement: unknown.statement,
295
+ reasonLabel: UNKNOWN_REASON_LABEL[unknown.reason],
296
+ tone: 'unknown',
297
+ };
298
+ }
299
+ // ---------------------------------------------------------------------------
300
+ // History
301
+ // ---------------------------------------------------------------------------
302
+ const HISTORY_LABEL = {
303
+ ESTABLISHED: 'Established history',
304
+ MODERATE: 'Some history',
305
+ LIMITED: 'Limited history',
306
+ NONE: 'No history',
307
+ };
308
+ function historyPresentation(status) {
309
+ return {
310
+ status,
311
+ label: HISTORY_LABEL[status],
312
+ statement: protect_1.HISTORY_STATUS_MEANING[status],
313
+ tone: 'neutral',
314
+ isWarning: false,
315
+ };
316
+ }
317
+ function componentRows(components, copy) {
318
+ return [
319
+ { key: 'technicalRisk', label: 'Technical', value: components.technicalRisk, isCoverage: false },
320
+ { key: 'behavioralRisk', label: 'Behavioural', value: components.behavioralRisk, isCoverage: false },
321
+ {
322
+ key: 'threatIntelligenceRisk',
323
+ label: 'Threat intelligence',
324
+ value: components.threatIntelligenceRisk,
325
+ isCoverage: false,
326
+ },
327
+ {
328
+ key: 'historyConfidence',
329
+ label: 'Coverage',
330
+ value: components.historyConfidence,
331
+ isCoverage: true,
332
+ caveat: copy.coverageIsNotRisk,
333
+ },
334
+ ];
335
+ }
336
+ /**
337
+ * Split an assessment into what gets rendered where.
338
+ *
339
+ * Facts and capabilities never enter the signal list and signals never enter
340
+ * the fact list; the separation is structural rather than a convention each
341
+ * component is trusted to follow. Coverage signals have already been demoted
342
+ * to facts by `normalizeEvidence` on the wire boundary, so anything arriving
343
+ * in `threatSignals` here genuinely claims to be one.
344
+ */
345
+ function assessmentSections(assessment, copy) {
346
+ const facts = assessment.facts ?? [];
347
+ const capabilities = assessment.capabilities ?? [];
348
+ const signals = assessment.threatSignals ?? [];
349
+ const unknowns = assessment.unknowns ?? [];
350
+ const activeSignals = signals.filter((s) => s.status === 'ACTIVE' && s.confidence >= protect_1.MIN_RAISING_CONFIDENCE);
351
+ const inertSignals = signals.filter((s) => !activeSignals.includes(s));
352
+ const isEmpty = facts.length === 0 && capabilities.length === 0 && signals.length === 0 && unknowns.length === 0;
353
+ const parts = [];
354
+ if (facts.length)
355
+ parts.push(`${facts.length} ${plural(facts.length, 'fact')}`);
356
+ if (capabilities.length) {
357
+ parts.push(`${capabilities.length} ${plural(capabilities.length, 'capability', 'capabilities')}`);
358
+ }
359
+ if (signals.length)
360
+ parts.push(`${signals.length} ${plural(signals.length, 'threat signal')}`);
361
+ if (unknowns.length)
362
+ parts.push(`${unknowns.length} ${plural(unknowns.length, 'unknown')}`);
363
+ return {
364
+ facts,
365
+ capabilities,
366
+ activeSignals,
367
+ inertSignals,
368
+ unknowns,
369
+ isEmpty,
370
+ emptyStatement: isEmpty ? `${copy.nothingReturned} ${copy.notAnAssurance}` : undefined,
371
+ summary: parts.length ? parts.join(' · ') : copy.nothingReturned,
372
+ };
373
+ }
374
+ function availabilityPresentation(assessment) {
375
+ const outage = (assessment.unknowns ?? []).filter((u) => u.reason === 'PROVIDER_UNAVAILABLE');
376
+ if (outage.length === 0)
377
+ return { unavailable: false, tone: 'neutral' };
378
+ return {
379
+ unavailable: true,
380
+ statement: outage.map((u) => u.statement).join(' '),
381
+ tone: 'neutral',
382
+ };
383
+ }
384
+ // ---------------------------------------------------------------------------
385
+ // Policy decision
386
+ // ---------------------------------------------------------------------------
387
+ const DECISION_LABEL = {
388
+ allow: 'No action requested',
389
+ inform: 'For your information',
390
+ warn: 'Review before continuing',
391
+ warn_strong: 'Review carefully before continuing',
392
+ require_confirmation: 'Explicit confirmation requested',
393
+ block: 'This application will not continue',
394
+ };
395
+ const DECISION_STATEMENT = {
396
+ allow: 'This application’s policy asks for nothing further.',
397
+ inform: 'Shown because this application’s policy asks that you see it.',
398
+ warn: 'This application’s policy asks you to read the detail before continuing.',
399
+ warn_strong: 'This application’s policy asks you to read the detail carefully before continuing.',
400
+ require_confirmation: 'This application’s policy asks you to confirm explicitly before continuing.',
401
+ block: 'This application’s policy stops here. That decision belongs to this application; Decentrys reports evidence and does not stop anything.',
402
+ };
403
+ function decisionPresentation(decision) {
404
+ return {
405
+ action: decision.action,
406
+ label: DECISION_LABEL[decision.action],
407
+ statement: DECISION_STATEMENT[decision.action],
408
+ reason: decision.reason,
409
+ blocksUi: false,
410
+ };
411
+ }
412
+ function approvalPresentation(details) {
413
+ const spenderName = details.spenderLabel?.trim() || shortenAddress(details.spender);
414
+ const assetName = details.symbol?.trim() || `tokens at ${shortenAddress(details.token)}`;
415
+ if (details.amount === undefined || details.amount === null || details.amount === '') {
416
+ return {
417
+ unlimited: false,
418
+ amountKnown: false,
419
+ amountLabel: 'Not decoded',
420
+ scopeLabel: 'Allowance amount not decoded',
421
+ statement: `The allowance amount could not be decoded, so how much this grants ${spenderName} over your `
422
+ + `${assetName} is not known.`,
423
+ spenderName,
424
+ assetName,
425
+ tone: 'capability',
426
+ emphasis: 'strong',
427
+ };
428
+ }
429
+ if (isUnlimitedAllowance(details.amount)) {
430
+ return {
431
+ unlimited: true,
432
+ amountKnown: true,
433
+ amountLabel: 'Unlimited',
434
+ scopeLabel: 'Unlimited allowance',
435
+ statement: `This grants ${spenderName} permission to spend an unlimited amount of your ${assetName}, `
436
+ + 'now and at any time in the future, until it is revoked.',
437
+ spenderName,
438
+ assetName,
439
+ tone: 'capability',
440
+ emphasis: 'strong',
441
+ };
442
+ }
443
+ // With no decimals supplied the figure is base units, and it is *labelled*
444
+ // as base units rather than silently presented as whole tokens — an
445
+ // allowance shown 10^18 times too small is worse than one not shown at all.
446
+ const baseUnits = details.decimals === undefined;
447
+ const figure = formatTokenAmount(details.amount, details.decimals);
448
+ const amountLabel = baseUnits ? `${figure} base units` : `${figure} ${assetName}`;
449
+ return {
450
+ unlimited: false,
451
+ amountKnown: true,
452
+ amountLabel,
453
+ scopeLabel: 'Limited allowance',
454
+ statement: `This grants ${spenderName} permission to spend up to ${figure} `
455
+ + `${baseUnits ? `base units of ${assetName}` : assetName}, until it is revoked.`,
456
+ spenderName,
457
+ assetName,
458
+ tone: 'capability',
459
+ emphasis: 'normal',
460
+ };
461
+ }
462
+ /** ERC-20 approvals commonly use a sentinel near uint256 max to mean "no cap". */
463
+ function isUnlimitedAllowance(amount) {
464
+ if (amount.trim().toLowerCase() === 'unlimited')
465
+ return true;
466
+ try {
467
+ return BigInt(amount) >= 1n << 255n;
468
+ }
469
+ catch {
470
+ return false;
471
+ }
472
+ }
473
+ // ---------------------------------------------------------------------------
474
+ // Formatting
475
+ // ---------------------------------------------------------------------------
476
+ /** `0.5` becomes `50%`. Never rounded away to "high" or "low". */
477
+ function formatConfidence(confidence) {
478
+ const clamped = Math.min(1, Math.max(0, confidence));
479
+ return `${Math.round(clamped * 100)}%`;
480
+ }
481
+ /**
482
+ * A fixed UTC rendering rather than a locale one.
483
+ *
484
+ * Locale formatting differs between a browser, an extension service worker and
485
+ * a React Native runtime, and an integrator wanting their own format has the
486
+ * raw ISO string on the model. Predictable beats pretty here.
487
+ */
488
+ function formatTimestamp(iso) {
489
+ const ms = Date.parse(iso);
490
+ if (Number.isNaN(ms))
491
+ return iso;
492
+ return `${new Date(ms).toISOString().slice(0, 16).replace('T', ' ')} UTC`;
493
+ }
494
+ function shortenAddress(address, lead = 6, tail = 4) {
495
+ if (address.length <= lead + tail + 1)
496
+ return address;
497
+ return `${address.slice(0, lead)}…${address.slice(-tail)}`;
498
+ }
499
+ /**
500
+ * Base units to a human amount, in integer arithmetic.
501
+ *
502
+ * Token balances routinely exceed what a double can hold exactly, and a
503
+ * rounding artefact in an allowance figure is a number a user would act on.
504
+ * With no decimals supplied the raw base units are returned unscaled; the
505
+ * caller is responsible for saying so, and `approvalPresentation` does.
506
+ */
507
+ function formatTokenAmount(amount, decimals) {
508
+ let value;
509
+ try {
510
+ value = BigInt(amount);
511
+ }
512
+ catch {
513
+ return amount;
514
+ }
515
+ if (decimals === undefined || decimals < 0)
516
+ return group(value.toString());
517
+ const negative = value < 0n;
518
+ const abs = negative ? -value : value;
519
+ const scale = 10n ** BigInt(decimals);
520
+ const whole = abs / scale;
521
+ const fraction = (abs % scale).toString().padStart(decimals, '0').replace(/0+$/, '');
522
+ const text = fraction ? `${group(whole.toString())}.${fraction}` : group(whole.toString());
523
+ return negative ? `-${text}` : text;
524
+ }
525
+ function group(digits) {
526
+ return digits.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
527
+ }
528
+ function plural(count, singular, pluralForm) {
529
+ if (count === 1)
530
+ return singular;
531
+ return pluralForm ?? `${singular}s`;
532
+ }
533
+ //# sourceMappingURL=presentation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentation.js","sourceRoot":"","sources":["../src/presentation.ts"],"names":[],"mappings":"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"}