@debridge-finance/borderless-validation-sdk 0.0.0-dev-3dc1a82 → 0.0.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 (272) hide show
  1. package/dist/cjs/helpers/address.js +18 -31
  2. package/dist/cjs/helpers/address.js.map +1 -1
  3. package/dist/cjs/helpers/constants.js +6 -0
  4. package/dist/cjs/helpers/constants.js.map +1 -0
  5. package/dist/cjs/helpers/evm-action.js +3 -3
  6. package/dist/cjs/helpers/evm-action.js.map +1 -1
  7. package/dist/cjs/helpers/evm-intent-id.js +1 -1
  8. package/dist/cjs/helpers/evm-intent-id.js.map +1 -1
  9. package/dist/cjs/helpers/evm-trade-amounts.js +1 -36
  10. package/dist/cjs/helpers/evm-trade-amounts.js.map +1 -1
  11. package/dist/cjs/types/enums.js +2 -26
  12. package/dist/cjs/types/enums.js.map +1 -1
  13. package/dist/cjs/types/request.js +2 -25
  14. package/dist/cjs/types/request.js.map +1 -1
  15. package/dist/cjs/types/response.js +4 -120
  16. package/dist/cjs/types/response.js.map +1 -1
  17. package/dist/cjs/types/validation.js +10 -74
  18. package/dist/cjs/types/validation.js.map +1 -1
  19. package/dist/cjs/validations/evm-caveats.js +14 -4
  20. package/dist/cjs/validations/evm-caveats.js.map +1 -1
  21. package/dist/cjs/validations/evm-op-budget.js +10 -13
  22. package/dist/cjs/validations/evm-op-budget.js.map +1 -1
  23. package/dist/cjs/validations/evm-op-gas-compensation.js +152 -0
  24. package/dist/cjs/validations/evm-op-gas-compensation.js.map +1 -0
  25. package/dist/cjs/validations/evm-op-hook.js +3 -410
  26. package/dist/cjs/validations/evm-op-hook.js.map +1 -1
  27. package/dist/cjs/validations/evm-op-wrap.js +7 -10
  28. package/dist/cjs/validations/evm-op-wrap.js.map +1 -1
  29. package/dist/cjs/validations/evm-required-actions.js +9 -7
  30. package/dist/cjs/validations/evm-required-actions.js.map +1 -1
  31. package/dist/cjs/validations/evm-sign712-metamask.js +94 -17
  32. package/dist/cjs/validations/evm-sign712-metamask.js.map +1 -1
  33. package/dist/cjs/validations/evm-sign7702.js +22 -34
  34. package/dist/cjs/validations/evm-sign7702.js.map +1 -1
  35. package/dist/cjs/validations/hooks-common.js +37 -252
  36. package/dist/cjs/validations/hooks-common.js.map +1 -1
  37. package/dist/cjs/validations/required-actions.js +7 -4
  38. package/dist/cjs/validations/required-actions.js.map +1 -1
  39. package/dist/cjs/validations/solana-hook.js +18 -32
  40. package/dist/cjs/validations/solana-hook.js.map +1 -1
  41. package/dist/cjs/validations/solana-op-budget.js +18 -56
  42. package/dist/cjs/validations/solana-op-budget.js.map +1 -1
  43. package/dist/cjs/validations/solana-op-wrap.js +13 -46
  44. package/dist/cjs/validations/solana-op-wrap.js.map +1 -1
  45. package/dist/cjs/validations/solana-required-actions.js +3 -3
  46. package/dist/cjs/validations/solana-required-actions.js.map +1 -1
  47. package/dist/cjs/validations/solana-transaction.js +5 -5
  48. package/dist/cjs/validations/solana-transaction.js.map +1 -1
  49. package/dist/cjs/validations/trade-grouping.js +1 -68
  50. package/dist/cjs/validations/trade-grouping.js.map +1 -1
  51. package/dist/cjs/validations/trades.js +37 -59
  52. package/dist/cjs/validations/trades.js.map +1 -1
  53. package/dist/cjs/validator.js +16 -11
  54. package/dist/cjs/validator.js.map +1 -1
  55. package/dist/cjs/whitelists/environment-config.js +28 -47
  56. package/dist/cjs/whitelists/environment-config.js.map +1 -1
  57. package/dist/cjs/whitelists/evm/caveat-enforcers.js +5 -21
  58. package/dist/cjs/whitelists/evm/caveat-enforcers.js.map +1 -1
  59. package/dist/cjs/whitelists/evm/delegation-manager.js +2 -7
  60. package/dist/cjs/whitelists/evm/delegation-manager.js.map +1 -1
  61. package/dist/cjs/whitelists/evm/eip7702-delegation.js +2 -7
  62. package/dist/cjs/whitelists/evm/eip7702-delegation.js.map +1 -1
  63. package/dist/cjs/whitelists/evm/index.js +1 -14
  64. package/dist/cjs/whitelists/evm/index.js.map +1 -1
  65. package/dist/cjs/whitelists/evm/permit2.js +12 -16
  66. package/dist/cjs/whitelists/evm/permit2.js.map +1 -1
  67. package/dist/cjs/whitelists/evm/weth.js +5 -16
  68. package/dist/cjs/whitelists/evm/weth.js.map +1 -1
  69. package/dist/cjs/whitelists/solana/intent-signature.js +1 -0
  70. package/dist/cjs/whitelists/solana/intent-signature.js.map +1 -1
  71. package/dist/cjs/whitelists/subscription-to-chain-id.js +0 -10
  72. package/dist/cjs/whitelists/subscription-to-chain-id.js.map +1 -1
  73. package/dist/cjs/whitelists/types.js +3 -13
  74. package/dist/cjs/whitelists/types.js.map +1 -1
  75. package/dist/esm/helpers/address.js +17 -28
  76. package/dist/esm/helpers/address.js.map +1 -1
  77. package/dist/esm/helpers/constants.js +3 -0
  78. package/dist/esm/helpers/constants.js.map +1 -0
  79. package/dist/esm/helpers/evm-action.js +3 -3
  80. package/dist/esm/helpers/evm-action.js.map +1 -1
  81. package/dist/esm/helpers/evm-intent-id.js +1 -1
  82. package/dist/esm/helpers/evm-intent-id.js.map +1 -1
  83. package/dist/esm/helpers/evm-trade-amounts.js +1 -36
  84. package/dist/esm/helpers/evm-trade-amounts.js.map +1 -1
  85. package/dist/esm/types/enums.js +1 -25
  86. package/dist/esm/types/enums.js.map +1 -1
  87. package/dist/esm/types/request.js +3 -26
  88. package/dist/esm/types/request.js.map +1 -1
  89. package/dist/esm/types/response.js +3 -119
  90. package/dist/esm/types/response.js.map +1 -1
  91. package/dist/esm/types/validation.js +10 -74
  92. package/dist/esm/types/validation.js.map +1 -1
  93. package/dist/esm/validations/evm-caveats.js +14 -4
  94. package/dist/esm/validations/evm-caveats.js.map +1 -1
  95. package/dist/esm/validations/evm-op-budget.js +10 -13
  96. package/dist/esm/validations/evm-op-budget.js.map +1 -1
  97. package/dist/esm/validations/evm-op-gas-compensation.js +149 -0
  98. package/dist/esm/validations/evm-op-gas-compensation.js.map +1 -0
  99. package/dist/esm/validations/evm-op-hook.js +2 -409
  100. package/dist/esm/validations/evm-op-hook.js.map +1 -1
  101. package/dist/esm/validations/evm-op-wrap.js +7 -10
  102. package/dist/esm/validations/evm-op-wrap.js.map +1 -1
  103. package/dist/esm/validations/evm-required-actions.js +9 -7
  104. package/dist/esm/validations/evm-required-actions.js.map +1 -1
  105. package/dist/esm/validations/evm-sign712-metamask.js +94 -17
  106. package/dist/esm/validations/evm-sign712-metamask.js.map +1 -1
  107. package/dist/esm/validations/evm-sign7702.js +22 -33
  108. package/dist/esm/validations/evm-sign7702.js.map +1 -1
  109. package/dist/esm/validations/hooks-common.js +38 -251
  110. package/dist/esm/validations/hooks-common.js.map +1 -1
  111. package/dist/esm/validations/required-actions.js +7 -4
  112. package/dist/esm/validations/required-actions.js.map +1 -1
  113. package/dist/esm/validations/solana-hook.js +20 -34
  114. package/dist/esm/validations/solana-hook.js.map +1 -1
  115. package/dist/esm/validations/solana-op-budget.js +18 -56
  116. package/dist/esm/validations/solana-op-budget.js.map +1 -1
  117. package/dist/esm/validations/solana-op-wrap.js +14 -47
  118. package/dist/esm/validations/solana-op-wrap.js.map +1 -1
  119. package/dist/esm/validations/solana-required-actions.js +3 -3
  120. package/dist/esm/validations/solana-required-actions.js.map +1 -1
  121. package/dist/esm/validations/solana-transaction.js +7 -7
  122. package/dist/esm/validations/solana-transaction.js.map +1 -1
  123. package/dist/esm/validations/trade-grouping.js +1 -68
  124. package/dist/esm/validations/trade-grouping.js.map +1 -1
  125. package/dist/esm/validations/trades.js +37 -59
  126. package/dist/esm/validations/trades.js.map +1 -1
  127. package/dist/esm/validator.js +16 -11
  128. package/dist/esm/validator.js.map +1 -1
  129. package/dist/esm/whitelists/environment-config.js +28 -47
  130. package/dist/esm/whitelists/environment-config.js.map +1 -1
  131. package/dist/esm/whitelists/evm/caveat-enforcers.js +4 -20
  132. package/dist/esm/whitelists/evm/caveat-enforcers.js.map +1 -1
  133. package/dist/esm/whitelists/evm/delegation-manager.js +1 -6
  134. package/dist/esm/whitelists/evm/delegation-manager.js.map +1 -1
  135. package/dist/esm/whitelists/evm/eip7702-delegation.js +1 -6
  136. package/dist/esm/whitelists/evm/eip7702-delegation.js.map +1 -1
  137. package/dist/esm/whitelists/evm/index.js +4 -4
  138. package/dist/esm/whitelists/evm/index.js.map +1 -1
  139. package/dist/esm/whitelists/evm/permit2.js +5 -9
  140. package/dist/esm/whitelists/evm/permit2.js.map +1 -1
  141. package/dist/esm/whitelists/evm/weth.js +5 -16
  142. package/dist/esm/whitelists/evm/weth.js.map +1 -1
  143. package/dist/esm/whitelists/solana/intent-signature.js +1 -0
  144. package/dist/esm/whitelists/solana/intent-signature.js.map +1 -1
  145. package/dist/esm/whitelists/subscription-to-chain-id.js +0 -9
  146. package/dist/esm/whitelists/subscription-to-chain-id.js.map +1 -1
  147. package/dist/esm/whitelists/types.js +5 -14
  148. package/dist/esm/whitelists/types.js.map +1 -1
  149. package/dist/types/helpers/address.d.ts +7 -5
  150. package/dist/types/helpers/address.d.ts.map +1 -1
  151. package/dist/types/helpers/constants.d.ts +2 -0
  152. package/dist/types/helpers/constants.d.ts.map +1 -0
  153. package/dist/types/helpers/evm-trade-amounts.d.ts +2 -2
  154. package/dist/types/helpers/evm-trade-amounts.d.ts.map +1 -1
  155. package/dist/types/types/enums.d.ts +1 -19
  156. package/dist/types/types/enums.d.ts.map +1 -1
  157. package/dist/types/types/request.d.ts +9 -19
  158. package/dist/types/types/request.d.ts.map +1 -1
  159. package/dist/types/types/response.d.ts +11 -367
  160. package/dist/types/types/response.d.ts.map +1 -1
  161. package/dist/types/types/validation.d.ts +11 -67
  162. package/dist/types/types/validation.d.ts.map +1 -1
  163. package/dist/types/validations/evm-caveats.d.ts.map +1 -1
  164. package/dist/types/validations/evm-op-budget.d.ts +2 -2
  165. package/dist/types/validations/evm-op-budget.d.ts.map +1 -1
  166. package/dist/types/validations/evm-op-gas-compensation.d.ts +3 -0
  167. package/dist/types/validations/evm-op-gas-compensation.d.ts.map +1 -0
  168. package/dist/types/validations/evm-op-hook.d.ts +2 -4
  169. package/dist/types/validations/evm-op-hook.d.ts.map +1 -1
  170. package/dist/types/validations/evm-op-wrap.d.ts +2 -2
  171. package/dist/types/validations/evm-op-wrap.d.ts.map +1 -1
  172. package/dist/types/validations/evm-required-actions.d.ts +2 -2
  173. package/dist/types/validations/evm-required-actions.d.ts.map +1 -1
  174. package/dist/types/validations/evm-sign712-metamask.d.ts.map +1 -1
  175. package/dist/types/validations/evm-sign7702.d.ts +1 -2
  176. package/dist/types/validations/evm-sign7702.d.ts.map +1 -1
  177. package/dist/types/validations/hooks-common.d.ts +0 -1
  178. package/dist/types/validations/hooks-common.d.ts.map +1 -1
  179. package/dist/types/validations/required-actions.d.ts +1 -2
  180. package/dist/types/validations/required-actions.d.ts.map +1 -1
  181. package/dist/types/validations/solana-hook.d.ts +2 -4
  182. package/dist/types/validations/solana-hook.d.ts.map +1 -1
  183. package/dist/types/validations/solana-op-budget.d.ts +2 -2
  184. package/dist/types/validations/solana-op-budget.d.ts.map +1 -1
  185. package/dist/types/validations/solana-op-wrap.d.ts +2 -2
  186. package/dist/types/validations/solana-op-wrap.d.ts.map +1 -1
  187. package/dist/types/validations/solana-required-actions.d.ts +2 -2
  188. package/dist/types/validations/solana-required-actions.d.ts.map +1 -1
  189. package/dist/types/validations/solana-transaction.d.ts +3 -3
  190. package/dist/types/validations/solana-transaction.d.ts.map +1 -1
  191. package/dist/types/validations/trade-grouping.d.ts +2 -3
  192. package/dist/types/validations/trade-grouping.d.ts.map +1 -1
  193. package/dist/types/validator.d.ts.map +1 -1
  194. package/dist/types/whitelists/environment-config.d.ts.map +1 -1
  195. package/dist/types/whitelists/evm/caveat-enforcers.d.ts +0 -8
  196. package/dist/types/whitelists/evm/caveat-enforcers.d.ts.map +1 -1
  197. package/dist/types/whitelists/evm/delegation-manager.d.ts +0 -2
  198. package/dist/types/whitelists/evm/delegation-manager.d.ts.map +1 -1
  199. package/dist/types/whitelists/evm/eip7702-delegation.d.ts +0 -2
  200. package/dist/types/whitelists/evm/eip7702-delegation.d.ts.map +1 -1
  201. package/dist/types/whitelists/evm/index.d.ts +4 -4
  202. package/dist/types/whitelists/evm/index.d.ts.map +1 -1
  203. package/dist/types/whitelists/evm/permit2.d.ts +0 -1
  204. package/dist/types/whitelists/evm/permit2.d.ts.map +1 -1
  205. package/dist/types/whitelists/evm/weth.d.ts.map +1 -1
  206. package/dist/types/whitelists/solana/intent-signature.d.ts.map +1 -1
  207. package/dist/types/whitelists/subscription-to-chain-id.d.ts +0 -1
  208. package/dist/types/whitelists/subscription-to-chain-id.d.ts.map +1 -1
  209. package/dist/types/whitelists/types.d.ts +1 -1
  210. package/dist/types/whitelists/types.d.ts.map +1 -1
  211. package/package.json +2 -2
  212. package/README.md +0 -164
  213. package/dist/cjs/helpers/evm-gas-compensation-tx.js +0 -102
  214. package/dist/cjs/helpers/evm-gas-compensation-tx.js.map +0 -1
  215. package/dist/cjs/helpers/gas-compensation.js +0 -36
  216. package/dist/cjs/helpers/gas-compensation.js.map +0 -1
  217. package/dist/cjs/helpers/placeholder.js +0 -174
  218. package/dist/cjs/helpers/placeholder.js.map +0 -1
  219. package/dist/cjs/helpers/sets.js +0 -13
  220. package/dist/cjs/helpers/sets.js.map +0 -1
  221. package/dist/cjs/validations/compensation-hook.js +0 -203
  222. package/dist/cjs/validations/compensation-hook.js.map +0 -1
  223. package/dist/cjs/validations/evm-sign712-shared.js +0 -116
  224. package/dist/cjs/validations/evm-sign712-shared.js.map +0 -1
  225. package/dist/cjs/validations/intent-destinations.js +0 -197
  226. package/dist/cjs/validations/intent-destinations.js.map +0 -1
  227. package/dist/cjs/validations/intent-tokens.js +0 -341
  228. package/dist/cjs/validations/intent-tokens.js.map +0 -1
  229. package/dist/cjs/validations/intent.js +0 -288
  230. package/dist/cjs/validations/intent.js.map +0 -1
  231. package/dist/cjs/whitelists/evm/metamask-delegation-chains.js +0 -16
  232. package/dist/cjs/whitelists/evm/metamask-delegation-chains.js.map +0 -1
  233. package/dist/esm/helpers/evm-gas-compensation-tx.js +0 -99
  234. package/dist/esm/helpers/evm-gas-compensation-tx.js.map +0 -1
  235. package/dist/esm/helpers/gas-compensation.js +0 -33
  236. package/dist/esm/helpers/gas-compensation.js.map +0 -1
  237. package/dist/esm/helpers/placeholder.js +0 -168
  238. package/dist/esm/helpers/placeholder.js.map +0 -1
  239. package/dist/esm/helpers/sets.js +0 -10
  240. package/dist/esm/helpers/sets.js.map +0 -1
  241. package/dist/esm/validations/compensation-hook.js +0 -200
  242. package/dist/esm/validations/compensation-hook.js.map +0 -1
  243. package/dist/esm/validations/evm-sign712-shared.js +0 -110
  244. package/dist/esm/validations/evm-sign712-shared.js.map +0 -1
  245. package/dist/esm/validations/intent-destinations.js +0 -194
  246. package/dist/esm/validations/intent-destinations.js.map +0 -1
  247. package/dist/esm/validations/intent-tokens.js +0 -338
  248. package/dist/esm/validations/intent-tokens.js.map +0 -1
  249. package/dist/esm/validations/intent.js +0 -285
  250. package/dist/esm/validations/intent.js.map +0 -1
  251. package/dist/esm/whitelists/evm/metamask-delegation-chains.js +0 -13
  252. package/dist/esm/whitelists/evm/metamask-delegation-chains.js.map +0 -1
  253. package/dist/types/helpers/evm-gas-compensation-tx.d.ts +0 -13
  254. package/dist/types/helpers/evm-gas-compensation-tx.d.ts.map +0 -1
  255. package/dist/types/helpers/gas-compensation.d.ts +0 -10
  256. package/dist/types/helpers/gas-compensation.d.ts.map +0 -1
  257. package/dist/types/helpers/placeholder.d.ts +0 -41
  258. package/dist/types/helpers/placeholder.d.ts.map +0 -1
  259. package/dist/types/helpers/sets.d.ts +0 -2
  260. package/dist/types/helpers/sets.d.ts.map +0 -1
  261. package/dist/types/validations/compensation-hook.d.ts +0 -3
  262. package/dist/types/validations/compensation-hook.d.ts.map +0 -1
  263. package/dist/types/validations/evm-sign712-shared.d.ts +0 -7
  264. package/dist/types/validations/evm-sign712-shared.d.ts.map +0 -1
  265. package/dist/types/validations/intent-destinations.d.ts +0 -4
  266. package/dist/types/validations/intent-destinations.d.ts.map +0 -1
  267. package/dist/types/validations/intent-tokens.d.ts +0 -4
  268. package/dist/types/validations/intent-tokens.d.ts.map +0 -1
  269. package/dist/types/validations/intent.d.ts +0 -5
  270. package/dist/types/validations/intent.d.ts.map +0 -1
  271. package/dist/types/whitelists/evm/metamask-delegation-chains.d.ts +0 -3
  272. package/dist/types/whitelists/evm/metamask-delegation-chains.d.ts.map +0 -1
@@ -1,5 +1,8 @@
1
1
  import { ViolationCode, EvmActionKind, EvmActionOperation, } from "../types/index.js";
2
- import { validateSign712DataPresent, validateSign712Domain, validateSign712Delegator, validateSign712Caveats, } from "./evm-sign712-shared.js";
2
+ import { isWhitelisted } from "../whitelists/types.js";
3
+ import { DELEGATION_MANAGER_CONTRACTS } from "../whitelists/evm/index.js";
4
+ import { addressEquals } from "../helpers/address.js";
5
+ import { classifyCaveats, validateExactExecutionPresence, validateExactExecutionContent, validateTimestampEnforcerValue, } from "./evm-caveats.js";
3
6
  const SIGN712_METAMASK_ALLOWED_ACTIONS = [
4
7
  EvmActionOperation.Budget,
5
8
  EvmActionOperation.Wrap,
@@ -10,28 +13,23 @@ export function validateSign712MetaMaskActions(actions, basePath, realChainId, q
10
13
  const violations = [];
11
14
  for (let i = 0; i < actions.length; i++) {
12
15
  const action = actions[i];
13
- if (action.type !== EvmActionKind.Sign712MetaMaskCaveats)
16
+ if (action.type !== EvmActionKind.Sign712MetaMask)
14
17
  continue;
15
18
  const actionPath = `${basePath}.requiredActions[${i}]`;
16
19
  const data = action.data;
17
- // CRITICAL: data structural presence — downstream content checks
18
- // assume `data.domain` and `data.message` exist.
19
- const presenceErrors = validateSign712DataPresent(data, actionPath);
20
- if (presenceErrors.length > 0) {
21
- violations.push(...presenceErrors);
20
+ // CRITICAL: `data` must be present and contain `domain` and `message`
21
+ if (!data || !data.domain || !data.message) {
22
+ violations.push({
23
+ code: ViolationCode.Sign712MetaMaskDomainNameNotDelegationManager,
24
+ message: `Sign712MetaMask data is missing domain or message`,
25
+ path: `${actionPath}.data`,
26
+ actual: data,
27
+ });
22
28
  continue;
23
29
  }
24
- violations.push(...validateSign712TransactionCalls(action, actionPath), ...validateSign712AllowedActions(action, actionPath), ...validateSign712Domain(data, actionPath, realChainId),
25
- // Delegator: in quote mode we cannot determine the trust source —
26
- // skip the check entirely. In execution mode the helper compares
27
- // against `srcChainAuthorityAddress` (which may itself be
28
- // `undefined` as a defensive check — preserved by passing through).
29
- ...(quoteMode
30
- ? []
31
- : validateSign712Delegator(data, actionPath, realChainId, srcChainAuthorityAddress, "srcChainAuthorityAddress")));
30
+ violations.push(...validateSign712TransactionCalls(action, actionPath), ...validateSign712AllowedActions(action, actionPath), ...validateSign712Domain(data, actionPath, realChainId), ...validateSign712Delegator(data, actionPath, realChainId, quoteMode, srcChainAuthorityAddress));
32
31
  const caveats = (data.message.caveats ?? []);
33
- const txCalls = action.details?.transactionCalls ?? [];
34
- violations.push(...validateSign712Caveats(caveats, action.actionId, txCalls, actionPath, realChainId, expirationTimestamp));
32
+ violations.push(...validateSign712MetaMaskCaveats(caveats, action, actionPath, realChainId, expirationTimestamp));
35
33
  }
36
34
  return violations;
37
35
  }
@@ -64,4 +62,83 @@ function validateSign712AllowedActions(action, actionPath) {
64
62
  }
65
63
  return violations;
66
64
  }
65
+ // CRITICAL: domain.name must be "DelegationManager"
66
+ // CRITICAL: domain.chainId must equal the real chainId
67
+ // CRITICAL: domain.verifyingContract must be in the DelegationManager whitelist
68
+ function validateSign712Domain(data, actionPath, realChainId) {
69
+ const violations = [];
70
+ if (data.domain.name !== "DelegationManager") {
71
+ violations.push({
72
+ code: ViolationCode.Sign712MetaMaskDomainNameNotDelegationManager,
73
+ message: `Sign712MetaMask domain.name must be "DelegationManager"`,
74
+ path: `${actionPath}.data.domain.name`,
75
+ expected: "DelegationManager",
76
+ actual: data.domain.name,
77
+ });
78
+ }
79
+ if (data.domain.chainId !== realChainId) {
80
+ violations.push({
81
+ code: ViolationCode.Sign712MetaMaskChainIdMismatch,
82
+ message: `Sign712MetaMask domain.chainId does not match the real chainId`,
83
+ path: `${actionPath}.data.domain.chainId`,
84
+ expected: realChainId,
85
+ actual: data.domain.chainId,
86
+ });
87
+ }
88
+ if (data.domain.verifyingContract === undefined ||
89
+ !isWhitelisted(DELEGATION_MANAGER_CONTRACTS, realChainId, data.domain.verifyingContract)) {
90
+ violations.push({
91
+ code: ViolationCode.Sign712MetaMaskVerifyingContractNotWhitelisted,
92
+ message: `Sign712MetaMask domain.verifyingContract is not whitelisted`,
93
+ path: `${actionPath}.data.domain.verifyingContract`,
94
+ actual: data.domain.verifyingContract,
95
+ });
96
+ }
97
+ return violations;
98
+ }
99
+ // LOW: in execution mode, message.delegator must match srcChainAuthorityAddress
100
+ function validateSign712Delegator(data, actionPath, realChainId, quoteMode, srcChainAuthorityAddress) {
101
+ if (quoteMode)
102
+ return [];
103
+ const delegator = data.message.delegator;
104
+ if (srcChainAuthorityAddress === undefined ||
105
+ delegator === undefined ||
106
+ !addressEquals(realChainId, delegator, srcChainAuthorityAddress)) {
107
+ return [{
108
+ code: ViolationCode.Sign712MetaMaskDelegatorMismatch,
109
+ message: `Sign712MetaMask message.delegator must match srcChainAuthorityAddress`,
110
+ path: `${actionPath}.data.message.delegator`,
111
+ expected: srcChainAuthorityAddress,
112
+ actual: delegator,
113
+ }];
114
+ }
115
+ return [];
116
+ }
117
+ function validateSign712MetaMaskCaveats(caveats, action, actionPath, realChainId, expirationTimestamp) {
118
+ const violations = [];
119
+ const classified = classifyCaveats(caveats, action.actionId, actionPath, realChainId, violations);
120
+ const txCalls = action.details?.transactionCalls ?? [];
121
+ violations.push(...validateExactExecutionPresence(classified, txCalls, actionPath));
122
+ validateExactExecutionContent(classified, txCalls, actionPath, violations);
123
+ // CRITICAL: must have at least one IdEnforcer caveat (replay protection)
124
+ if (!classified.hasIdEnforcer) {
125
+ violations.push({
126
+ code: ViolationCode.Sign712MetaMaskMissingIdEnforcerCaveat,
127
+ message: `Sign712MetaMask must have an IdEnforcer caveat`,
128
+ path: `${actionPath}.data.message.caveats`,
129
+ });
130
+ }
131
+ // CRITICAL: must have exactly one TimestampEnforcer caveat
132
+ if (classified.timestampCount === 0) {
133
+ violations.push({
134
+ code: ViolationCode.Sign712MetaMaskMissingTimestampEnforcerCaveat,
135
+ message: `Sign712MetaMask must have a TimestampEnforcer caveat`,
136
+ path: `${actionPath}.data.message.caveats`,
137
+ });
138
+ }
139
+ if (classified.firstTimestamp) {
140
+ validateTimestampEnforcerValue(classified.firstTimestamp.caveat, expirationTimestamp, classified.firstTimestamp.index, actionPath, violations);
141
+ }
142
+ return violations;
143
+ }
67
144
  //# sourceMappingURL=evm-sign712-metamask.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"evm-sign712-metamask.js","sourceRoot":"","sources":["../../../src/validations/evm-sign712-metamask.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"evm-sign712-metamask.js","sourceRoot":"","sources":["../../../src/validations/evm-sign712-metamask.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,aAAa,EAEb,aAAa,EACb,kBAAkB,GAGrB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAEH,eAAe,EACf,8BAA8B,EAC9B,6BAA6B,EAC7B,8BAA8B,GACjC,MAAM,eAAe,CAAC;AAEvB,MAAM,gCAAgC,GAAkC;IACpE,kBAAkB,CAAC,MAAM;IACzB,kBAAkB,CAAC,IAAI;IACvB,kBAAkB,CAAC,IAAI;IACvB,kBAAkB,CAAC,eAAe;CACrC,CAAC;AAEF,MAAM,UAAU,8BAA8B,CAC1C,OAA4B,EAC5B,QAAgB,EAChB,WAAoB,EACpB,SAAkB,EAClB,mBAA2B,EAC3B,wBAAiC;IAEjC,MAAM,UAAU,GAAgB,EAAE,CAAC;IAEnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,CAAC,eAAe;YAAE,SAAS;QAE5D,MAAM,UAAU,GAAG,GAAG,QAAQ,oBAAoB,CAAC,GAAG,CAAC;QACvD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAkC,CAAC;QAEvD,sEAAsE;QACtE,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACzC,UAAU,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,aAAa,CAAC,6CAA6C;gBACjE,OAAO,EAAE,mDAAmD;gBAC5D,IAAI,EAAE,GAAG,UAAU,OAAO;gBAC1B,MAAM,EAAE,IAAI;aACf,CAAC,CAAC;YACH,SAAS;QACb,CAAC;QAED,UAAU,CAAC,IAAI,CACX,GAAG,+BAA+B,CAAC,MAAM,EAAE,UAAU,CAAC,EACtD,GAAG,6BAA6B,CAAC,MAAM,EAAE,UAAU,CAAC,EACpD,GAAG,qBAAqB,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,EACvD,GAAG,wBAAwB,CACvB,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,wBAAwB,CACrE,CACJ,CAAC;QAEF,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAa,CAAC;QACzD,UAAU,CAAC,IAAI,CACX,GAAG,8BAA8B,CAC7B,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,mBAAmB,CAChE,CACJ,CAAC;IACN,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,4DAA4D;AAC5D,SAAS,+BAA+B,CACpC,MAAyB,EACzB,UAAkB;IAElB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,gBAAgB,IAAI,EAAE,CAAC;IACvD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC;gBACJ,IAAI,EAAE,aAAa,CAAC,oCAAoC;gBACxD,OAAO,EAAE,wDAAwD;gBACjE,IAAI,EAAE,GAAG,UAAU,2BAA2B;gBAC9C,MAAM,EAAE,OAAO;aAClB,CAAC,CAAC;IACP,CAAC;IACD,OAAO,EAAE,CAAC;AACd,CAAC;AAED,+DAA+D;AAC/D,SAAS,6BAA6B,CAClC,MAAyB,EACzB,UAAkB;IAElB,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC,gCAAgC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YACjD,UAAU,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,aAAa,CAAC,8BAA8B;gBAClD,OAAO,EAAE,2BAA2B,EAAE,kBAAkB;gBACxD,IAAI,EAAE,GAAG,UAAU,UAAU;gBAC7B,QAAQ,EAAE,gCAAgC;gBAC1C,MAAM,EAAE,MAAM,CAAC,OAAO;aACzB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IACD,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,oDAAoD;AACpD,uDAAuD;AACvD,gFAAgF;AAChF,SAAS,qBAAqB,CAC1B,IAAoB,EACpB,UAAkB,EAClB,WAAoB;IAEpB,MAAM,UAAU,GAAgB,EAAE,CAAC;IAEnC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;QAC3C,UAAU,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,aAAa,CAAC,6CAA6C;YACjE,OAAO,EAAE,yDAAyD;YAClE,IAAI,EAAE,GAAG,UAAU,mBAAmB;YACtC,QAAQ,EAAE,mBAAmB;YAC7B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;SAC3B,CAAC,CAAC;IACP,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,KAAK,WAAW,EAAE,CAAC;QACtC,UAAU,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,aAAa,CAAC,8BAA8B;YAClD,OAAO,EAAE,gEAAgE;YACzE,IAAI,EAAE,GAAG,UAAU,sBAAsB;YACzC,QAAQ,EAAE,WAAW;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO;SAC9B,CAAC,CAAC;IACP,CAAC;IAED,IACI,IAAI,CAAC,MAAM,CAAC,iBAAiB,KAAK,SAAS;QAC3C,CAAC,aAAa,CACV,4BAA4B,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAC3E,EACH,CAAC;QACC,UAAU,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,aAAa,CAAC,8CAA8C;YAClE,OAAO,EAAE,6DAA6D;YACtE,IAAI,EAAE,GAAG,UAAU,gCAAgC;YACnD,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,iBAAiB;SACxC,CAAC,CAAC;IACP,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,gFAAgF;AAChF,SAAS,wBAAwB,CAC7B,IAAoB,EACpB,UAAkB,EAClB,WAAoB,EACpB,SAAkB,EAClB,wBAAiC;IAEjC,IAAI,SAAS;QAAE,OAAO,EAAE,CAAC;IAEzB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAA+B,CAAC;IAC/D,IACI,wBAAwB,KAAK,SAAS;QACtC,SAAS,KAAK,SAAS;QACvB,CAAC,aAAa,CAAC,WAAW,EAAE,SAAS,EAAE,wBAAwB,CAAC,EAClE,CAAC;QACC,OAAO,CAAC;gBACJ,IAAI,EAAE,aAAa,CAAC,gCAAgC;gBACpD,OAAO,EAAE,uEAAuE;gBAChF,IAAI,EAAE,GAAG,UAAU,yBAAyB;gBAC5C,QAAQ,EAAE,wBAAwB;gBAClC,MAAM,EAAE,SAAS;aACpB,CAAC,CAAC;IACP,CAAC;IACD,OAAO,EAAE,CAAC;AACd,CAAC;AAED,SAAS,8BAA8B,CACnC,OAAiB,EACjB,MAAyB,EACzB,UAAkB,EAClB,WAAoB,EACpB,mBAA2B;IAE3B,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,MAAM,UAAU,GAAG,eAAe,CAC9B,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,CAChE,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,gBAAgB,IAAI,EAAE,CAAC;IAEvD,UAAU,CAAC,IAAI,CACX,GAAG,8BAA8B,CAC7B,UAAU,EAAE,OAAO,EAAE,UAAU,CAClC,CACJ,CAAC;IAEF,6BAA6B,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IAE3E,yEAAyE;IACzE,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC;QAC5B,UAAU,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,aAAa,CAAC,sCAAsC;YAC1D,OAAO,EAAE,gDAAgD;YACzD,IAAI,EAAE,GAAG,UAAU,uBAAuB;SAC7C,CAAC,CAAC;IACP,CAAC;IAED,2DAA2D;IAC3D,IAAI,UAAU,CAAC,cAAc,KAAK,CAAC,EAAE,CAAC;QAClC,UAAU,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,aAAa,CAAC,6CAA6C;YACjE,OAAO,EAAE,sDAAsD;YAC/D,IAAI,EAAE,GAAG,UAAU,uBAAuB;SAC7C,CAAC,CAAC;IACP,CAAC;IAED,IAAI,UAAU,CAAC,cAAc,EAAE,CAAC;QAC5B,8BAA8B,CAC1B,UAAU,CAAC,cAAc,CAAC,MAAM,EAAE,mBAAmB,EACrD,UAAU,CAAC,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,CAC1D,CAAC;IACN,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC"}
@@ -4,38 +4,6 @@ import { EIP7702_DELEGATION_CONTRACTS } from "../whitelists/evm/index.js";
4
4
  // =============================================
5
5
  // Sign7702Authorization constraints
6
6
  // =============================================
7
- // CRITICAL: per-action checks for a `Sign7702Authorization` action.
8
- // Shared between intent-scope (`validateSign7702Actions`) and hook-scope
9
- // (`validateHookSign7702Binding`); both wrap this with their scope-specific
10
- // constraints (intent: position+duplicate; hook: type↔actions binding +
11
- // `validateHookDelegateOp` for position/count).
12
- export function validateSign7702Action(action, actionPath, realChainId) {
13
- const violations = [];
14
- // HIGH: actions[] must contain exactly one element — Delegate
15
- const ops = action.actions;
16
- if (ops.length !== 1 || ops[0] !== EvmActionOperation.Delegate) {
17
- violations.push({
18
- code: ViolationCode.Sign7702ActionsNotSingleDelegate,
19
- message: `Sign7702Authorization actions must contain exactly [Delegate]`,
20
- path: `${actionPath}.actions`,
21
- expected: [EvmActionOperation.Delegate],
22
- actual: action.actions,
23
- });
24
- }
25
- // CRITICAL: data.contractAddress must be in the whitelist
26
- const data = action.data;
27
- const contractAddress = data?.contractAddress;
28
- if (!contractAddress
29
- || !isWhitelisted(EIP7702_DELEGATION_CONTRACTS, realChainId, contractAddress)) {
30
- violations.push({
31
- code: ViolationCode.Sign7702ContractAddressNotWhitelisted,
32
- message: `Sign7702Authorization contractAddress is not in the whitelist`,
33
- path: `${actionPath}.data.contractAddress`,
34
- actual: contractAddress,
35
- });
36
- }
37
- return violations;
38
- }
39
7
  export function validateSign7702Actions(actions, basePath, realChainId) {
40
8
  const violations = [];
41
9
  let sign7702Count = 0;
@@ -45,7 +13,28 @@ export function validateSign7702Actions(actions, basePath, realChainId) {
45
13
  if (action.type !== EvmActionKind.Sign7702Authorization)
46
14
  continue;
47
15
  const actionPath = `${basePath}.requiredActions[${i}]`;
48
- violations.push(...validateSign7702Action(action, actionPath, realChainId));
16
+ // HIGH: actions[] must contain exactly one element — Delegate
17
+ if (action.actions.length !== 1 ||
18
+ action.actions[0] !== EvmActionOperation.Delegate) {
19
+ violations.push({
20
+ code: ViolationCode.Sign7702ActionsNotSingleDelegate,
21
+ message: `Sign7702Authorization actions must contain exactly [Delegate]`,
22
+ path: `${actionPath}.actions`,
23
+ expected: [EvmActionOperation.Delegate],
24
+ actual: action.actions,
25
+ });
26
+ }
27
+ // CRITICAL: data.contractAddress must be in the whitelist
28
+ const data = action.data;
29
+ const contractAddress = data?.contractAddress;
30
+ if (!contractAddress || !isWhitelisted(EIP7702_DELEGATION_CONTRACTS, realChainId, contractAddress)) {
31
+ violations.push({
32
+ code: ViolationCode.Sign7702ContractAddressNotWhitelisted,
33
+ message: `Sign7702Authorization contractAddress is not in the whitelist`,
34
+ path: `${actionPath}.data.contractAddress`,
35
+ actual: contractAddress,
36
+ });
37
+ }
49
38
  // HIGH: at most one Sign7702Authorization per intent
50
39
  // Note: only the first duplicate will be reported, subsequent ones will be ignored
51
40
  sign7702Count++;
@@ -1 +1 @@
1
- {"version":3,"file":"evm-sign7702.js","sourceRoot":"","sources":["../../../src/validations/evm-sign7702.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,aAAa,EAEb,aAAa,EACb,kBAAkB,GAIrB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAEjE,gDAAgD;AAChD,oCAAoC;AACpC,gDAAgD;AAEhD,oEAAoE;AACpE,yEAAyE;AACzE,4EAA4E;AAC5E,wEAAwE;AACxE,gDAAgD;AAChD,MAAM,UAAU,sBAAsB,CAClC,MAA0E,EAC1E,UAAkB,EAClB,WAAoB;IAEpB,MAAM,UAAU,GAAgB,EAAE,CAAC;IAEnC,8DAA8D;IAC9D,MAAM,GAAG,GAAG,MAAM,CAAC,OAAmB,CAAC;IACvC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,kBAAkB,CAAC,QAAQ,EAAE,CAAC;QAC7D,UAAU,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,aAAa,CAAC,gCAAgC;YACpD,OAAO,EAAE,+DAA+D;YACxE,IAAI,EAAE,GAAG,UAAU,UAAU;YAC7B,QAAQ,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC;YACvC,MAAM,EAAE,MAAM,CAAC,OAAO;SACzB,CAAC,CAAC;IACP,CAAC;IAED,0DAA0D;IAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAgD,CAAC;IACrE,MAAM,eAAe,GAAG,IAAI,EAAE,eAAe,CAAC;IAC9C,IACI,CAAC,eAAe;WACb,CAAC,aAAa,CAAC,4BAA4B,EAAE,WAAW,EAAE,eAAe,CAAC,EAC/E,CAAC;QACC,UAAU,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,aAAa,CAAC,qCAAqC;YACzD,OAAO,EAAE,+DAA+D;YACxE,IAAI,EAAE,GAAG,UAAU,uBAAuB;YAC1C,MAAM,EAAE,eAAe;SAC1B,CAAC,CAAC;IACP,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,uBAAuB,CACnC,OAA4B,EAC5B,QAAgB,EAChB,WAAoB;IAEpB,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,kBAAkB,GAAG,CAAC,CAAC,CAAC;IAE5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,CAAC,qBAAqB;YAAE,SAAS;QAElE,MAAM,UAAU,GAAG,GAAG,QAAQ,oBAAoB,CAAC,GAAG,CAAC;QACvD,UAAU,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;QAE5E,qDAAqD;QACrD,mFAAmF;QACnF,aAAa,EAAE,CAAC;QAChB,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;YACtB,kBAAkB,GAAG,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;YAC7B,UAAU,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,aAAa,CAAC,8BAA8B;gBAClD,OAAO,EAAE,kEAAkE,kBAAkB,QAAQ,CAAC,EAAE;gBACxG,IAAI,EAAE,GAAG,UAAU,OAAO;gBAC1B,QAAQ,EAAE,CAAC;gBACX,MAAM,EAAE,aAAa;aACxB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"evm-sign7702.js","sourceRoot":"","sources":["../../../src/validations/evm-sign7702.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,aAAa,EAEb,aAAa,EACb,kBAAkB,GAGrB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAEjE,gDAAgD;AAChD,oCAAoC;AACpC,gDAAgD;AAEhD,MAAM,UAAU,uBAAuB,CACnC,OAA4B,EAC5B,QAAgB,EAChB,WAAoB;IAEpB,MAAM,UAAU,GAAgB,EAAE,CAAC;IACnC,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,kBAAkB,GAAG,CAAC,CAAC,CAAC;IAE5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,CAAC,qBAAqB;YAAE,SAAS;QAElE,MAAM,UAAU,GAAG,GAAG,QAAQ,oBAAoB,CAAC,GAAG,CAAC;QAEvD,8DAA8D;QAC9D,IACI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YAC3B,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,kBAAkB,CAAC,QAAQ,EACnD,CAAC;YACC,UAAU,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,aAAa,CAAC,gCAAgC;gBACpD,OAAO,EAAE,+DAA+D;gBACxE,IAAI,EAAE,GAAG,UAAU,UAAU;gBAC7B,QAAQ,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC;gBACvC,MAAM,EAAE,MAAM,CAAC,OAAO;aACzB,CAAC,CAAC;QACP,CAAC;QAED,0DAA0D;QAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,IAAgD,CAAC;QACrE,MAAM,eAAe,GAAG,IAAI,EAAE,eAAe,CAAC;QAC9C,IAAI,CAAC,eAAe,IAAI,CAAC,aAAa,CAAC,4BAA4B,EAAE,WAAW,EAAE,eAAe,CAAC,EAAE,CAAC;YACjG,UAAU,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,aAAa,CAAC,qCAAqC;gBACzD,OAAO,EAAE,+DAA+D;gBACxE,IAAI,EAAE,GAAG,UAAU,uBAAuB;gBAC1C,MAAM,EAAE,eAAe;aAC1B,CAAC,CAAC;QACP,CAAC;QAED,qDAAqD;QACrD,mFAAmF;QACnF,aAAa,EAAE,CAAC;QAChB,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;YACtB,kBAAkB,GAAG,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;YAC7B,UAAU,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,aAAa,CAAC,8BAA8B;gBAClD,OAAO,EAAE,kEAAkE,kBAAkB,QAAQ,CAAC,EAAE;gBACxG,IAAI,EAAE,GAAG,UAAU,OAAO;gBAC1B,QAAQ,EAAE,CAAC;gBACX,MAAM,EAAE,aAAa;aACxB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC"}
@@ -1,26 +1,9 @@
1
1
  import { ViolationCode, } from "../types/index.js";
2
- import { BundleHookType, ChainEngine, EvmActionOperation, SolanaActionOperation, } from "../types/enums.js";
3
- import { addressEquals, getChainEngine } from "../helpers/address.js";
4
- import { extractGasCompensationGroups } from "../helpers/gas-compensation.js";
5
- import { HookMode, PlaceholderResolutionErrorReason, resolveEagerPlaceholders, } from "../helpers/placeholder.js";
2
+ import { ChainId } from "../types/enums.js";
6
3
  import { validateSolanaHookActions } from "./solana-hook.js";
7
- import { validateEvmHookActions } from "./evm-op-hook.js";
8
- import { validateCompensationHookStructure } from "./compensation-hook.js";
9
- import { resolveChainId, resolveChainIdOrSelf, } from "../whitelists/subscription-to-chain-id.js";
10
- // Re-exported so call sites can pass the mode without importing from helpers.
11
- export { HookMode } from "../helpers/placeholder.js";
12
- // Allowed hook-scope operations — each chain checked against its own enum.
13
- const EVM_HOOK_OPERATIONS = [
14
- EvmActionOperation.Delegate,
15
- EvmActionOperation.Hook,
16
- EvmActionOperation.GasCompensation,
17
- ];
18
- const EVM_HOOK_OPERATIONS_SET = new Set(EVM_HOOK_OPERATIONS);
19
- const SOLANA_HOOK_OPERATIONS = [
20
- SolanaActionOperation.Hook,
21
- SolanaActionOperation.GasCompensation,
22
- ];
23
- const SOLANA_HOOK_OPERATIONS_SET = new Set(SOLANA_HOOK_OPERATIONS);
4
+ // Both EVM and Solana use identical string values for hook operations
5
+ const HOOK_OPERATIONS = ["Hook", "GasCompensation"];
6
+ const HOOK_OPERATIONS_SET = new Set(HOOK_OPERATIONS);
24
7
  export function validateHooks(request, response, quoteMode) {
25
8
  return [
26
9
  ...validateHookAAConstraint(request, response),
@@ -54,35 +37,26 @@ function validateHookAAConstraint(request, response) {
54
37
  }
55
38
  return violations;
56
39
  }
57
- // HIGH: preHooks = request.preHooks + one compensation hook per unique
58
- // gasCompensationInfo group (exact equality — API always adds one per group).
59
- // postHooks must match exactly — the API never adds extras to postHooks.
40
+ // HIGH: response.preHooks.length must equal request.preHooks.length
60
41
  function validateHookCounts(request, response) {
61
42
  const violations = [];
62
43
  const requestPreCount = request.preHooks?.length ?? 0;
63
44
  const requestPostCount = request.postHooks?.length ?? 0;
64
- // preHooks: exactly request.preHooks.length + one per unique gas
65
- // compensation group. If request has no gasCompensationInfo at all, extras
66
- // are forbidden (this also guards against MITM adding preHook entries when
67
- // the user never asked for compensation).
68
- const compensationGroupCount = extractGasCompensationGroups(request).length;
69
- const expectedPreCount = requestPreCount + compensationGroupCount;
70
- if (response.preHooks.length !== expectedPreCount) {
45
+ if (response.preHooks.length !== requestPreCount) {
71
46
  violations.push({
72
47
  code: ViolationCode.HookCountMismatch,
73
- message: "response.preHooks count does not match"
74
- + " request.preHooks.length + unique gasCompensationInfo groups",
48
+ message: "response.preHooks count does not match request.preHooks count",
75
49
  path: "response.preHooks",
76
- expected: expectedPreCount,
50
+ expected: requestPreCount,
77
51
  actual: response.preHooks.length,
78
52
  });
79
53
  }
80
- // postHooks: strict 1:1 match, no extras allowed
81
- if (response.postHooks.length !== requestPostCount) {
54
+ // postHooks may contain additional compensation hooks beyond what was in the request,
55
+ // so response count must be >= request count
56
+ if (response.postHooks.length < requestPostCount) {
82
57
  violations.push({
83
58
  code: ViolationCode.HookCountMismatch,
84
- message: "response.postHooks count does not match"
85
- + " request.postHooks count",
59
+ message: "response.postHooks count is less than request.postHooks count",
86
60
  path: "response.postHooks",
87
61
  expected: requestPostCount,
88
62
  actual: response.postHooks.length,
@@ -97,7 +71,7 @@ function validatePreHooks(request, response, quoteMode) {
97
71
  const basePath = `response.preHooks[${i}]`;
98
72
  const hookPayload = response.preHooks[i];
99
73
  const requestHook = requestHooks[i];
100
- violations.push(...validateSingleHookPayload(hookPayload, requestHook, basePath, request, response.trades, HookMode.PreHooks, quoteMode));
74
+ violations.push(...validateSingleHookPayload(hookPayload, requestHook, basePath, request, quoteMode));
101
75
  }
102
76
  return violations;
103
77
  }
@@ -109,153 +83,31 @@ function validatePostHooks(request, response, quoteMode) {
109
83
  const hookPayload = response.postHooks[i];
110
84
  // User postHooks are matched by index; extra entries are compensation hooks
111
85
  const requestHook = i < requestHooks.length ? requestHooks[i] : undefined;
112
- violations.push(...validateSingleHookPayload(hookPayload, requestHook, basePath, request, response.trades, HookMode.PostHooks, quoteMode));
86
+ violations.push(...validateSingleHookPayload(hookPayload, requestHook, basePath, request, quoteMode));
113
87
  }
114
88
  return violations;
115
89
  }
116
- function validateSingleHookPayload(hookPayload, requestHook, basePath, request, responseTrades, mode, quoteMode) {
117
- const isCompensationPreHook = requestHook === undefined && mode === HookMode.PreHooks;
90
+ function validateSingleHookPayload(hookPayload, requestHook, basePath, request, quoteMode) {
118
91
  return [
119
- ...validateHookEcho(hookPayload, requestHook, basePath, responseTrades, mode),
92
+ ...validateHookEcho(hookPayload, requestHook, basePath),
120
93
  ...validateHookUniqueActionIds(hookPayload, basePath),
121
94
  ...validateHookActionsList(hookPayload, basePath),
122
- ...validateHookDelegateOp(hookPayload, basePath),
123
- ...validateHookSolanaNotDirect(hookPayload, basePath),
124
95
  ...validateGasCompensationRequiresInfo(hookPayload, basePath, request),
125
- ...(isCompensationPreHook
126
- ? validateCompensationHookStructure(hookPayload, basePath, request)
127
- : []),
128
- ...dispatchChainSpecificValidation(hookPayload, requestHook, basePath, quoteMode, request, mode, responseTrades),
96
+ ...dispatchChainSpecificValidation(hookPayload, requestHook, basePath, quoteMode, request),
129
97
  ];
130
98
  }
131
- // MEDIUM: Solana hooks must not be of type 'direct'.
132
- function validateHookSolanaNotDirect(hookPayload, basePath) {
133
- const realChainId = resolveChainIdOrSelf(hookPayload.hook.chainId);
134
- if (getChainEngine(realChainId) !== ChainEngine.Solana)
99
+ // CRITICAL: response hook must echo back the request hook exactly
100
+ function validateHookEcho(hookPayload, requestHook, basePath) {
101
+ if (!requestHook)
135
102
  return [];
136
- if (hookPayload.hook.type !== BundleHookType.Direct)
137
- return [];
138
- return [{
139
- code: ViolationCode.HookSolanaCannotBeDirect,
140
- message: "Solana hooks cannot be of type 'direct'",
141
- path: `${basePath}.hook.type`,
142
- expected: BundleHookType.Delegated,
143
- actual: hookPayload.hook.type,
144
- }];
145
- }
146
- // CRITICAL: response hook must echo back the request hook field-by-field.
147
- // Notes:
148
- // - hook.data in the response has eager placeholders resolved (deferred markers kept).
149
- // We apply the same resolution to request.data and compare.
150
- // - For Solana hooks the API deletes `to` and `value` in the echo; we skip those.
151
- // - For EVM hooks `value` is copied from request as-is (eager resolution is not
152
- // reflected in the echoed value — only in internal txData used by requiredActions).
153
- function validateHookEcho(hookPayload, requestHook, basePath, responseTrades, mode) {
154
- // Missing request counterpart — two shapes, both are MITM-safe:
155
- // (a) preHook with `i >= request.preHooks.length`:
156
- // legitimate case — compensation hook appended by the API.
157
- // MITM case — attacker injects an arbitrary preHook.
158
- // The echo-by-field check can't distinguish them (there's no request
159
- // to compare against), so we delegate to the structural compensation
160
- // check.
161
- // (b) postHook with `i >= request.postHooks.length`:
162
- // no legitimate case — the API never appends to postHooks. So we
163
- // produce a violation.
164
- if (!requestHook) {
165
- if (mode === HookMode.PostHooks) {
166
- return [{
167
- code: ViolationCode.UnexpectedPostHook,
168
- message: "response.postHooks contains an entry with no matching"
169
- + " request postHook",
170
- path: `${basePath}.hook`,
171
- actual: hookPayload.hook,
172
- }];
173
- }
174
- return [];
175
- }
176
- const echoed = hookPayload.hook;
177
- const chainId = requestHook.chainId;
178
- const realChainId = resolveChainIdOrSelf(chainId);
179
- const isSolana = getChainEngine(realChainId) === ChainEngine.Solana;
180
- const hookPath = `${basePath}.hook`;
181
- const violations = [];
182
- // chainId — strict number equality (subscriptionId on both sides)
183
- if (echoed.chainId !== chainId) {
184
- violations.push(echoMismatch(`${hookPath}.chainId`, requestHook.chainId, echoed.chainId));
185
- }
186
- // from — address equality
187
- if (!addressEquals(realChainId, echoed.from, requestHook.from)) {
188
- violations.push(echoMismatch(`${hookPath}.from`, requestHook.from, echoed.from));
189
- }
190
- // isAtomic — strict boolean
191
- if (echoed.isAtomic !== requestHook.isAtomic) {
192
- violations.push(echoMismatch(`${hookPath}.isAtomic`, requestHook.isAtomic, echoed.isAtomic));
193
- }
194
- // to, value — chain-dependent.
195
- // Solana: API deletes both from the echo; skip entirely.
196
- // EVM: compare as-is (value is not modified by placeholder resolution).
197
- if (!isSolana) {
198
- violations.push(...compareOptionalAddress(realChainId, `${hookPath}.to`, requestHook.to, echoed.to));
199
- violations.push(...compareOptionalString(`${hookPath}.value`, requestHook.value, echoed.value));
200
- }
201
- // data — eager placeholders are resolved by the API before echoing.
202
- const { resolved: expectedData, errors } = resolveEagerPlaceholders(requestHook.data, realChainId, requestHook.placeHolders, responseTrades, mode);
203
- for (const error of errors) {
204
- const reasonText = PlaceholderResolutionErrorReason[error.reason];
205
- violations.push({
206
- code: ViolationCode.HookPlaceholderResolutionFailed,
207
- message: `failed to resolve placeholder "${error.nameVariable}"`
208
- + ` (${reasonText})`,
209
- path: `${hookPath}.data`,
210
- actual: { nameVariable: error.nameVariable, reason: reasonText },
211
- details: error.details,
212
- });
213
- }
214
- if (expectedData !== echoed.data) {
215
- violations.push(echoMismatch(`${hookPath}.data`, expectedData, echoed.data));
216
- }
217
- // placeHolders — deep equality via stringify (same source → same serialization).
218
- if (JSON.stringify(echoed.placeHolders)
219
- !== JSON.stringify(requestHook.placeHolders)) {
220
- violations.push(echoMismatch(`${hookPath}.placeHolders`, requestHook.placeHolders, echoed.placeHolders));
221
- }
222
- // gasCompensationInfo — deep equality or both undefined.
223
- if (JSON.stringify(echoed.gasCompensationInfo)
224
- !== JSON.stringify(requestHook.gasCompensationInfo)) {
225
- violations.push(echoMismatch(`${hookPath}.gasCompensationInfo`, requestHook.gasCompensationInfo, echoed.gasCompensationInfo));
226
- }
227
- // type — strict equality (or both undefined).
228
- if (echoed.type !== requestHook.type) {
229
- violations.push(echoMismatch(`${hookPath}.type`, requestHook.type, echoed.type));
230
- }
231
- // gasLimit — strict string equality (or both undefined).
232
- if (echoed.gasLimit !== requestHook.gasLimit) {
233
- violations.push(echoMismatch(`${hookPath}.gasLimit`, requestHook.gasLimit, echoed.gasLimit));
234
- }
235
- return violations;
236
- }
237
- function echoMismatch(path, expected, actual) {
238
- return {
239
- code: ViolationCode.HookEchoMismatch,
240
- message: "response hook field does not match request",
241
- path,
242
- expected,
243
- actual,
244
- };
245
- }
246
- function compareOptionalString(path, expected, actual) {
247
- if (expected === actual)
248
- return [];
249
- return [echoMismatch(path, expected, actual)];
250
- }
251
- function compareOptionalAddress(chainId, path, expected, actual) {
252
- if (expected === undefined && actual === undefined)
253
- return [];
254
- if (expected === undefined || actual === undefined) {
255
- return [echoMismatch(path, expected, actual)];
256
- }
257
- if (!addressEquals(chainId, expected, actual)) {
258
- return [echoMismatch(path, expected, actual)];
103
+ if (JSON.stringify(hookPayload.hook) !== JSON.stringify(requestHook)) {
104
+ return [{
105
+ code: ViolationCode.HookEchoMismatch,
106
+ message: "response hook does not match request hook",
107
+ path: `${basePath}.hook`,
108
+ expected: requestHook,
109
+ actual: hookPayload.hook,
110
+ }];
259
111
  }
260
112
  return [];
261
113
  }
@@ -283,10 +135,6 @@ function validateHookUniqueActionIds(hookPayload, basePath) {
283
135
  }
284
136
  // HIGH: each hook required action must have exactly one operation: [Hook] or [GasCompensation]
285
137
  function validateHookActionsList(hookPayload, basePath) {
286
- const realChainId = resolveChainIdOrSelf(hookPayload.hook.chainId);
287
- const isSolana = getChainEngine(realChainId) === ChainEngine.Solana;
288
- const allowedSet = isSolana ? SOLANA_HOOK_OPERATIONS_SET : EVM_HOOK_OPERATIONS_SET;
289
- const allowedList = isSolana ? SOLANA_HOOK_OPERATIONS : EVM_HOOK_OPERATIONS;
290
138
  const violations = [];
291
139
  for (let i = 0; i < hookPayload.requiredActions.length; i++) {
292
140
  const action = hookPayload.requiredActions[i];
@@ -301,85 +149,26 @@ function validateHookActionsList(hookPayload, basePath) {
301
149
  });
302
150
  continue;
303
151
  }
304
- if (!allowedSet.has(action.actions[0])) {
152
+ if (!HOOK_OPERATIONS_SET.has(action.actions[0])) {
305
153
  violations.push({
306
154
  code: ViolationCode.HookActionsInvalid,
307
155
  message: "hook required action operation must be Hook"
308
156
  + " or GasCompensation",
309
157
  path: `${actionPath}.actions`,
310
- expected: allowedList,
158
+ expected: HOOK_OPERATIONS,
311
159
  actual: action.actions,
312
160
  });
313
161
  }
314
162
  }
315
163
  return violations;
316
164
  }
317
- // HIGH: Delegate-op constraints for EVM hook requiredActions.
318
- // * `Delegate` may appear at most once.
319
- // * If present, it must be the first required action (the API emits
320
- // Sign7702Authorization → Sign712MetaMaskCaveats* in this order).
321
- // * Direct hooks (`hook.type === 'direct'`) must not contain `Delegate`
322
- // (Direct mode skips EIP-7702 delegation entirely).
323
- // Solana hooks bypass this check — `Delegate` is rejected upstream by
324
- // `validateHookActionsList`.
325
- function validateHookDelegateOp(hookPayload, basePath) {
326
- const realChainId = resolveChainIdOrSelf(hookPayload.hook.chainId);
327
- if (getChainEngine(realChainId) === ChainEngine.Solana)
328
- return [];
329
- const indices = [];
330
- for (let i = 0; i < hookPayload.requiredActions.length; i++) {
331
- const action = hookPayload.requiredActions[i];
332
- const ops = action.actions;
333
- if (ops.includes(EvmActionOperation.Delegate)) {
334
- indices.push(i);
335
- }
336
- }
337
- if (indices.length === 0)
338
- return [];
339
- const violations = [];
340
- if (hookPayload.hook.type === BundleHookType.Direct) {
341
- violations.push({
342
- code: ViolationCode.HookDelegateInDirect,
343
- message: "Direct hook must not contain a Delegate operation"
344
- + " (Direct mode skips EIP-7702 delegation)",
345
- path: `${basePath}.requiredActions`,
346
- actual: indices,
347
- });
348
- }
349
- if (indices.length > 1) {
350
- violations.push({
351
- code: ViolationCode.HookMultipleDelegate,
352
- message: "hook requiredActions must contain at most one Delegate",
353
- path: `${basePath}.requiredActions`,
354
- expected: 1,
355
- actual: indices,
356
- });
357
- }
358
- if (indices[0] !== 0) {
359
- violations.push({
360
- code: ViolationCode.HookDelegateNotFirst,
361
- message: "if Delegate is present in hook requiredActions, it must be"
362
- + " the first action",
363
- path: `${basePath}.requiredActions[${indices[0]}]`,
364
- expected: 0,
365
- actual: indices[0],
366
- });
367
- }
368
- return violations;
369
- }
370
165
  // CRITICAL: GasCompensation must only appear when gasCompensationInfo exists
371
166
  function validateGasCompensationRequiresInfo(hookPayload, basePath, request) {
372
167
  const hasGasCompensationInfo = (request.preHooks ?? []).some(h => h.gasCompensationInfo !== undefined);
373
- const realChainId = resolveChainIdOrSelf(hookPayload.hook.chainId);
374
- const isSolana = getChainEngine(realChainId) === ChainEngine.Solana;
375
- const gasCompensationOp = isSolana
376
- ? SolanaActionOperation.GasCompensation
377
- : EvmActionOperation.GasCompensation;
378
168
  const violations = [];
379
169
  for (let i = 0; i < hookPayload.requiredActions.length; i++) {
380
170
  const action = hookPayload.requiredActions[i];
381
- const hasGasCompensation = action.actions
382
- .includes(gasCompensationOp);
171
+ const hasGasCompensation = action.actions.includes("GasCompensation");
383
172
  if (hasGasCompensation && !hasGasCompensationInfo) {
384
173
  violations.push({
385
174
  code: ViolationCode.HookGasCompensationWithoutInfo,
@@ -392,20 +181,18 @@ function validateGasCompensationRequiresInfo(hookPayload, basePath, request) {
392
181
  }
393
182
  return violations;
394
183
  }
395
- function dispatchChainSpecificValidation(hookPayload, requestHook, basePath, quoteMode, request, mode, responseTrades) {
396
- const realChainId = resolveChainIdOrSelf(hookPayload.hook.chainId);
397
- if (getChainEngine(realChainId) === ChainEngine.Solana) {
184
+ function dispatchChainSpecificValidation(hookPayload, requestHook, basePath, quoteMode, request) {
185
+ const chainId = hookPayload.hook.chainId;
186
+ if (chainId === ChainId.Solana) {
398
187
  const srcChainAuthorityAddress = findSolanaSrcChainAuthority(request);
399
- return validateSolanaHookActions(hookPayload, requestHook, basePath, quoteMode, srcChainAuthorityAddress, request, realChainId, mode, responseTrades);
188
+ return validateSolanaHookActions(hookPayload, requestHook, basePath, quoteMode, srcChainAuthorityAddress, request);
400
189
  }
401
- return validateEvmHookActions(hookPayload, requestHook, basePath, mode, responseTrades, realChainId, request);
190
+ // AI: EVM hook validation dispatch will go here when implemented
191
+ return [];
402
192
  }
403
193
  function findSolanaSrcChainAuthority(request) {
404
194
  for (const trade of request.trades) {
405
- const realChainId = resolveChainId(trade.srcChainId);
406
- if (realChainId === undefined)
407
- continue;
408
- if (getChainEngine(realChainId) === ChainEngine.Solana) {
195
+ if (trade.srcChainId === ChainId.Solana) {
409
196
  return trade.srcChainAuthorityAddress;
410
197
  }
411
198
  }