@xochi/client 0.0.0-stage → 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 (125) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/LICENSE +21 -0
  3. package/README.md +119 -2
  4. package/dist/cjs/claim.d.ts +33 -0
  5. package/dist/cjs/claim.js +44 -0
  6. package/dist/cjs/fee.d.ts +247 -0
  7. package/dist/cjs/fee.js +295 -0
  8. package/dist/cjs/index.d.ts +18 -0
  9. package/dist/cjs/index.js +33 -0
  10. package/dist/cjs/machine/claimInfo.d.ts +29 -0
  11. package/dist/cjs/machine/claimInfo.js +26 -0
  12. package/dist/cjs/machine/decisions.d.ts +452 -0
  13. package/dist/cjs/machine/decisions.js +665 -0
  14. package/dist/cjs/machine/deposit.d.ts +113 -0
  15. package/dist/cjs/machine/deposit.js +265 -0
  16. package/dist/cjs/machine/index.d.ts +23 -0
  17. package/dist/cjs/machine/index.js +53 -0
  18. package/dist/cjs/machine/machine.d.ts +409 -0
  19. package/dist/cjs/machine/machine.js +1615 -0
  20. package/dist/cjs/machine/phase.d.ts +24 -0
  21. package/dist/cjs/machine/phase.js +45 -0
  22. package/dist/cjs/machine/quoteChecks.d.ts +41 -0
  23. package/dist/cjs/machine/quoteChecks.js +82 -0
  24. package/dist/cjs/machine/receipt.d.ts +151 -0
  25. package/dist/cjs/machine/receipt.js +69 -0
  26. package/dist/cjs/machine/recipientEcho.d.ts +16 -0
  27. package/dist/cjs/machine/recipientEcho.js +27 -0
  28. package/dist/cjs/machine/solverPin.d.ts +110 -0
  29. package/dist/cjs/machine/solverPin.js +214 -0
  30. package/dist/cjs/machine/state.d.ts +167 -0
  31. package/dist/cjs/machine/state.js +31 -0
  32. package/dist/cjs/machine/transition.d.ts +15 -0
  33. package/dist/cjs/machine/transition.js +20 -0
  34. package/dist/cjs/machine/validateRequest.d.ts +15 -0
  35. package/dist/cjs/machine/validateRequest.js +127 -0
  36. package/dist/cjs/machine/view.d.ts +3 -0
  37. package/dist/cjs/machine/view.js +74 -0
  38. package/dist/cjs/machine/wire.d.ts +527 -0
  39. package/dist/cjs/machine/wire.js +280 -0
  40. package/dist/cjs/package.json +1 -0
  41. package/dist/cjs/shared/api.d.ts +9 -0
  42. package/dist/cjs/shared/api.js +5 -0
  43. package/dist/cjs/shared/chains.d.ts +243 -0
  44. package/dist/cjs/shared/chains.js +250 -0
  45. package/dist/cjs/shared/eip712.d.ts +44 -0
  46. package/dist/cjs/shared/eip712.js +64 -0
  47. package/dist/cjs/shared/index.d.ts +15 -0
  48. package/dist/cjs/shared/index.js +31 -0
  49. package/dist/cjs/shared/intentStream.d.ts +74 -0
  50. package/dist/cjs/shared/intentStream.js +59 -0
  51. package/dist/cjs/shared/intents.d.ts +88 -0
  52. package/dist/cjs/shared/intents.js +227 -0
  53. package/dist/cjs/shared/schemas.d.ts +928 -0
  54. package/dist/cjs/shared/schemas.js +524 -0
  55. package/dist/cjs/shared/stealth.d.ts +53 -0
  56. package/dist/cjs/shared/stealth.js +68 -0
  57. package/dist/cjs/shared/trading.d.ts +153 -0
  58. package/dist/cjs/shared/trading.js +185 -0
  59. package/dist/cjs/shared/types.d.ts +37 -0
  60. package/dist/cjs/shared/types.js +7 -0
  61. package/dist/cjs/shared/validators.d.ts +30 -0
  62. package/dist/cjs/shared/validators.js +79 -0
  63. package/dist/cjs/transport/client.d.ts +234 -0
  64. package/dist/cjs/transport/client.js +1456 -0
  65. package/dist/esm/claim.d.ts +33 -0
  66. package/dist/esm/claim.js +41 -0
  67. package/dist/esm/fee.d.ts +247 -0
  68. package/dist/esm/fee.js +285 -0
  69. package/dist/esm/index.d.ts +18 -0
  70. package/dist/esm/index.js +17 -0
  71. package/dist/esm/machine/claimInfo.d.ts +29 -0
  72. package/dist/esm/machine/claimInfo.js +23 -0
  73. package/dist/esm/machine/decisions.d.ts +452 -0
  74. package/dist/esm/machine/decisions.js +640 -0
  75. package/dist/esm/machine/deposit.d.ts +113 -0
  76. package/dist/esm/machine/deposit.js +260 -0
  77. package/dist/esm/machine/index.d.ts +23 -0
  78. package/dist/esm/machine/index.js +23 -0
  79. package/dist/esm/machine/machine.d.ts +409 -0
  80. package/dist/esm/machine/machine.js +1609 -0
  81. package/dist/esm/machine/phase.d.ts +24 -0
  82. package/dist/esm/machine/phase.js +42 -0
  83. package/dist/esm/machine/quoteChecks.d.ts +41 -0
  84. package/dist/esm/machine/quoteChecks.js +78 -0
  85. package/dist/esm/machine/receipt.d.ts +151 -0
  86. package/dist/esm/machine/receipt.js +64 -0
  87. package/dist/esm/machine/recipientEcho.d.ts +16 -0
  88. package/dist/esm/machine/recipientEcho.js +24 -0
  89. package/dist/esm/machine/solverPin.d.ts +110 -0
  90. package/dist/esm/machine/solverPin.js +210 -0
  91. package/dist/esm/machine/state.d.ts +167 -0
  92. package/dist/esm/machine/state.js +28 -0
  93. package/dist/esm/machine/transition.d.ts +15 -0
  94. package/dist/esm/machine/transition.js +17 -0
  95. package/dist/esm/machine/validateRequest.d.ts +15 -0
  96. package/dist/esm/machine/validateRequest.js +123 -0
  97. package/dist/esm/machine/view.d.ts +3 -0
  98. package/dist/esm/machine/view.js +71 -0
  99. package/dist/esm/machine/wire.d.ts +527 -0
  100. package/dist/esm/machine/wire.js +266 -0
  101. package/dist/esm/shared/api.d.ts +9 -0
  102. package/dist/esm/shared/api.js +4 -0
  103. package/dist/esm/shared/chains.d.ts +243 -0
  104. package/dist/esm/shared/chains.js +236 -0
  105. package/dist/esm/shared/eip712.d.ts +44 -0
  106. package/dist/esm/shared/eip712.js +61 -0
  107. package/dist/esm/shared/index.d.ts +15 -0
  108. package/dist/esm/shared/index.js +15 -0
  109. package/dist/esm/shared/intentStream.d.ts +74 -0
  110. package/dist/esm/shared/intentStream.js +55 -0
  111. package/dist/esm/shared/intents.d.ts +88 -0
  112. package/dist/esm/shared/intents.js +213 -0
  113. package/dist/esm/shared/schemas.d.ts +928 -0
  114. package/dist/esm/shared/schemas.js +521 -0
  115. package/dist/esm/shared/stealth.d.ts +53 -0
  116. package/dist/esm/shared/stealth.js +64 -0
  117. package/dist/esm/shared/trading.d.ts +153 -0
  118. package/dist/esm/shared/trading.js +182 -0
  119. package/dist/esm/shared/types.d.ts +37 -0
  120. package/dist/esm/shared/types.js +6 -0
  121. package/dist/esm/shared/validators.d.ts +30 -0
  122. package/dist/esm/shared/validators.js +74 -0
  123. package/dist/esm/transport/client.d.ts +234 -0
  124. package/dist/esm/transport/client.js +1447 -0
  125. package/package.json +61 -4
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Trading Constants
3
+ *
4
+ * Shared trading configuration for slippage, quotes, and limits.
5
+ */
6
+ /** Default slippage in basis points (0.5%) */
7
+ export declare const DEFAULT_SLIPPAGE_BPS = 50;
8
+ /** Available slippage options in basis points */
9
+ export declare const SLIPPAGE_OPTIONS: readonly [10, 50, 100, 200];
10
+ export type SlippageOption = (typeof SLIPPAGE_OPTIONS)[number];
11
+ /** Slippage presets with labels */
12
+ export declare const SLIPPAGE_PRESETS: {
13
+ readonly low: 10;
14
+ readonly medium: 50;
15
+ readonly high: 100;
16
+ };
17
+ /** Quote expiry in seconds */
18
+ export declare const QUOTE_EXPIRY_SEC = 30;
19
+ /** Maximum retries for failed quotes */
20
+ export declare const MAX_QUOTE_RETRIES = 3;
21
+ /** Maximum decimal places for token amounts */
22
+ export declare const MAX_TOKEN_DECIMALS = 18;
23
+ /** Minimum trade amount in USD */
24
+ export declare const MIN_TRADE_USD = 1;
25
+ /** Maximum slippage percentage */
26
+ export declare const MAX_SLIPPAGE_PERCENT = 50;
27
+ /** Minimum slippage percentage */
28
+ export declare const MIN_SLIPPAGE_PERCENT = 0.01;
29
+ /**
30
+ * Hard ceiling on how far below market a fill may be before execution is
31
+ * refused. This is all-in value loss (fees + fixed network minimum + market
32
+ * slippage) versus the live market rate, not the user's configurable slippage
33
+ * tolerance. Protects users from executing trades -- typically dust orders --
34
+ * where costs eat more than half the notional.
35
+ */
36
+ export declare const MAX_PRICE_IMPACT_PERCENT = 50;
37
+ /**
38
+ * Minimum trust score for Aztec L2 shielded settlement (the Private privacy
39
+ * level). L1 stealth (ERC-5564) is NOT trust-gated: privacy is free by default,
40
+ * so any wallet can settle to a one-time stealth address and simply pays its own
41
+ * trust-tier fee. Only the deeper Aztec-shielded tiers -- Private (50+) and
42
+ * Sovereign (75+), both reached via pxe-bridge -- require trust.
43
+ */
44
+ export declare const SHIELDED_MIN_SCORE = 50;
45
+ /** Trust score thresholds by tier */
46
+ export declare const TRUST_THRESHOLDS: {
47
+ readonly trusted: 25;
48
+ readonly verified: 50;
49
+ readonly premium: 75;
50
+ readonly institutional: 100;
51
+ };
52
+ /** Basis points denominator (1 bps = 0.01%) */
53
+ export declare const BPS_DENOMINATOR = 10000;
54
+ /** Maximum deadline offset in seconds (1 hour) */
55
+ export declare const MAX_DEADLINE_OFFSET_SEC = 3600;
56
+ /**
57
+ * Server-side ceiling on a quote request's `deadline`, in seconds from now.
58
+ *
59
+ * Deliberately looser than MAX_DEADLINE_OFFSET_SEC, which is the CLIENT's rule
60
+ * (src/utils/validators.ts) and the value the frontend actually sends. This is
61
+ * the outer bound the API will accept from anyone, sized so an agent or a device
62
+ * with a skewed clock is not rejected for asking a reasonable question.
63
+ *
64
+ * The reason there is a ceiling at all: `deadline` is what the user signs into
65
+ * the intent EIP-712, so an unbounded value is an authorization with no
66
+ * expiry -- and `decideReconcile` treats "past the signed deadline" as the point
67
+ * where an in-doubt intent can no longer move funds.
68
+ */
69
+ export declare const MAX_QUOTE_DEADLINE_FUTURE_SEC: number;
70
+ /**
71
+ * How far in the PAST a quote `deadline` may be and still be accepted, in
72
+ * seconds. Pure clock-skew tolerance: no correct client asks for a deadline that
73
+ * has already passed, but one whose clock is behind might.
74
+ *
75
+ * A past-dated deadline is not inert data: the abandoned-deposit sweep reads
76
+ * `deadline` to decide when a deposit route has died, so `deadline: 1` would
77
+ * mean "terminalise this live route on the next cron tick". The sweep gates on
78
+ * the server-set `created_at` too; this is the other half: the value never
79
+ * gets stored in the first place.
80
+ */
81
+ export declare const MAX_QUOTE_DEADLINE_PAST_SEC = 3600;
82
+ /**
83
+ * Sanity bound on the SOLVER-supplied `deposit_deadline`, in seconds from the
84
+ * quote, applied only when Xochi persists it.
85
+ *
86
+ * The client treats this field as untrusted: `POLL_CEILING_MAX_MS` exists
87
+ * because a malformed or hostile `deposit_deadline` far in the future must not
88
+ * turn the poll into a permanent background request loop. Persisting it makes
89
+ * the server trust it more than the browser does, and it is the PRIMARY gate
90
+ * on the abandoned-deposit sweep (`COALESCE(deposit_deadline, deadline)`), so
91
+ * one bad value -- a misparsed `XOCHI_DEPOSIT_DEADLINE_SECONDS`, a solver bug
92
+ * -- would make every deposit row permanently and silently unsweepable.
93
+ *
94
+ * Riddler's default is 1800s, so this is two orders of magnitude of headroom: it
95
+ * rejects nothing a correctly configured solver can mint. A value outside it is
96
+ * stored as NULL, which degrades the sweep to the quote `deadline` rather than
97
+ * to no gate at all. The value SERVED to the client is never altered -- it is
98
+ * covered by the deposit attestation signature, so changing it would break
99
+ * client-side verification.
100
+ */
101
+ export declare const MAX_DEPOSIT_WINDOW_SEC: number;
102
+ /** Maximum proof age in seconds (1 hour) -- proofs older than this are rejected server-side */
103
+ export declare const MAX_PROOF_AGE_SEC = 3600;
104
+ /** Grace period for rotated provider sets in seconds (24 hours) */
105
+ export declare const PROVIDER_SET_GRACE_PERIOD_SEC = 86400;
106
+ /** Ethereum address length including 0x prefix */
107
+ export declare const ETH_ADDRESS_LENGTH = 42;
108
+ /** Max slippage in basis points */
109
+ export declare const MAX_SLIPPAGE_BPS: number;
110
+ /** Multipliers for attestation scoring within a category */
111
+ export declare const ATTESTATION_MULTIPLIERS: {
112
+ readonly first: 1;
113
+ readonly second: 0.25;
114
+ readonly subsequent: 0.1;
115
+ };
116
+ /** Default query limit for paginated API responses */
117
+ export declare const DEFAULT_QUERY_LIMIT = 50;
118
+ /** Maximum query limit for announcement scanning */
119
+ export declare const MAX_ANNOUNCEMENT_LIMIT = 1000;
120
+ /** Default announcement query limit */
121
+ export declare const DEFAULT_ANNOUNCEMENT_LIMIT = 100;
122
+ /** Rate limit window in milliseconds (15 minutes) */
123
+ export declare const RATE_LIMIT_WINDOW_MS: number;
124
+ /** Maximum rate-limited attempts per window */
125
+ export declare const RATE_LIMIT_MAX_ATTEMPTS = 5;
126
+ /** JWT token expiry in hours */
127
+ export declare const JWT_EXPIRY_HOURS = 4;
128
+ /** Tier proof expiry in milliseconds (7 days) */
129
+ export declare const TIER_PROOF_EXPIRY_MS: number;
130
+ /** Max rate limit store size before cleanup */
131
+ export declare const RATE_LIMIT_STORE_MAX = 10000;
132
+ /** Base delay for failed auth in milliseconds */
133
+ export declare const AUTH_FAILURE_BASE_DELAY_MS = 500;
134
+ /** Max delay for failed auth in milliseconds */
135
+ export declare const AUTH_FAILURE_MAX_DELAY_MS = 5000;
136
+ /** Max demo code length */
137
+ export declare const MAX_DEMO_CODE_LENGTH = 100;
138
+ /** Mock spread factor (1% spread = 99/100) */
139
+ export declare const MOCK_SPREAD_NUMERATOR = 99n;
140
+ export declare const MOCK_SPREAD_DENOMINATOR = 100n;
141
+ /** All trading constants in one object */
142
+ export declare const TRADING: {
143
+ readonly defaultSlippageBps: 50;
144
+ readonly slippageOptions: readonly [10, 50, 100, 200];
145
+ readonly quoteExpirySec: 30;
146
+ readonly maxQuoteRetries: 3;
147
+ readonly maxTokenDecimals: 18;
148
+ readonly minTradeUsd: 1;
149
+ readonly maxSlippagePercent: 50;
150
+ readonly minSlippagePercent: 0.01;
151
+ readonly maxPriceImpactPercent: 50;
152
+ readonly shieldedMinScore: 50;
153
+ };
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ /**
3
+ * Trading Constants
4
+ *
5
+ * Shared trading configuration for slippage, quotes, and limits.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.TRADING = exports.MOCK_SPREAD_DENOMINATOR = exports.MOCK_SPREAD_NUMERATOR = exports.MAX_DEMO_CODE_LENGTH = exports.AUTH_FAILURE_MAX_DELAY_MS = exports.AUTH_FAILURE_BASE_DELAY_MS = exports.RATE_LIMIT_STORE_MAX = exports.TIER_PROOF_EXPIRY_MS = exports.JWT_EXPIRY_HOURS = exports.RATE_LIMIT_MAX_ATTEMPTS = exports.RATE_LIMIT_WINDOW_MS = exports.DEFAULT_ANNOUNCEMENT_LIMIT = exports.MAX_ANNOUNCEMENT_LIMIT = exports.DEFAULT_QUERY_LIMIT = exports.ATTESTATION_MULTIPLIERS = exports.MAX_SLIPPAGE_BPS = exports.ETH_ADDRESS_LENGTH = exports.PROVIDER_SET_GRACE_PERIOD_SEC = exports.MAX_PROOF_AGE_SEC = exports.MAX_DEPOSIT_WINDOW_SEC = exports.MAX_QUOTE_DEADLINE_PAST_SEC = exports.MAX_QUOTE_DEADLINE_FUTURE_SEC = exports.MAX_DEADLINE_OFFSET_SEC = exports.BPS_DENOMINATOR = exports.TRUST_THRESHOLDS = exports.SHIELDED_MIN_SCORE = exports.MAX_PRICE_IMPACT_PERCENT = exports.MIN_SLIPPAGE_PERCENT = exports.MAX_SLIPPAGE_PERCENT = exports.MIN_TRADE_USD = exports.MAX_TOKEN_DECIMALS = exports.MAX_QUOTE_RETRIES = exports.QUOTE_EXPIRY_SEC = exports.SLIPPAGE_PRESETS = exports.SLIPPAGE_OPTIONS = exports.DEFAULT_SLIPPAGE_BPS = void 0;
9
+ // ============================================================
10
+ // Slippage Configuration
11
+ // ============================================================
12
+ /** Default slippage in basis points (0.5%) */
13
+ exports.DEFAULT_SLIPPAGE_BPS = 50;
14
+ /** Available slippage options in basis points */
15
+ exports.SLIPPAGE_OPTIONS = [10, 50, 100, 200];
16
+ /** Slippage presets with labels */
17
+ exports.SLIPPAGE_PRESETS = {
18
+ low: 10, // 0.1%
19
+ medium: 50, // 0.5%
20
+ high: 100, // 1%
21
+ };
22
+ // ============================================================
23
+ // Quote Configuration
24
+ // ============================================================
25
+ /** Quote expiry in seconds */
26
+ exports.QUOTE_EXPIRY_SEC = 30;
27
+ /** Maximum retries for failed quotes */
28
+ exports.MAX_QUOTE_RETRIES = 3;
29
+ // ============================================================
30
+ // Trading Limits
31
+ // ============================================================
32
+ /** Maximum decimal places for token amounts */
33
+ exports.MAX_TOKEN_DECIMALS = 18;
34
+ /** Minimum trade amount in USD */
35
+ exports.MIN_TRADE_USD = 1;
36
+ /** Maximum slippage percentage */
37
+ exports.MAX_SLIPPAGE_PERCENT = 50;
38
+ /** Minimum slippage percentage */
39
+ exports.MIN_SLIPPAGE_PERCENT = 0.01;
40
+ /**
41
+ * Hard ceiling on how far below market a fill may be before execution is
42
+ * refused. This is all-in value loss (fees + fixed network minimum + market
43
+ * slippage) versus the live market rate, not the user's configurable slippage
44
+ * tolerance. Protects users from executing trades -- typically dust orders --
45
+ * where costs eat more than half the notional.
46
+ */
47
+ exports.MAX_PRICE_IMPACT_PERCENT = 50;
48
+ // ============================================================
49
+ // Trust Thresholds
50
+ // ============================================================
51
+ /**
52
+ * Minimum trust score for Aztec L2 shielded settlement (the Private privacy
53
+ * level). L1 stealth (ERC-5564) is NOT trust-gated: privacy is free by default,
54
+ * so any wallet can settle to a one-time stealth address and simply pays its own
55
+ * trust-tier fee. Only the deeper Aztec-shielded tiers -- Private (50+) and
56
+ * Sovereign (75+), both reached via pxe-bridge -- require trust.
57
+ */
58
+ exports.SHIELDED_MIN_SCORE = 50;
59
+ /** Trust score thresholds by tier */
60
+ exports.TRUST_THRESHOLDS = {
61
+ trusted: 25,
62
+ verified: 50,
63
+ premium: 75,
64
+ institutional: 100,
65
+ };
66
+ // ============================================================
67
+ // Numeric Constants
68
+ // ============================================================
69
+ /** Basis points denominator (1 bps = 0.01%) */
70
+ exports.BPS_DENOMINATOR = 10_000;
71
+ /** Maximum deadline offset in seconds (1 hour) */
72
+ exports.MAX_DEADLINE_OFFSET_SEC = 3600;
73
+ /**
74
+ * Server-side ceiling on a quote request's `deadline`, in seconds from now.
75
+ *
76
+ * Deliberately looser than MAX_DEADLINE_OFFSET_SEC, which is the CLIENT's rule
77
+ * (src/utils/validators.ts) and the value the frontend actually sends. This is
78
+ * the outer bound the API will accept from anyone, sized so an agent or a device
79
+ * with a skewed clock is not rejected for asking a reasonable question.
80
+ *
81
+ * The reason there is a ceiling at all: `deadline` is what the user signs into
82
+ * the intent EIP-712, so an unbounded value is an authorization with no
83
+ * expiry -- and `decideReconcile` treats "past the signed deadline" as the point
84
+ * where an in-doubt intent can no longer move funds.
85
+ */
86
+ exports.MAX_QUOTE_DEADLINE_FUTURE_SEC = 24 * 3600;
87
+ /**
88
+ * How far in the PAST a quote `deadline` may be and still be accepted, in
89
+ * seconds. Pure clock-skew tolerance: no correct client asks for a deadline that
90
+ * has already passed, but one whose clock is behind might.
91
+ *
92
+ * A past-dated deadline is not inert data: the abandoned-deposit sweep reads
93
+ * `deadline` to decide when a deposit route has died, so `deadline: 1` would
94
+ * mean "terminalise this live route on the next cron tick". The sweep gates on
95
+ * the server-set `created_at` too; this is the other half: the value never
96
+ * gets stored in the first place.
97
+ */
98
+ exports.MAX_QUOTE_DEADLINE_PAST_SEC = 3600;
99
+ /**
100
+ * Sanity bound on the SOLVER-supplied `deposit_deadline`, in seconds from the
101
+ * quote, applied only when Xochi persists it.
102
+ *
103
+ * The client treats this field as untrusted: `POLL_CEILING_MAX_MS` exists
104
+ * because a malformed or hostile `deposit_deadline` far in the future must not
105
+ * turn the poll into a permanent background request loop. Persisting it makes
106
+ * the server trust it more than the browser does, and it is the PRIMARY gate
107
+ * on the abandoned-deposit sweep (`COALESCE(deposit_deadline, deadline)`), so
108
+ * one bad value -- a misparsed `XOCHI_DEPOSIT_DEADLINE_SECONDS`, a solver bug
109
+ * -- would make every deposit row permanently and silently unsweepable.
110
+ *
111
+ * Riddler's default is 1800s, so this is two orders of magnitude of headroom: it
112
+ * rejects nothing a correctly configured solver can mint. A value outside it is
113
+ * stored as NULL, which degrades the sweep to the quote `deadline` rather than
114
+ * to no gate at all. The value SERVED to the client is never altered -- it is
115
+ * covered by the deposit attestation signature, so changing it would break
116
+ * client-side verification.
117
+ */
118
+ exports.MAX_DEPOSIT_WINDOW_SEC = 24 * 3600;
119
+ /** Maximum proof age in seconds (1 hour) -- proofs older than this are rejected server-side */
120
+ exports.MAX_PROOF_AGE_SEC = 3600;
121
+ /** Grace period for rotated provider sets in seconds (24 hours) */
122
+ exports.PROVIDER_SET_GRACE_PERIOD_SEC = 86400;
123
+ /** Ethereum address length including 0x prefix */
124
+ exports.ETH_ADDRESS_LENGTH = 42;
125
+ /** Max slippage in basis points */
126
+ exports.MAX_SLIPPAGE_BPS = exports.MAX_SLIPPAGE_PERCENT * 100;
127
+ // ============================================================
128
+ // Attestation Diminishing Returns
129
+ // ============================================================
130
+ /** Multipliers for attestation scoring within a category */
131
+ exports.ATTESTATION_MULTIPLIERS = {
132
+ first: 1.0,
133
+ second: 0.25,
134
+ subsequent: 0.1,
135
+ };
136
+ // ============================================================
137
+ // Query Limits
138
+ // ============================================================
139
+ /** Default query limit for paginated API responses */
140
+ exports.DEFAULT_QUERY_LIMIT = 50;
141
+ /** Maximum query limit for announcement scanning */
142
+ exports.MAX_ANNOUNCEMENT_LIMIT = 1000;
143
+ /** Default announcement query limit */
144
+ exports.DEFAULT_ANNOUNCEMENT_LIMIT = 100;
145
+ // ============================================================
146
+ // Auth & Rate Limiting
147
+ // ============================================================
148
+ /** Rate limit window in milliseconds (15 minutes) */
149
+ exports.RATE_LIMIT_WINDOW_MS = 15 * 60 * 1000;
150
+ /** Maximum rate-limited attempts per window */
151
+ exports.RATE_LIMIT_MAX_ATTEMPTS = 5;
152
+ /** JWT token expiry in hours */
153
+ exports.JWT_EXPIRY_HOURS = 4;
154
+ /** Tier proof expiry in milliseconds (7 days) */
155
+ exports.TIER_PROOF_EXPIRY_MS = 7 * 24 * 60 * 60 * 1000;
156
+ /** Max rate limit store size before cleanup */
157
+ exports.RATE_LIMIT_STORE_MAX = 10_000;
158
+ /** Base delay for failed auth in milliseconds */
159
+ exports.AUTH_FAILURE_BASE_DELAY_MS = 500;
160
+ /** Max delay for failed auth in milliseconds */
161
+ exports.AUTH_FAILURE_MAX_DELAY_MS = 5000;
162
+ /** Max demo code length */
163
+ exports.MAX_DEMO_CODE_LENGTH = 100;
164
+ // ============================================================
165
+ // Mock Spread
166
+ // ============================================================
167
+ /** Mock spread factor (1% spread = 99/100) */
168
+ exports.MOCK_SPREAD_NUMERATOR = 99n;
169
+ exports.MOCK_SPREAD_DENOMINATOR = 100n;
170
+ // ============================================================
171
+ // Bundled Trading Config
172
+ // ============================================================
173
+ /** All trading constants in one object */
174
+ exports.TRADING = {
175
+ defaultSlippageBps: exports.DEFAULT_SLIPPAGE_BPS,
176
+ slippageOptions: exports.SLIPPAGE_OPTIONS,
177
+ quoteExpirySec: exports.QUOTE_EXPIRY_SEC,
178
+ maxQuoteRetries: exports.MAX_QUOTE_RETRIES,
179
+ maxTokenDecimals: exports.MAX_TOKEN_DECIMALS,
180
+ minTradeUsd: exports.MIN_TRADE_USD,
181
+ maxSlippagePercent: exports.MAX_SLIPPAGE_PERCENT,
182
+ minSlippagePercent: exports.MIN_SLIPPAGE_PERCENT,
183
+ maxPriceImpactPercent: exports.MAX_PRICE_IMPACT_PERCENT,
184
+ shieldedMinScore: exports.SHIELDED_MIN_SCORE,
185
+ };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Shared Types
3
+ *
4
+ * Type definitions used across frontend and backend.
5
+ */
6
+ /** Lowercase tier id used on the wire + in the fee breakdown. */
7
+ export type Tier = "standard" | "trusted" | "verified" | "premium" | "institutional";
8
+ /**
9
+ * Itemized fee breakdown for a quote (economics.md Part 1, "Frontend display spec").
10
+ * Three additive layers on a never-discounted cost floor: solver spread + gas
11
+ * floor (Riddler), venue fee (Xochi), routing fee (Raxol -> buyback). Amounts are
12
+ * destination-token smallest units (strings); rates are bps. Discounts carve
13
+ * venue + routing only, never the solver floor.
14
+ */
15
+ export interface FeeBreakdown {
16
+ tier: Tier;
17
+ assetClass: "stable" | "volatile";
18
+ /** Guaranteed minimum, never discounted (Riddler). */
19
+ gasFloor: {
20
+ amount: string;
21
+ usd: string;
22
+ };
23
+ solverFeeBps: number;
24
+ solverFee: string;
25
+ /** > 0 only on large-vs-depth fills; render as a warning, not a fee. */
26
+ priceImpactBps: number;
27
+ priceImpact: string;
28
+ venueFeeBps: number;
29
+ venueFee: string;
30
+ routingFeeBps: number;
31
+ routingFee: string;
32
+ totalBps: number;
33
+ totalFee: string;
34
+ totalUsd: string;
35
+ /** 15 -- solver upside on positive slippage; the user keeps the other 85%. */
36
+ surplusSharePct: number;
37
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ /**
3
+ * Shared Types
4
+ *
5
+ * Type definitions used across frontend and backend.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Validators
3
+ *
4
+ * Address validators: EVM hex20 and checksummed Tron base58.
5
+ */
6
+ /** Ethereum address regex pattern */
7
+ export declare const ETH_ADDRESS_REGEX: RegExp;
8
+ /** Zero address constant */
9
+ export declare const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
10
+ /** Check if string is a valid Ethereum address */
11
+ export declare function isValidAddress(address: string): boolean;
12
+ /**
13
+ * Tron mainnet address shape: 34 chars, leading "T", base58 alphabet (no
14
+ * 0/O/I/l). Shape alone is NOT sufficient to accept an address -- see
15
+ * `isValidTronAddress`, which also verifies the base58check checksum.
16
+ */
17
+ export declare const TRON_ADDRESS_REGEX: RegExp;
18
+ /**
19
+ * Validate a Tron address, checksum included.
20
+ *
21
+ * The shape regex alone accepts any typo that keeps the length and alphabet,
22
+ * which is nearly all of them. Base58check carries a 4-byte checksum, so a
23
+ * mistyped address survives it with probability about 1 in 4 billion. That
24
+ * matters here specifically because a Tron payout recipient is typed by hand on
25
+ * an EVM-origin swap: there is no Tron wallet in the flow to catch it later, and
26
+ * a TRC-20 transfer to a well-formed but unowned address is irrecoverable.
27
+ *
28
+ * Checksum = first 4 bytes of sha256(sha256(0x41 || address_bytes)).
29
+ */
30
+ export declare function isValidTronAddress(address: string): boolean;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ /**
3
+ * Validators
4
+ *
5
+ * Address validators: EVM hex20 and checksummed Tron base58.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.TRON_ADDRESS_REGEX = exports.ZERO_ADDRESS = exports.ETH_ADDRESS_REGEX = void 0;
9
+ exports.isValidAddress = isValidAddress;
10
+ exports.isValidTronAddress = isValidTronAddress;
11
+ const viem_1 = require("viem");
12
+ // ============================================================
13
+ // Address Validation
14
+ // ============================================================
15
+ /** Ethereum address regex pattern */
16
+ exports.ETH_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
17
+ /** Zero address constant */
18
+ exports.ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
19
+ /** Check if string is a valid Ethereum address */
20
+ function isValidAddress(address) {
21
+ return exports.ETH_ADDRESS_REGEX.test(address);
22
+ }
23
+ /**
24
+ * Tron mainnet address shape: 34 chars, leading "T", base58 alphabet (no
25
+ * 0/O/I/l). Shape alone is NOT sufficient to accept an address -- see
26
+ * `isValidTronAddress`, which also verifies the base58check checksum.
27
+ */
28
+ exports.TRON_ADDRESS_REGEX = /^T[1-9A-HJ-NP-Za-km-z]{33}$/;
29
+ const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
30
+ /** Decoded Tron address: 0x41 prefix + 20 address bytes + 4 checksum bytes. */
31
+ const TRON_DECODED_BYTES = 25;
32
+ const TRON_ADDRESS_PREFIX = 0x41;
33
+ /** Decode base58 into bytes. Returns null on any character outside the alphabet. */
34
+ function base58Decode(input) {
35
+ let acc = 0n;
36
+ for (const char of input) {
37
+ const digit = BASE58_ALPHABET.indexOf(char);
38
+ if (digit < 0)
39
+ return null;
40
+ acc = acc * 58n + BigInt(digit);
41
+ }
42
+ const bytes = [];
43
+ while (acc > 0n) {
44
+ bytes.unshift(Number(acc % 256n));
45
+ acc /= 256n;
46
+ }
47
+ // Every leading '1' in base58 encodes one leading zero byte.
48
+ for (const char of input) {
49
+ if (char !== BASE58_ALPHABET[0])
50
+ break;
51
+ bytes.unshift(0);
52
+ }
53
+ return Uint8Array.from(bytes);
54
+ }
55
+ /**
56
+ * Validate a Tron address, checksum included.
57
+ *
58
+ * The shape regex alone accepts any typo that keeps the length and alphabet,
59
+ * which is nearly all of them. Base58check carries a 4-byte checksum, so a
60
+ * mistyped address survives it with probability about 1 in 4 billion. That
61
+ * matters here specifically because a Tron payout recipient is typed by hand on
62
+ * an EVM-origin swap: there is no Tron wallet in the flow to catch it later, and
63
+ * a TRC-20 transfer to a well-formed but unowned address is irrecoverable.
64
+ *
65
+ * Checksum = first 4 bytes of sha256(sha256(0x41 || address_bytes)).
66
+ */
67
+ function isValidTronAddress(address) {
68
+ if (!exports.TRON_ADDRESS_REGEX.test(address))
69
+ return false;
70
+ const decoded = base58Decode(address);
71
+ if (!decoded || decoded.length !== TRON_DECODED_BYTES)
72
+ return false;
73
+ if (decoded[0] !== TRON_ADDRESS_PREFIX)
74
+ return false;
75
+ const payload = decoded.subarray(0, 21);
76
+ const checksum = decoded.subarray(21);
77
+ const digest = (0, viem_1.sha256)((0, viem_1.sha256)(payload, "bytes"), "bytes");
78
+ return checksum.every((byte, i) => byte === digest[i]);
79
+ }