@debridge-finance/borderless-validation-sdk 0.0.0-dev-dee2389 → 0.0.0-dev-25d2153

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 (225) hide show
  1. package/README.md +164 -0
  2. package/dist/cjs/helpers/address.js +31 -18
  3. package/dist/cjs/helpers/address.js.map +1 -1
  4. package/dist/cjs/helpers/evm-action.js +3 -3
  5. package/dist/cjs/helpers/evm-action.js.map +1 -1
  6. package/dist/cjs/helpers/evm-gas-compensation-tx.js +102 -0
  7. package/dist/cjs/helpers/evm-gas-compensation-tx.js.map +1 -0
  8. package/dist/cjs/helpers/evm-intent-id.js +1 -1
  9. package/dist/cjs/helpers/evm-intent-id.js.map +1 -1
  10. package/dist/cjs/helpers/gas-compensation.js +36 -0
  11. package/dist/cjs/helpers/gas-compensation.js.map +1 -0
  12. package/dist/cjs/helpers/placeholder.js +174 -0
  13. package/dist/cjs/helpers/placeholder.js.map +1 -0
  14. package/dist/cjs/helpers/sets.js +13 -0
  15. package/dist/cjs/helpers/sets.js.map +1 -0
  16. package/dist/cjs/types/enums.js +26 -2
  17. package/dist/cjs/types/enums.js.map +1 -1
  18. package/dist/cjs/types/request.js +25 -2
  19. package/dist/cjs/types/request.js.map +1 -1
  20. package/dist/cjs/types/response.js +119 -3
  21. package/dist/cjs/types/response.js.map +1 -1
  22. package/dist/cjs/types/validation.js +72 -8
  23. package/dist/cjs/types/validation.js.map +1 -1
  24. package/dist/cjs/validations/compensation-hook.js +203 -0
  25. package/dist/cjs/validations/compensation-hook.js.map +1 -0
  26. package/dist/cjs/validations/evm-caveats.js +4 -14
  27. package/dist/cjs/validations/evm-caveats.js.map +1 -1
  28. package/dist/cjs/validations/evm-op-budget.js +3 -3
  29. package/dist/cjs/validations/evm-op-budget.js.map +1 -1
  30. package/dist/cjs/validations/evm-op-hook.js +410 -3
  31. package/dist/cjs/validations/evm-op-hook.js.map +1 -1
  32. package/dist/cjs/validations/evm-op-wrap.js +3 -3
  33. package/dist/cjs/validations/evm-op-wrap.js.map +1 -1
  34. package/dist/cjs/validations/evm-required-actions.js +4 -6
  35. package/dist/cjs/validations/evm-required-actions.js.map +1 -1
  36. package/dist/cjs/validations/evm-sign712-metamask.js +17 -94
  37. package/dist/cjs/validations/evm-sign712-metamask.js.map +1 -1
  38. package/dist/cjs/validations/evm-sign712-shared.js +116 -0
  39. package/dist/cjs/validations/evm-sign712-shared.js.map +1 -0
  40. package/dist/cjs/validations/evm-sign7702.js +34 -22
  41. package/dist/cjs/validations/evm-sign7702.js.map +1 -1
  42. package/dist/cjs/validations/hooks-common.js +247 -35
  43. package/dist/cjs/validations/hooks-common.js.map +1 -1
  44. package/dist/cjs/validations/intent-destinations.js +197 -0
  45. package/dist/cjs/validations/intent-destinations.js.map +1 -0
  46. package/dist/cjs/validations/intent-tokens.js +341 -0
  47. package/dist/cjs/validations/intent-tokens.js.map +1 -0
  48. package/dist/cjs/validations/intent.js +288 -0
  49. package/dist/cjs/validations/intent.js.map +1 -0
  50. package/dist/cjs/validations/required-actions.js +2 -5
  51. package/dist/cjs/validations/required-actions.js.map +1 -1
  52. package/dist/cjs/validations/solana-hook.js +32 -18
  53. package/dist/cjs/validations/solana-hook.js.map +1 -1
  54. package/dist/cjs/validations/trades.js +5 -0
  55. package/dist/cjs/validations/trades.js.map +1 -1
  56. package/dist/cjs/validator.js +8 -1
  57. package/dist/cjs/validator.js.map +1 -1
  58. package/dist/cjs/whitelists/environment-config.js +47 -15
  59. package/dist/cjs/whitelists/environment-config.js.map +1 -1
  60. package/dist/cjs/whitelists/evm/caveat-enforcers.js +21 -5
  61. package/dist/cjs/whitelists/evm/caveat-enforcers.js.map +1 -1
  62. package/dist/cjs/whitelists/evm/delegation-manager.js +7 -2
  63. package/dist/cjs/whitelists/evm/delegation-manager.js.map +1 -1
  64. package/dist/cjs/whitelists/evm/eip7702-delegation.js +7 -2
  65. package/dist/cjs/whitelists/evm/eip7702-delegation.js.map +1 -1
  66. package/dist/cjs/whitelists/evm/index.js +14 -1
  67. package/dist/cjs/whitelists/evm/index.js.map +1 -1
  68. package/dist/cjs/whitelists/evm/metamask-delegation-chains.js +16 -0
  69. package/dist/cjs/whitelists/evm/metamask-delegation-chains.js.map +1 -0
  70. package/dist/cjs/whitelists/evm/permit2.js +16 -12
  71. package/dist/cjs/whitelists/evm/permit2.js.map +1 -1
  72. package/dist/cjs/whitelists/evm/weth.js +16 -5
  73. package/dist/cjs/whitelists/evm/weth.js.map +1 -1
  74. package/dist/cjs/whitelists/solana/intent-signature.js +0 -1
  75. package/dist/cjs/whitelists/solana/intent-signature.js.map +1 -1
  76. package/dist/cjs/whitelists/subscription-to-chain-id.js +10 -0
  77. package/dist/cjs/whitelists/subscription-to-chain-id.js.map +1 -1
  78. package/dist/cjs/whitelists/types.js +13 -3
  79. package/dist/cjs/whitelists/types.js.map +1 -1
  80. package/dist/esm/helpers/address.js +28 -17
  81. package/dist/esm/helpers/address.js.map +1 -1
  82. package/dist/esm/helpers/evm-action.js +3 -3
  83. package/dist/esm/helpers/evm-action.js.map +1 -1
  84. package/dist/esm/helpers/evm-gas-compensation-tx.js +99 -0
  85. package/dist/esm/helpers/evm-gas-compensation-tx.js.map +1 -0
  86. package/dist/esm/helpers/evm-intent-id.js +1 -1
  87. package/dist/esm/helpers/evm-intent-id.js.map +1 -1
  88. package/dist/esm/helpers/gas-compensation.js +33 -0
  89. package/dist/esm/helpers/gas-compensation.js.map +1 -0
  90. package/dist/esm/helpers/placeholder.js +168 -0
  91. package/dist/esm/helpers/placeholder.js.map +1 -0
  92. package/dist/esm/helpers/sets.js +10 -0
  93. package/dist/esm/helpers/sets.js.map +1 -0
  94. package/dist/esm/types/enums.js +25 -1
  95. package/dist/esm/types/enums.js.map +1 -1
  96. package/dist/esm/types/request.js +26 -3
  97. package/dist/esm/types/request.js.map +1 -1
  98. package/dist/esm/types/response.js +118 -2
  99. package/dist/esm/types/response.js.map +1 -1
  100. package/dist/esm/types/validation.js +72 -8
  101. package/dist/esm/types/validation.js.map +1 -1
  102. package/dist/esm/validations/compensation-hook.js +200 -0
  103. package/dist/esm/validations/compensation-hook.js.map +1 -0
  104. package/dist/esm/validations/evm-caveats.js +4 -14
  105. package/dist/esm/validations/evm-caveats.js.map +1 -1
  106. package/dist/esm/validations/evm-op-budget.js +3 -3
  107. package/dist/esm/validations/evm-op-budget.js.map +1 -1
  108. package/dist/esm/validations/evm-op-hook.js +409 -2
  109. package/dist/esm/validations/evm-op-hook.js.map +1 -1
  110. package/dist/esm/validations/evm-op-wrap.js +3 -3
  111. package/dist/esm/validations/evm-op-wrap.js.map +1 -1
  112. package/dist/esm/validations/evm-required-actions.js +4 -6
  113. package/dist/esm/validations/evm-required-actions.js.map +1 -1
  114. package/dist/esm/validations/evm-sign712-metamask.js +17 -94
  115. package/dist/esm/validations/evm-sign712-metamask.js.map +1 -1
  116. package/dist/esm/validations/evm-sign712-shared.js +110 -0
  117. package/dist/esm/validations/evm-sign712-shared.js.map +1 -0
  118. package/dist/esm/validations/evm-sign7702.js +33 -22
  119. package/dist/esm/validations/evm-sign7702.js.map +1 -1
  120. package/dist/esm/validations/hooks-common.js +246 -36
  121. package/dist/esm/validations/hooks-common.js.map +1 -1
  122. package/dist/esm/validations/intent-destinations.js +194 -0
  123. package/dist/esm/validations/intent-destinations.js.map +1 -0
  124. package/dist/esm/validations/intent-tokens.js +338 -0
  125. package/dist/esm/validations/intent-tokens.js.map +1 -0
  126. package/dist/esm/validations/intent.js +285 -0
  127. package/dist/esm/validations/intent.js.map +1 -0
  128. package/dist/esm/validations/required-actions.js +2 -5
  129. package/dist/esm/validations/required-actions.js.map +1 -1
  130. package/dist/esm/validations/solana-hook.js +34 -20
  131. package/dist/esm/validations/solana-hook.js.map +1 -1
  132. package/dist/esm/validations/trades.js +5 -0
  133. package/dist/esm/validations/trades.js.map +1 -1
  134. package/dist/esm/validator.js +8 -1
  135. package/dist/esm/validator.js.map +1 -1
  136. package/dist/esm/whitelists/environment-config.js +47 -15
  137. package/dist/esm/whitelists/environment-config.js.map +1 -1
  138. package/dist/esm/whitelists/evm/caveat-enforcers.js +20 -4
  139. package/dist/esm/whitelists/evm/caveat-enforcers.js.map +1 -1
  140. package/dist/esm/whitelists/evm/delegation-manager.js +6 -1
  141. package/dist/esm/whitelists/evm/delegation-manager.js.map +1 -1
  142. package/dist/esm/whitelists/evm/eip7702-delegation.js +6 -1
  143. package/dist/esm/whitelists/evm/eip7702-delegation.js.map +1 -1
  144. package/dist/esm/whitelists/evm/index.js +4 -4
  145. package/dist/esm/whitelists/evm/index.js.map +1 -1
  146. package/dist/esm/whitelists/evm/metamask-delegation-chains.js +13 -0
  147. package/dist/esm/whitelists/evm/metamask-delegation-chains.js.map +1 -0
  148. package/dist/esm/whitelists/evm/permit2.js +9 -5
  149. package/dist/esm/whitelists/evm/permit2.js.map +1 -1
  150. package/dist/esm/whitelists/evm/weth.js +16 -5
  151. package/dist/esm/whitelists/evm/weth.js.map +1 -1
  152. package/dist/esm/whitelists/solana/intent-signature.js +0 -1
  153. package/dist/esm/whitelists/solana/intent-signature.js.map +1 -1
  154. package/dist/esm/whitelists/subscription-to-chain-id.js +9 -0
  155. package/dist/esm/whitelists/subscription-to-chain-id.js.map +1 -1
  156. package/dist/esm/whitelists/types.js +14 -5
  157. package/dist/esm/whitelists/types.js.map +1 -1
  158. package/dist/types/helpers/address.d.ts +5 -7
  159. package/dist/types/helpers/address.d.ts.map +1 -1
  160. package/dist/types/helpers/evm-gas-compensation-tx.d.ts +13 -0
  161. package/dist/types/helpers/evm-gas-compensation-tx.d.ts.map +1 -0
  162. package/dist/types/helpers/gas-compensation.d.ts +10 -0
  163. package/dist/types/helpers/gas-compensation.d.ts.map +1 -0
  164. package/dist/types/helpers/placeholder.d.ts +41 -0
  165. package/dist/types/helpers/placeholder.d.ts.map +1 -0
  166. package/dist/types/helpers/sets.d.ts +2 -0
  167. package/dist/types/helpers/sets.d.ts.map +1 -0
  168. package/dist/types/types/enums.d.ts +19 -1
  169. package/dist/types/types/enums.d.ts.map +1 -1
  170. package/dist/types/types/request.d.ts +19 -9
  171. package/dist/types/types/request.d.ts.map +1 -1
  172. package/dist/types/types/response.d.ts +365 -9
  173. package/dist/types/types/response.d.ts.map +1 -1
  174. package/dist/types/types/validation.d.ts +64 -8
  175. package/dist/types/types/validation.d.ts.map +1 -1
  176. package/dist/types/validations/compensation-hook.d.ts +3 -0
  177. package/dist/types/validations/compensation-hook.d.ts.map +1 -0
  178. package/dist/types/validations/evm-caveats.d.ts.map +1 -1
  179. package/dist/types/validations/evm-op-hook.d.ts +4 -2
  180. package/dist/types/validations/evm-op-hook.d.ts.map +1 -1
  181. package/dist/types/validations/evm-required-actions.d.ts.map +1 -1
  182. package/dist/types/validations/evm-sign712-metamask.d.ts.map +1 -1
  183. package/dist/types/validations/evm-sign712-shared.d.ts +7 -0
  184. package/dist/types/validations/evm-sign712-shared.d.ts.map +1 -0
  185. package/dist/types/validations/evm-sign7702.d.ts +2 -1
  186. package/dist/types/validations/evm-sign7702.d.ts.map +1 -1
  187. package/dist/types/validations/hooks-common.d.ts +1 -0
  188. package/dist/types/validations/hooks-common.d.ts.map +1 -1
  189. package/dist/types/validations/intent-destinations.d.ts +4 -0
  190. package/dist/types/validations/intent-destinations.d.ts.map +1 -0
  191. package/dist/types/validations/intent-tokens.d.ts +4 -0
  192. package/dist/types/validations/intent-tokens.d.ts.map +1 -0
  193. package/dist/types/validations/intent.d.ts +5 -0
  194. package/dist/types/validations/intent.d.ts.map +1 -0
  195. package/dist/types/validations/required-actions.d.ts +2 -1
  196. package/dist/types/validations/required-actions.d.ts.map +1 -1
  197. package/dist/types/validations/solana-hook.d.ts +4 -2
  198. package/dist/types/validations/solana-hook.d.ts.map +1 -1
  199. package/dist/types/validator.d.ts.map +1 -1
  200. package/dist/types/whitelists/environment-config.d.ts.map +1 -1
  201. package/dist/types/whitelists/evm/caveat-enforcers.d.ts +8 -0
  202. package/dist/types/whitelists/evm/caveat-enforcers.d.ts.map +1 -1
  203. package/dist/types/whitelists/evm/delegation-manager.d.ts +2 -0
  204. package/dist/types/whitelists/evm/delegation-manager.d.ts.map +1 -1
  205. package/dist/types/whitelists/evm/eip7702-delegation.d.ts +2 -0
  206. package/dist/types/whitelists/evm/eip7702-delegation.d.ts.map +1 -1
  207. package/dist/types/whitelists/evm/index.d.ts +4 -4
  208. package/dist/types/whitelists/evm/index.d.ts.map +1 -1
  209. package/dist/types/whitelists/evm/metamask-delegation-chains.d.ts +3 -0
  210. package/dist/types/whitelists/evm/metamask-delegation-chains.d.ts.map +1 -0
  211. package/dist/types/whitelists/evm/permit2.d.ts +1 -0
  212. package/dist/types/whitelists/evm/permit2.d.ts.map +1 -1
  213. package/dist/types/whitelists/evm/weth.d.ts.map +1 -1
  214. package/dist/types/whitelists/solana/intent-signature.d.ts.map +1 -1
  215. package/dist/types/whitelists/subscription-to-chain-id.d.ts +1 -0
  216. package/dist/types/whitelists/subscription-to-chain-id.d.ts.map +1 -1
  217. package/dist/types/whitelists/types.d.ts +1 -0
  218. package/dist/types/whitelists/types.d.ts.map +1 -1
  219. package/package.json +2 -2
  220. package/dist/cjs/validations/evm-op-gas-compensation.js +0 -152
  221. package/dist/cjs/validations/evm-op-gas-compensation.js.map +0 -1
  222. package/dist/esm/validations/evm-op-gas-compensation.js +0 -149
  223. package/dist/esm/validations/evm-op-gas-compensation.js.map +0 -1
  224. package/dist/types/validations/evm-op-gas-compensation.d.ts +0 -3
  225. package/dist/types/validations/evm-op-gas-compensation.d.ts.map +0 -1
@@ -0,0 +1,338 @@
1
+ import { ViolationCode, SpecialAmount, ChainEngine, } from "../types/index.js";
2
+ import { detectChainEngine, getChainEngine, normalizeAddress, } from "../helpers/address.js";
3
+ import { resolveWrappedTokenAddress } from "../helpers/evm-token.js";
4
+ import { resolveChainId } from "../whitelists/subscription-to-chain-id.js";
5
+ export function validateIntentTokens(intent, group, basePath) {
6
+ const resolution = resolveGroupInputTokens(group);
7
+ return [
8
+ ...resolution.violations,
9
+ ...validateInputTokens(intent.inputToken, group, resolution.expected, `${basePath}.inputToken`),
10
+ ...validateGiveTokens(intent, group, `${basePath}.giveToken`),
11
+ ...validateTakeTokens(intent, group, `${basePath}.takeToken`),
12
+ ];
13
+ }
14
+ // Resolves every request trade's srcChainTokenIn to its expected on-chain
15
+ // address (wrapped mint for native tokens) and returns the deduplicated set.
16
+ // A trade fails to resolve when it specifies a native token for a chain that
17
+ // has no WETH mapping in our whitelist. Each failure emits a dedicated violation
18
+ // so the caller knows which trade is unverifiable.
19
+ function resolveGroupInputTokens(group) {
20
+ const expected = new Set();
21
+ const violations = [];
22
+ for (let i = 0; i < group.trades.length; i++) {
23
+ const trade = group.trades[i];
24
+ const resolved = resolveWrappedTokenAddress(trade.srcChainTokenIn, group.realChainId);
25
+ if (resolved === undefined) {
26
+ violations.push({
27
+ code: ViolationCode.IntentInputTokenWrappedAddressUnknown,
28
+ message: "cannot resolve wrapped token address: native token on a"
29
+ + " chain with no WETH mapping in the whitelist",
30
+ path: `request.trades[${group.tradeIndices[i]}].srcChainTokenIn`,
31
+ actual: trade.srcChainTokenIn,
32
+ });
33
+ continue;
34
+ }
35
+ expected.add(normalizeAddress(group.realChainId, resolved));
36
+ }
37
+ return { expected, violations };
38
+ }
39
+ // CRITICAL: intent.inputToken[] must represent exactly the set of unique
40
+ // srcChainTokenIn addresses from the group's trades (native → wrapped).
41
+ // Missing expected addresses, duplicate entries, and unknown addresses are
42
+ // each reported as specific violations.
43
+ function validateInputTokens(inputTokens, group, expectedTokens, basePath) {
44
+ const actual = inputTokens ?? [];
45
+ const violations = [];
46
+ const actualAddresses = actual.map(t => normalizeAddress(group.realChainId, t.address));
47
+ const firstOccurrence = new Map();
48
+ for (let i = 0; i < actualAddresses.length; i++) {
49
+ const address = actualAddresses[i];
50
+ const earlier = firstOccurrence.get(address);
51
+ if (earlier !== undefined) {
52
+ violations.push({
53
+ code: ViolationCode.IntentInputTokenDuplicate,
54
+ message: `intent.inputToken[${i}] duplicates the entry at index `
55
+ + `${earlier} — each srcChainTokenIn (or its wrapped `
56
+ + `equivalent) must appear once`,
57
+ path: `${basePath}[${i}].address`,
58
+ actual: address,
59
+ });
60
+ }
61
+ else {
62
+ firstOccurrence.set(address, i);
63
+ }
64
+ }
65
+ for (const expectedToken of expectedTokens) {
66
+ if (!firstOccurrence.has(expectedToken)) {
67
+ violations.push({
68
+ code: ViolationCode.IntentInputTokenMissing,
69
+ message: "an expected srcChainTokenIn address (or its wrapped "
70
+ + "equivalent) is missing from intent.inputToken[]",
71
+ path: basePath,
72
+ expected: expectedToken,
73
+ });
74
+ }
75
+ }
76
+ // Validate each unique entry (duplicates were already reported above)
77
+ for (const [address, i] of firstOccurrence) {
78
+ if (!expectedTokens.has(address)) {
79
+ violations.push({
80
+ code: ViolationCode.IntentInputTokenAddressMismatch,
81
+ message: "intent.inputToken[].address does not match any request"
82
+ + " srcChainTokenIn (including native-to-wrapped resolution)",
83
+ path: `${basePath}[${i}].address`,
84
+ expected: Array.from(expectedTokens),
85
+ actual: address,
86
+ });
87
+ continue;
88
+ }
89
+ violations.push(...validateConstraintBudget(actual[i], group, address, `${basePath}[${i}]`));
90
+ }
91
+ return violations;
92
+ }
93
+ // CRITICAL: constraintBudget equals the sum of request amounts for trades
94
+ // whose srcChainTokenIn resolves to this inputToken.address.
95
+ // Skipped when any contributing trade has non-numeric amount ('auto'/'max')
96
+ // or when any has prependOperatingExpenses=true (API adds unpredictable costs).
97
+ function validateConstraintBudget(inputToken, group, normalizedAddress, basePath) {
98
+ const contributingTrades = group.trades.filter(trade => {
99
+ const resolved = resolveWrappedTokenAddress(trade.srcChainTokenIn, group.realChainId);
100
+ // Safe skip: unresolved input tokens are already reported by
101
+ // resolveGroupInputTokens.
102
+ if (resolved === undefined)
103
+ return false;
104
+ return normalizeAddress(group.realChainId, resolved) === normalizedAddress;
105
+ });
106
+ if (!canPredictBudget(contributingTrades)) {
107
+ return [];
108
+ }
109
+ const expectedSum = contributingTrades.reduce((acc, trade) => acc + BigInt(trade.srcChainTokenInAmount), 0n);
110
+ let actualBudget;
111
+ try {
112
+ actualBudget = BigInt(inputToken.constraintBudget);
113
+ }
114
+ catch (error) {
115
+ return [{
116
+ code: ViolationCode.IntentNumericValueInvalid,
117
+ message: "intent.inputToken[].constraintBudget is not a valid number",
118
+ path: `${basePath}.constraintBudget`,
119
+ actual: inputToken.constraintBudget,
120
+ details: error,
121
+ }];
122
+ }
123
+ if (actualBudget !== expectedSum) {
124
+ return [{
125
+ code: ViolationCode.IntentConstraintBudgetMismatch,
126
+ message: "intent.inputToken[].constraintBudget must equal the sum of"
127
+ + " request srcChainTokenInAmount values for the matching trades",
128
+ path: `${basePath}.constraintBudget`,
129
+ expected: expectedSum.toString(),
130
+ actual: inputToken.constraintBudget,
131
+ }];
132
+ }
133
+ return [];
134
+ }
135
+ function canPredictBudget(trades) {
136
+ return trades.every(trade => isNumericAmount(trade.srcChainTokenInAmount) &&
137
+ trade.prependOperatingExpenses !== true);
138
+ }
139
+ function isNumericAmount(amount) {
140
+ if (amount === SpecialAmount.Auto || amount === SpecialAmount.Max)
141
+ return false;
142
+ try {
143
+ BigInt(amount);
144
+ return true;
145
+ }
146
+ catch {
147
+ return false;
148
+ }
149
+ }
150
+ // CRITICAL: each giveToken[].inputTokenAddress must equal one of
151
+ // intent.inputToken[].address that is used by at least one cross-chain trade
152
+ // in the group. Same-chain trades do not produce giveToken entries.
153
+ // inputToken[] is separately validated against the request, so this rule
154
+ // forms a chain of trust: give → input → request.
155
+ function validateGiveTokens(intent, group, basePath) {
156
+ const allowed = collectInputAddressesForCrossChainTrades(intent, group);
157
+ const giveTokens = intent.giveToken ?? [];
158
+ if (allowed.size === 0) {
159
+ if (giveTokens.length > 0) {
160
+ return [{
161
+ code: ViolationCode.IntentGiveTokenNotEmptyForSameChain,
162
+ message: "intent.giveToken[] must be empty or undefined when no"
163
+ + " trade in the group is cross-chain",
164
+ path: basePath,
165
+ expected: 0,
166
+ actual: giveTokens.length,
167
+ }];
168
+ }
169
+ return [];
170
+ }
171
+ const violations = [];
172
+ const expectedFormat = getChainEngine(group.realChainId);
173
+ for (let i = 0; i < giveTokens.length; i++) {
174
+ const normalized = normalizeAddress(group.realChainId, giveTokens[i].inputTokenAddress);
175
+ if (!allowed.has(normalized)) {
176
+ violations.push({
177
+ code: ViolationCode.IntentGiveTokenInputAddressMismatch,
178
+ message: "intent.giveToken[].inputTokenAddress must equal one of"
179
+ + " intent.inputToken[].address used by a cross-chain"
180
+ + " trade in the group",
181
+ path: `${basePath}[${i}].inputTokenAddress`,
182
+ expected: Array.from(allowed),
183
+ actual: giveTokens[i].inputTokenAddress,
184
+ });
185
+ }
186
+ // CRITICAL: giveTokenAddress is a bridge token in src chain — its value
187
+ // is API-determined and unpredictable, but its format must match the
188
+ // intent chain's engine.
189
+ const actualFormat = detectChainEngine(giveTokens[i].giveTokenAddress);
190
+ if (actualFormat !== expectedFormat) {
191
+ violations.push({
192
+ code: ViolationCode.IntentGiveTokenAddressFormatMismatch,
193
+ message: `intent.giveToken[].giveTokenAddress format (${ChainEngine[actualFormat]})`
194
+ + ` does not match the intent chain engine`
195
+ + ` (${ChainEngine[expectedFormat]})`,
196
+ path: `${basePath}[${i}].giveTokenAddress`,
197
+ expected: ChainEngine[expectedFormat],
198
+ actual: giveTokens[i].giveTokenAddress,
199
+ });
200
+ }
201
+ }
202
+ return violations;
203
+ }
204
+ // Returns the subset of intent.inputToken[].address values that also appear
205
+ // as the (native-resolved) srcChainTokenIn of a cross-chain trade in the group.
206
+ function collectInputAddressesForCrossChainTrades(intent, group) {
207
+ const inputAddresses = new Set((intent.inputToken ?? []).map(t => normalizeAddress(group.realChainId, t.address)));
208
+ const result = new Set();
209
+ for (const trade of group.trades) {
210
+ if (!isCrossChain(trade))
211
+ continue;
212
+ const resolved = resolveWrappedTokenAddress(trade.srcChainTokenIn, group.realChainId);
213
+ // Safe skip: unresolved input tokens are already reported by
214
+ // resolveGroupInputTokens.
215
+ if (resolved === undefined)
216
+ continue;
217
+ const normalized = normalizeAddress(group.realChainId, resolved);
218
+ if (inputAddresses.has(normalized)) {
219
+ result.add(normalized);
220
+ }
221
+ }
222
+ return result;
223
+ }
224
+ function isCrossChain(trade) {
225
+ return trade.srcChainId !== trade.dstChainId;
226
+ }
227
+ // CRITICAL: intent.takeToken[] must represent exactly the set of unique
228
+ // (dstChainId, dstChainTokenOut) pairs from the group's trades. Missing pairs,
229
+ // duplicate entries, and unknown chainId/address combinations are each reported
230
+ // as specific violations.
231
+ // CRITICAL: fromTokenAddress must be in inputToken[] (same-chain) or giveToken[]
232
+ // (cross-chain).
233
+ function validateTakeTokens(intent, group, basePath) {
234
+ const violations = [];
235
+ const expectedTakeTokens = buildExpectedTakeTokens(group);
236
+ const actualKeys = intent.takeToken.map(takeToken => buildTakeTokenKey(takeToken));
237
+ const firstOccurrence = new Map();
238
+ for (let i = 0; i < actualKeys.length; i++) {
239
+ const key = actualKeys[i];
240
+ const earlier = firstOccurrence.get(key);
241
+ if (earlier !== undefined) {
242
+ violations.push({
243
+ code: ViolationCode.IntentTakeTokenDuplicate,
244
+ message: `intent.takeToken[${i}] duplicates the entry at`
245
+ + ` index ${earlier} — each (takeTokenChainId,`
246
+ + ` takeTokenAddress) pair must appear once`,
247
+ path: `${basePath}[${i}]`,
248
+ actual: key,
249
+ });
250
+ }
251
+ else {
252
+ firstOccurrence.set(key, i);
253
+ }
254
+ }
255
+ for (const expectedTakeToken of expectedTakeTokens) {
256
+ if (!firstOccurrence.has(expectedTakeToken)) {
257
+ violations.push({
258
+ code: ViolationCode.IntentTakeTokenMissing,
259
+ message: "an expected (dstChainId, dstChainTokenOut) pair is"
260
+ + " missing from intent.takeToken[]",
261
+ path: basePath,
262
+ expected: expectedTakeToken,
263
+ });
264
+ }
265
+ }
266
+ // Validate each unique entry (duplicates are already reported above)
267
+ for (const [, i] of firstOccurrence) {
268
+ violations.push(...validateSingleTakeToken(intent, intent.takeToken[i], group, expectedTakeTokens, `${basePath}[${i}]`));
269
+ }
270
+ return violations;
271
+ }
272
+ // Single source of truth for the "chainId:normalizedAddress" key format used
273
+ // to compare takeToken entries as a set. If realChainId is unknown we skip
274
+ // normalization so the function can still produce a deterministic key for
275
+ // duplicate detection; the chainId mismatch is flagged separately.
276
+ function buildChainTokenKey(chainId, realChainId, address) {
277
+ const normalized = realChainId !== undefined
278
+ ? normalizeAddress(realChainId, address)
279
+ : address;
280
+ return `${chainId}:${normalized}`;
281
+ }
282
+ function buildTakeTokenKey(takeToken) {
283
+ return buildChainTokenKey(takeToken.takeTokenChainId, resolveChainId(takeToken.takeTokenChainId), takeToken.takeTokenAddress);
284
+ }
285
+ function buildExpectedTakeTokens(group) {
286
+ const set = new Set();
287
+ for (const trade of group.trades) {
288
+ const dstRealChainId = resolveChainId(trade.dstChainId);
289
+ // Safe skip: unknown subscriptionId for dstChainId is reported elsewhere
290
+ // (validateTrades reports UnknownSubscriptionId for dstChainId)
291
+ if (dstRealChainId === undefined)
292
+ continue;
293
+ set.add(buildChainTokenKey(trade.dstChainId, dstRealChainId, trade.dstChainTokenOut));
294
+ }
295
+ return set;
296
+ }
297
+ function validateSingleTakeToken(intent, takeToken, group, expected, basePath) {
298
+ const violations = [];
299
+ const dstRealChainId = resolveChainId(takeToken.takeTokenChainId);
300
+ // Safe skip: unknown subscriptionId for dstChainId is reported elsewhere
301
+ // (validateTrades reports UnknownSubscriptionId for dstChainId)
302
+ if (dstRealChainId !== undefined) {
303
+ const key = buildChainTokenKey(takeToken.takeTokenChainId, dstRealChainId, takeToken.takeTokenAddress);
304
+ if (!expected.has(key)) {
305
+ violations.push({
306
+ code: ViolationCode.IntentTakeTokenAddressMismatch,
307
+ message: "intent.takeToken[] (takeTokenChainId, takeTokenAddress)"
308
+ + " pair does not match any request (dstChainId,"
309
+ + " dstChainTokenOut) pair in the trade group",
310
+ path: basePath,
311
+ expected: Array.from(expected),
312
+ actual: key,
313
+ });
314
+ }
315
+ }
316
+ violations.push(...validateTakeTokenFromAddress(intent, takeToken, group, basePath));
317
+ return violations;
318
+ }
319
+ function validateTakeTokenFromAddress(intent, takeToken, group, basePath) {
320
+ const isSameChain = takeToken.takeTokenChainId === group.srcChainId;
321
+ const normalized = normalizeAddress(group.realChainId, takeToken.fromTokenAddress);
322
+ const allowedSet = isSameChain
323
+ ? new Set((intent.inputToken ?? []).map(t => normalizeAddress(group.realChainId, t.address)))
324
+ : new Set((intent.giveToken ?? []).map(t => normalizeAddress(group.realChainId, t.giveTokenAddress)));
325
+ if (!allowedSet.has(normalized)) {
326
+ return [{
327
+ code: ViolationCode.IntentTakeTokenFromAddressInvalid,
328
+ message: isSameChain
329
+ ? "intent.takeToken[].fromTokenAddress must be present in intent.inputToken[].address for same-chain trades"
330
+ : "intent.takeToken[].fromTokenAddress must be present in intent.giveToken[].giveTokenAddress for cross-chain trades",
331
+ path: `${basePath}.fromTokenAddress`,
332
+ expected: Array.from(allowedSet),
333
+ actual: takeToken.fromTokenAddress,
334
+ }];
335
+ }
336
+ return [];
337
+ }
338
+ //# sourceMappingURL=intent-tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent-tokens.js","sourceRoot":"","sources":["../../../src/validations/intent-tokens.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,285 @@
1
+ import { keccak256, zeroHash } from "viem";
2
+ import { ViolationCode, ChainId, } from "../types/index.js";
3
+ import { addressEquals, normalizeAddress } from "../helpers/address.js";
4
+ import { setsEqual } from "../helpers/sets.js";
5
+ import { computeIntentId } from "../helpers/evm-intent-id.js";
6
+ import { computeSolanaIntentId } from "../helpers/solana-intent-id.js";
7
+ import { validateIntentTokens } from "./intent-tokens.js";
8
+ import { validateIntentDestinations } from "./intent-destinations.js";
9
+ export function validateIntents(contexts, quoteMode, envConfig) {
10
+ const violations = [];
11
+ for (const ctx of contexts) {
12
+ violations.push(...validateSingleIntent(ctx, quoteMode, envConfig));
13
+ }
14
+ return violations;
15
+ }
16
+ function validateSingleIntent(ctx, quoteMode, envConfig) {
17
+ const basePath = `response.intents[${ctx.intentIndex}].intent`;
18
+ const intent = ctx.intentPayload.intent;
19
+ const group = ctx.tradeGroup;
20
+ const violations = [
21
+ ...validateNonNegativeNumerics(intent, basePath),
22
+ ...validateIntentDifferentiationFields(intent, group, basePath),
23
+ ...validateIntentTokens(intent, group, basePath),
24
+ ...validateIntentDestinations(intent, group, basePath, quoteMode),
25
+ ];
26
+ if (!quoteMode) {
27
+ violations.push(...validateExecutionIdentity(intent, group, basePath, envConfig), ...validateAllowedCancelBeneficiary(intent, group, basePath), ...validateSrcAllowedSender(intent, group, basePath));
28
+ }
29
+ return violations;
30
+ }
31
+ // CRITICAL (execution): intentOwner and intentAuthority must equal srcChainAuthorityAddress.
32
+ // CRITICAL (execution): intentId must equal the hash/PDA computed from the intent struct.
33
+ function validateExecutionIdentity(intent, group, basePath, envConfig) {
34
+ const violations = [];
35
+ const expectedOwner = group.srcChainAuthorityAddress;
36
+ const ownerUnverifiable = expectedOwner === undefined;
37
+ if (ownerUnverifiable
38
+ || !addressEquals(group.realChainId, intent.intentOwner, expectedOwner)) {
39
+ violations.push({
40
+ code: ViolationCode.IntentOwnerMismatch,
41
+ message: ownerUnverifiable
42
+ ? "cannot verify intent.intentOwner: request trade has no srcChainAuthorityAddress in execution mode"
43
+ : "intent.intentOwner must equal srcChainAuthorityAddress",
44
+ path: `${basePath}.intentOwner`,
45
+ expected: expectedOwner,
46
+ actual: intent.intentOwner,
47
+ });
48
+ }
49
+ if (ownerUnverifiable
50
+ || !addressEquals(group.realChainId, intent.intentAuthority, expectedOwner)) {
51
+ violations.push({
52
+ code: ViolationCode.IntentAuthorityMismatch,
53
+ message: ownerUnverifiable
54
+ ? "cannot verify intent.intentAuthority: request trade has no srcChainAuthorityAddress in execution mode"
55
+ : "intent.intentAuthority must equal srcChainAuthorityAddress",
56
+ path: `${basePath}.intentAuthority`,
57
+ expected: expectedOwner,
58
+ actual: intent.intentAuthority,
59
+ });
60
+ }
61
+ violations.push(...validateIntentIdMatches(intent, group, basePath, envConfig));
62
+ return violations;
63
+ }
64
+ function validateIntentIdMatches(intent, group, basePath, envConfig) {
65
+ let computed;
66
+ try {
67
+ computed = group.realChainId === ChainId.Solana
68
+ ? computeSolanaIntentId(intent, group.realChainId, envConfig.solanaIntentProgram)
69
+ : computeIntentId(intent);
70
+ }
71
+ catch (error) {
72
+ return [{
73
+ code: ViolationCode.IntentIdComputeError,
74
+ message: "failed to compute intentId from intent struct",
75
+ path: `${basePath}.intentId`,
76
+ details: error,
77
+ }];
78
+ }
79
+ if (!hexEquals(intent.intentId, computed)) {
80
+ return [{
81
+ code: ViolationCode.IntentIdMismatch,
82
+ message: "intent.intentId does not match the hash of the intent struct",
83
+ path: `${basePath}.intentId`,
84
+ expected: computed,
85
+ actual: intent.intentId,
86
+ }];
87
+ }
88
+ return [];
89
+ }
90
+ // CRITICAL (execution): allowedCancelBeneficiary must equal request
91
+ // srcAllowedCancelBeneficiary (if specified) or fall back to
92
+ // srcChainAuthorityAddress.
93
+ function validateAllowedCancelBeneficiary(intent, group, basePath) {
94
+ const requestValue = group.trades[0].srcAllowedCancelBeneficiary;
95
+ const expected = requestValue ?? group.srcChainAuthorityAddress;
96
+ const actual = intent.allowedCancelBeneficiary;
97
+ // Mixed-mode edge case: the group's authority is undefined AND the request
98
+ // has no srcAllowedCancelBeneficiary, so there is no expected value.
99
+ // See the note on validateExecutionIdentity above.
100
+ if (expected === undefined) {
101
+ return [{
102
+ code: ViolationCode.IntentAllowedCancelBeneficiaryMismatch,
103
+ message: "cannot verify intent.allowedCancelBeneficiary: request trade"
104
+ + " has neither srcAllowedCancelBeneficiary nor srcChainAuthorityAddress"
105
+ + " in execution mode",
106
+ path: `${basePath}.allowedCancelBeneficiary`,
107
+ expected: undefined,
108
+ actual,
109
+ }];
110
+ }
111
+ if (actual === undefined || !addressEquals(group.realChainId, actual, expected)) {
112
+ return [{
113
+ code: ViolationCode.IntentAllowedCancelBeneficiaryMismatch,
114
+ message: requestValue !== undefined
115
+ ? "intent.allowedCancelBeneficiary must equal request srcAllowedCancelBeneficiary"
116
+ : "intent.allowedCancelBeneficiary must fall back to srcChainAuthorityAddress",
117
+ path: `${basePath}.allowedCancelBeneficiary`,
118
+ expected,
119
+ actual,
120
+ }];
121
+ }
122
+ return [];
123
+ }
124
+ // CRITICAL (execution): if any trade in the group has srcAllowedSender,
125
+ // intent.srcAllowedSender must contain exactly those addresses. If none
126
+ // specified, API substitutes its own delegate address (not verifiable — see
127
+ // accepted gap).
128
+ function validateSrcAllowedSender(intent, group, basePath) {
129
+ const requested = group.trades
130
+ .map(t => t.srcAllowedSender)
131
+ .filter((s) => s !== undefined);
132
+ // Safe skip: when no trade specifies srcAllowedSender, the API uses a delegate
133
+ // address from its internal config — we have no whitelist to verify it
134
+ if (requested.length === 0)
135
+ return [];
136
+ const expectedSet = new Set(requested.map(addr => normalizeAddress(group.realChainId, addr)));
137
+ const actualList = intent.srcAllowedSender ?? [];
138
+ const actualSet = new Set(actualList.map(addr => normalizeAddress(group.realChainId, addr)));
139
+ if (!setsEqual(expectedSet, actualSet)) {
140
+ return [{
141
+ code: ViolationCode.IntentSrcAllowedSenderMismatch,
142
+ message: "intent.srcAllowedSender must contain exactly the addresses"
143
+ + " from request srcAllowedSender fields (no extras, no omissions)",
144
+ path: `${basePath}.srcAllowedSender`,
145
+ expected: Array.from(expectedSet),
146
+ actual: actualList,
147
+ }];
148
+ }
149
+ return [];
150
+ }
151
+ // Fields that drive group-to-intent splitting: the API groups request trades by
152
+ // (srcChainId, srcChainAuthorityAddress, dlnHook, metadata) and produces a separate
153
+ // intent for each unique combination. These fields on the intent must reflect the
154
+ // corresponding request trade fields.
155
+ function validateIntentDifferentiationFields(intent, group, basePath) {
156
+ return [
157
+ ...validateExecutionMetadata(intent, basePath),
158
+ ...validateDlnMetadata(intent, group, basePath),
159
+ ...validateExternalCallHash(intent, group, basePath),
160
+ ];
161
+ }
162
+ // CRITICAL: executionMetadata is hardcoded to undefined in the API intent
163
+ // service and never populated.
164
+ // TODO: this logic should be updated when API will start setting executionMetadata.
165
+ function validateExecutionMetadata(intent, basePath) {
166
+ if (isEmptyHex(intent.executionMetadata))
167
+ return [];
168
+ return [{
169
+ code: ViolationCode.IntentExecutionMetadataMismatch,
170
+ message: "intent.executionMetadata must be undefined or empty per current API contract",
171
+ path: `${basePath}.executionMetadata`,
172
+ expected: undefined,
173
+ actual: intent.executionMetadata,
174
+ }];
175
+ }
176
+ // CRITICAL: intent.dlnMetadata must match request.trades[].metadata from one of
177
+ // the trades in the group. When no trade in the group has metadata, the intent
178
+ // field must be empty/undefined.
179
+ function validateDlnMetadata(intent, group, basePath) {
180
+ const expected = new Set();
181
+ for (const trade of group.trades)
182
+ expected.add(trade.metadata);
183
+ if (matchesAnyHex(intent.dlnMetadata, expected))
184
+ return [];
185
+ return [{
186
+ code: ViolationCode.IntentDlnMetadataMismatch,
187
+ message: "intent.dlnMetadata must match one of request.trades[].metadata"
188
+ + " values from the trade group",
189
+ path: `${basePath}.dlnMetadata`,
190
+ expected: Array.from(expected),
191
+ actual: intent.dlnMetadata,
192
+ }];
193
+ }
194
+ // CRITICAL: intent.externalCallHash must match keccak256(request.trades[].dlnHook)
195
+ // from one of the trades in the group. When no trade has a dlnHook, the intent
196
+ // field must be empty/zero.
197
+ function validateExternalCallHash(intent, group, basePath) {
198
+ const expected = new Set();
199
+ for (const trade of group.trades) {
200
+ expected.add(trade.dlnHook === undefined
201
+ ? undefined
202
+ : keccak256(trade.dlnHook));
203
+ }
204
+ if (matchesAnyHex(intent.externalCallHash, expected))
205
+ return [];
206
+ return [{
207
+ code: ViolationCode.IntentExternalCallHashMismatch,
208
+ message: "intent.externalCallHash must match keccak256 of one of"
209
+ + " request.trades[].dlnHook values from the trade group",
210
+ path: `${basePath}.externalCallHash`,
211
+ expected: Array.from(expected),
212
+ actual: intent.externalCallHash,
213
+ }];
214
+ }
215
+ function isEmptyHex(value) {
216
+ if (value === undefined)
217
+ return true;
218
+ const normalized = value.toLowerCase();
219
+ return normalized === "0x" || normalized === zeroHash;
220
+ }
221
+ function matchesAnyHex(actual, expected) {
222
+ for (const exp of expected) {
223
+ if (hexEquals(actual, exp))
224
+ return true;
225
+ }
226
+ return false;
227
+ }
228
+ function hexEquals(a, b) {
229
+ if (isEmptyHex(a) && isEmptyHex(b))
230
+ return true;
231
+ if (a === undefined || b === undefined)
232
+ return false;
233
+ return a.toLowerCase() === b.toLowerCase();
234
+ }
235
+ // CRITICAL: all numeric values in intent must be non-negative.
236
+ function validateNonNegativeNumerics(intent, basePath) {
237
+ const violations = [];
238
+ const numberFields = [
239
+ { name: "expirationTimestamp", value: intent.expirationTimestamp },
240
+ { name: "intentTimestamp", value: intent.intentTimestamp },
241
+ ];
242
+ for (const { name, value } of numberFields) {
243
+ if (value < 0) {
244
+ violations.push({
245
+ code: ViolationCode.IntentNumericValueNegative,
246
+ message: `intent.${name} must be non-negative`,
247
+ path: `${basePath}.${name}`,
248
+ actual: value,
249
+ });
250
+ }
251
+ }
252
+ violations.push(...checkBigIntFields(intent.inputToken ?? [], `${basePath}.inputToken`, ["minPartialAmount", "maxPartialAmount", "constraintBudget"]));
253
+ violations.push(...checkBigIntFields(intent.giveToken ?? [], `${basePath}.giveToken`, ["numerator", "denominator"]));
254
+ violations.push(...checkBigIntFields(intent.takeToken, `${basePath}.takeToken`, ["numerator", "denominator"]));
255
+ return violations;
256
+ }
257
+ function checkBigIntFields(items, basePath, fieldNames) {
258
+ const violations = [];
259
+ for (let i = 0; i < items.length; i++) {
260
+ for (const fieldName of fieldNames) {
261
+ const raw = items[i][fieldName];
262
+ try {
263
+ if (BigInt(raw) < 0n) {
264
+ violations.push({
265
+ code: ViolationCode.IntentNumericValueNegative,
266
+ message: `${basePath}[${i}].${fieldName} must be non-negative`,
267
+ path: `${basePath}[${i}].${fieldName}`,
268
+ actual: raw,
269
+ });
270
+ }
271
+ }
272
+ catch (error) {
273
+ violations.push({
274
+ code: ViolationCode.IntentNumericValueInvalid,
275
+ message: `${basePath}[${i}].${fieldName} is not a valid number`,
276
+ path: `${basePath}[${i}].${fieldName}`,
277
+ actual: raw,
278
+ details: error,
279
+ });
280
+ }
281
+ }
282
+ }
283
+ return violations;
284
+ }
285
+ //# sourceMappingURL=intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent.js","sourceRoot":"","sources":["../../../src/validations/intent.ts"],"names":[],"mappings":"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"}