@debridge-finance/borderless-validation-sdk 0.0.0-dev-dee2389
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.
- package/dist/cjs/graylists/evm/token-permit-metadata.js +28 -0
- package/dist/cjs/graylists/evm/token-permit-metadata.js.map +1 -0
- package/dist/cjs/helpers/address.js +75 -0
- package/dist/cjs/helpers/address.js.map +1 -0
- package/dist/cjs/helpers/caveat-decoder.js +60 -0
- package/dist/cjs/helpers/caveat-decoder.js.map +1 -0
- package/dist/cjs/helpers/constants.js +6 -0
- package/dist/cjs/helpers/constants.js.map +1 -0
- package/dist/cjs/helpers/evm-action.js +20 -0
- package/dist/cjs/helpers/evm-action.js.map +1 -0
- package/dist/cjs/helpers/evm-calldata.js +45 -0
- package/dist/cjs/helpers/evm-calldata.js.map +1 -0
- package/dist/cjs/helpers/evm-intent-id-abi.js +67 -0
- package/dist/cjs/helpers/evm-intent-id-abi.js.map +1 -0
- package/dist/cjs/helpers/evm-intent-id.js +70 -0
- package/dist/cjs/helpers/evm-intent-id.js.map +1 -0
- package/dist/cjs/helpers/evm-token.js +30 -0
- package/dist/cjs/helpers/evm-token.js.map +1 -0
- package/dist/cjs/helpers/evm-trade-amounts.js +42 -0
- package/dist/cjs/helpers/evm-trade-amounts.js.map +1 -0
- package/dist/cjs/helpers/solana-instruction.js +160 -0
- package/dist/cjs/helpers/solana-instruction.js.map +1 -0
- package/dist/cjs/helpers/solana-intent-id.js +460 -0
- package/dist/cjs/helpers/solana-intent-id.js.map +1 -0
- package/dist/cjs/helpers/solana-transaction-decode.js +58 -0
- package/dist/cjs/helpers/solana-transaction-decode.js.map +1 -0
- package/dist/cjs/helpers/zod.js +12 -0
- package/dist/cjs/helpers/zod.js.map +1 -0
- package/dist/cjs/index.js +9 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/types/enums.js +137 -0
- package/dist/cjs/types/enums.js.map +1 -0
- package/dist/cjs/types/index.js +21 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/types/request.js +65 -0
- package/dist/cjs/types/request.js.map +1 -0
- package/dist/cjs/types/response.js +252 -0
- package/dist/cjs/types/response.js.map +1 -0
- package/dist/cjs/types/validation.js +242 -0
- package/dist/cjs/types/validation.js.map +1 -0
- package/dist/cjs/validations/echo-fields.js +67 -0
- package/dist/cjs/validations/echo-fields.js.map +1 -0
- package/dist/cjs/validations/evm-caveats.js +235 -0
- package/dist/cjs/validations/evm-caveats.js.map +1 -0
- package/dist/cjs/validations/evm-op-budget.js +261 -0
- package/dist/cjs/validations/evm-op-budget.js.map +1 -0
- package/dist/cjs/validations/evm-op-gas-compensation.js +152 -0
- package/dist/cjs/validations/evm-op-gas-compensation.js.map +1 -0
- package/dist/cjs/validations/evm-op-hook.js +8 -0
- package/dist/cjs/validations/evm-op-hook.js.map +1 -0
- package/dist/cjs/validations/evm-op-wrap.js +112 -0
- package/dist/cjs/validations/evm-op-wrap.js.map +1 -0
- package/dist/cjs/validations/evm-permit.js +224 -0
- package/dist/cjs/validations/evm-permit.js.map +1 -0
- package/dist/cjs/validations/evm-permit2.js +361 -0
- package/dist/cjs/validations/evm-permit2.js.map +1 -0
- package/dist/cjs/validations/evm-required-actions.js +184 -0
- package/dist/cjs/validations/evm-required-actions.js.map +1 -0
- package/dist/cjs/validations/evm-sign712-metamask.js +147 -0
- package/dist/cjs/validations/evm-sign712-metamask.js.map +1 -0
- package/dist/cjs/validations/evm-sign712.js +203 -0
- package/dist/cjs/validations/evm-sign712.js.map +1 -0
- package/dist/cjs/validations/evm-sign7702.js +59 -0
- package/dist/cjs/validations/evm-sign7702.js.map +1 -0
- package/dist/cjs/validations/evm-transaction.js +38 -0
- package/dist/cjs/validations/evm-transaction.js.map +1 -0
- package/dist/cjs/validations/hooks-common.js +207 -0
- package/dist/cjs/validations/hooks-common.js.map +1 -0
- package/dist/cjs/validations/required-actions.js +69 -0
- package/dist/cjs/validations/required-actions.js.map +1 -0
- package/dist/cjs/validations/solana-hook.js +225 -0
- package/dist/cjs/validations/solana-hook.js.map +1 -0
- package/dist/cjs/validations/solana-op-budget.js +293 -0
- package/dist/cjs/validations/solana-op-budget.js.map +1 -0
- package/dist/cjs/validations/solana-op-wrap.js +191 -0
- package/dist/cjs/validations/solana-op-wrap.js.map +1 -0
- package/dist/cjs/validations/solana-required-actions.js +122 -0
- package/dist/cjs/validations/solana-required-actions.js.map +1 -0
- package/dist/cjs/validations/solana-sign.js +171 -0
- package/dist/cjs/validations/solana-sign.js.map +1 -0
- package/dist/cjs/validations/solana-transaction.js +238 -0
- package/dist/cjs/validations/solana-transaction.js.map +1 -0
- package/dist/cjs/validations/trade-grouping.js +165 -0
- package/dist/cjs/validations/trade-grouping.js.map +1 -0
- package/dist/cjs/validations/trade-intent-consistency.js +104 -0
- package/dist/cjs/validations/trade-intent-consistency.js.map +1 -0
- package/dist/cjs/validations/trades.js +517 -0
- package/dist/cjs/validations/trades.js.map +1 -0
- package/dist/cjs/validator.js +75 -0
- package/dist/cjs/validator.js.map +1 -0
- package/dist/cjs/whitelists/environment-config.js +118 -0
- package/dist/cjs/whitelists/environment-config.js.map +1 -0
- package/dist/cjs/whitelists/evm/caveat-enforcers.js +18 -0
- package/dist/cjs/whitelists/evm/caveat-enforcers.js.map +1 -0
- package/dist/cjs/whitelists/evm/delegation-manager.js +9 -0
- package/dist/cjs/whitelists/evm/delegation-manager.js.map +1 -0
- package/dist/cjs/whitelists/evm/eip7702-delegation.js +8 -0
- package/dist/cjs/whitelists/evm/eip7702-delegation.js.map +1 -0
- package/dist/cjs/whitelists/evm/index.js +17 -0
- package/dist/cjs/whitelists/evm/index.js.map +1 -0
- package/dist/cjs/whitelists/evm/permit2.js +18 -0
- package/dist/cjs/whitelists/evm/permit2.js.map +1 -0
- package/dist/cjs/whitelists/evm/weth.js +19 -0
- package/dist/cjs/whitelists/evm/weth.js.map +1 -0
- package/dist/cjs/whitelists/solana/index.js +19 -0
- package/dist/cjs/whitelists/solana/index.js.map +1 -0
- package/dist/cjs/whitelists/solana/intent-signature.js +25 -0
- package/dist/cjs/whitelists/solana/intent-signature.js.map +1 -0
- package/dist/cjs/whitelists/solana/programs.js +19 -0
- package/dist/cjs/whitelists/solana/programs.js.map +1 -0
- package/dist/cjs/whitelists/subscription-to-chain-id.js +36 -0
- package/dist/cjs/whitelists/subscription-to-chain-id.js.map +1 -0
- package/dist/cjs/whitelists/types.js +29 -0
- package/dist/cjs/whitelists/types.js.map +1 -0
- package/dist/esm/graylists/evm/token-permit-metadata.js +24 -0
- package/dist/esm/graylists/evm/token-permit-metadata.js.map +1 -0
- package/dist/esm/helpers/address.js +63 -0
- package/dist/esm/helpers/address.js.map +1 -0
- package/dist/esm/helpers/caveat-decoder.js +55 -0
- package/dist/esm/helpers/caveat-decoder.js.map +1 -0
- package/dist/esm/helpers/constants.js +3 -0
- package/dist/esm/helpers/constants.js.map +1 -0
- package/dist/esm/helpers/evm-action.js +16 -0
- package/dist/esm/helpers/evm-action.js.map +1 -0
- package/dist/esm/helpers/evm-calldata.js +39 -0
- package/dist/esm/helpers/evm-calldata.js.map +1 -0
- package/dist/esm/helpers/evm-intent-id-abi.js +64 -0
- package/dist/esm/helpers/evm-intent-id-abi.js.map +1 -0
- package/dist/esm/helpers/evm-intent-id.js +67 -0
- package/dist/esm/helpers/evm-intent-id.js.map +1 -0
- package/dist/esm/helpers/evm-token.js +25 -0
- package/dist/esm/helpers/evm-token.js.map +1 -0
- package/dist/esm/helpers/evm-trade-amounts.js +39 -0
- package/dist/esm/helpers/evm-trade-amounts.js.map +1 -0
- package/dist/esm/helpers/solana-instruction.js +146 -0
- package/dist/esm/helpers/solana-instruction.js.map +1 -0
- package/dist/esm/helpers/solana-intent-id.js +457 -0
- package/dist/esm/helpers/solana-intent-id.js.map +1 -0
- package/dist/esm/helpers/solana-transaction-decode.js +55 -0
- package/dist/esm/helpers/solana-transaction-decode.js.map +1 -0
- package/dist/esm/helpers/zod.js +9 -0
- package/dist/esm/helpers/zod.js.map +1 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/types/enums.js +134 -0
- package/dist/esm/types/enums.js.map +1 -0
- package/dist/esm/types/index.js +5 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/request.js +62 -0
- package/dist/esm/types/request.js.map +1 -0
- package/dist/esm/types/response.js +249 -0
- package/dist/esm/types/response.js.map +1 -0
- package/dist/esm/types/validation.js +239 -0
- package/dist/esm/types/validation.js.map +1 -0
- package/dist/esm/validations/echo-fields.js +64 -0
- package/dist/esm/validations/echo-fields.js.map +1 -0
- package/dist/esm/validations/evm-caveats.js +228 -0
- package/dist/esm/validations/evm-caveats.js.map +1 -0
- package/dist/esm/validations/evm-op-budget.js +258 -0
- package/dist/esm/validations/evm-op-budget.js.map +1 -0
- package/dist/esm/validations/evm-op-gas-compensation.js +149 -0
- package/dist/esm/validations/evm-op-gas-compensation.js.map +1 -0
- package/dist/esm/validations/evm-op-hook.js +5 -0
- package/dist/esm/validations/evm-op-hook.js.map +1 -0
- package/dist/esm/validations/evm-op-wrap.js +109 -0
- package/dist/esm/validations/evm-op-wrap.js.map +1 -0
- package/dist/esm/validations/evm-permit.js +221 -0
- package/dist/esm/validations/evm-permit.js.map +1 -0
- package/dist/esm/validations/evm-permit2.js +358 -0
- package/dist/esm/validations/evm-permit2.js.map +1 -0
- package/dist/esm/validations/evm-required-actions.js +181 -0
- package/dist/esm/validations/evm-required-actions.js.map +1 -0
- package/dist/esm/validations/evm-sign712-metamask.js +144 -0
- package/dist/esm/validations/evm-sign712-metamask.js.map +1 -0
- package/dist/esm/validations/evm-sign712.js +200 -0
- package/dist/esm/validations/evm-sign712.js.map +1 -0
- package/dist/esm/validations/evm-sign7702.js +56 -0
- package/dist/esm/validations/evm-sign7702.js.map +1 -0
- package/dist/esm/validations/evm-transaction.js +35 -0
- package/dist/esm/validations/evm-transaction.js.map +1 -0
- package/dist/esm/validations/hooks-common.js +204 -0
- package/dist/esm/validations/hooks-common.js.map +1 -0
- package/dist/esm/validations/required-actions.js +66 -0
- package/dist/esm/validations/required-actions.js.map +1 -0
- package/dist/esm/validations/solana-hook.js +222 -0
- package/dist/esm/validations/solana-hook.js.map +1 -0
- package/dist/esm/validations/solana-op-budget.js +290 -0
- package/dist/esm/validations/solana-op-budget.js.map +1 -0
- package/dist/esm/validations/solana-op-wrap.js +188 -0
- package/dist/esm/validations/solana-op-wrap.js.map +1 -0
- package/dist/esm/validations/solana-required-actions.js +119 -0
- package/dist/esm/validations/solana-required-actions.js.map +1 -0
- package/dist/esm/validations/solana-sign.js +168 -0
- package/dist/esm/validations/solana-sign.js.map +1 -0
- package/dist/esm/validations/solana-transaction.js +234 -0
- package/dist/esm/validations/solana-transaction.js.map +1 -0
- package/dist/esm/validations/trade-grouping.js +161 -0
- package/dist/esm/validations/trade-grouping.js.map +1 -0
- package/dist/esm/validations/trade-intent-consistency.js +101 -0
- package/dist/esm/validations/trade-intent-consistency.js.map +1 -0
- package/dist/esm/validations/trades.js +514 -0
- package/dist/esm/validations/trades.js.map +1 -0
- package/dist/esm/validator.js +72 -0
- package/dist/esm/validator.js.map +1 -0
- package/dist/esm/whitelists/environment-config.js +115 -0
- package/dist/esm/whitelists/environment-config.js.map +1 -0
- package/dist/esm/whitelists/evm/caveat-enforcers.js +15 -0
- package/dist/esm/whitelists/evm/caveat-enforcers.js.map +1 -0
- package/dist/esm/whitelists/evm/delegation-manager.js +6 -0
- package/dist/esm/whitelists/evm/delegation-manager.js.map +1 -0
- package/dist/esm/whitelists/evm/eip7702-delegation.js +5 -0
- package/dist/esm/whitelists/evm/eip7702-delegation.js.map +1 -0
- package/dist/esm/whitelists/evm/index.js +6 -0
- package/dist/esm/whitelists/evm/index.js.map +1 -0
- package/dist/esm/whitelists/evm/permit2.js +15 -0
- package/dist/esm/whitelists/evm/permit2.js.map +1 -0
- package/dist/esm/whitelists/evm/weth.js +16 -0
- package/dist/esm/whitelists/evm/weth.js.map +1 -0
- package/dist/esm/whitelists/solana/index.js +3 -0
- package/dist/esm/whitelists/solana/index.js.map +1 -0
- package/dist/esm/whitelists/solana/intent-signature.js +22 -0
- package/dist/esm/whitelists/solana/intent-signature.js.map +1 -0
- package/dist/esm/whitelists/solana/programs.js +16 -0
- package/dist/esm/whitelists/solana/programs.js.map +1 -0
- package/dist/esm/whitelists/subscription-to-chain-id.js +32 -0
- package/dist/esm/whitelists/subscription-to-chain-id.js.map +1 -0
- package/dist/esm/whitelists/types.js +26 -0
- package/dist/esm/whitelists/types.js.map +1 -0
- package/dist/types/graylists/evm/token-permit-metadata.d.ts +11 -0
- package/dist/types/graylists/evm/token-permit-metadata.d.ts.map +1 -0
- package/dist/types/helpers/address.d.ts +13 -0
- package/dist/types/helpers/address.d.ts.map +1 -0
- package/dist/types/helpers/caveat-decoder.d.ts +13 -0
- package/dist/types/helpers/caveat-decoder.d.ts.map +1 -0
- package/dist/types/helpers/constants.d.ts +2 -0
- package/dist/types/helpers/constants.d.ts.map +1 -0
- package/dist/types/helpers/evm-action.d.ts +4 -0
- package/dist/types/helpers/evm-action.d.ts.map +1 -0
- package/dist/types/helpers/evm-calldata.d.ts +15 -0
- package/dist/types/helpers/evm-calldata.d.ts.map +1 -0
- package/dist/types/helpers/evm-intent-id-abi.d.ts +106 -0
- package/dist/types/helpers/evm-intent-id-abi.d.ts.map +1 -0
- package/dist/types/helpers/evm-intent-id.d.ts +3 -0
- package/dist/types/helpers/evm-intent-id.d.ts.map +1 -0
- package/dist/types/helpers/evm-token.d.ts +4 -0
- package/dist/types/helpers/evm-token.d.ts.map +1 -0
- package/dist/types/helpers/evm-trade-amounts.d.ts +16 -0
- package/dist/types/helpers/evm-trade-amounts.d.ts.map +1 -0
- package/dist/types/helpers/solana-instruction.d.ts +44 -0
- package/dist/types/helpers/solana-instruction.d.ts.map +1 -0
- package/dist/types/helpers/solana-intent-id.d.ts +3 -0
- package/dist/types/helpers/solana-intent-id.d.ts.map +1 -0
- package/dist/types/helpers/solana-transaction-decode.d.ts +18 -0
- package/dist/types/helpers/solana-transaction-decode.d.ts.map +1 -0
- package/dist/types/helpers/zod.d.ts +2 -0
- package/dist/types/helpers/zod.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/types/enums.d.ts +112 -0
- package/dist/types/types/enums.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +5 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/types/request.d.ts +134 -0
- package/dist/types/types/request.d.ts.map +1 -0
- package/dist/types/types/response.d.ts +1140 -0
- package/dist/types/types/response.d.ts.map +1 -0
- package/dist/types/types/validation.d.ts +216 -0
- package/dist/types/types/validation.d.ts.map +1 -0
- package/dist/types/validations/echo-fields.d.ts +3 -0
- package/dist/types/validations/echo-fields.d.ts.map +1 -0
- package/dist/types/validations/evm-caveats.d.ts +33 -0
- package/dist/types/validations/evm-caveats.d.ts.map +1 -0
- package/dist/types/validations/evm-op-budget.d.ts +4 -0
- package/dist/types/validations/evm-op-budget.d.ts.map +1 -0
- package/dist/types/validations/evm-op-gas-compensation.d.ts +3 -0
- package/dist/types/validations/evm-op-gas-compensation.d.ts.map +1 -0
- package/dist/types/validations/evm-op-hook.d.ts +3 -0
- package/dist/types/validations/evm-op-hook.d.ts.map +1 -0
- package/dist/types/validations/evm-op-wrap.d.ts +3 -0
- package/dist/types/validations/evm-op-wrap.d.ts.map +1 -0
- package/dist/types/validations/evm-permit.d.ts +4 -0
- package/dist/types/validations/evm-permit.d.ts.map +1 -0
- package/dist/types/validations/evm-permit2.d.ts +4 -0
- package/dist/types/validations/evm-permit2.d.ts.map +1 -0
- package/dist/types/validations/evm-required-actions.d.ts +4 -0
- package/dist/types/validations/evm-required-actions.d.ts.map +1 -0
- package/dist/types/validations/evm-sign712-metamask.d.ts +3 -0
- package/dist/types/validations/evm-sign712-metamask.d.ts.map +1 -0
- package/dist/types/validations/evm-sign712.d.ts +4 -0
- package/dist/types/validations/evm-sign712.d.ts.map +1 -0
- package/dist/types/validations/evm-sign7702.d.ts +3 -0
- package/dist/types/validations/evm-sign7702.d.ts.map +1 -0
- package/dist/types/validations/evm-transaction.d.ts +3 -0
- package/dist/types/validations/evm-transaction.d.ts.map +1 -0
- package/dist/types/validations/hooks-common.d.ts +3 -0
- package/dist/types/validations/hooks-common.d.ts.map +1 -0
- package/dist/types/validations/required-actions.d.ts +4 -0
- package/dist/types/validations/required-actions.d.ts.map +1 -0
- package/dist/types/validations/solana-hook.d.ts +4 -0
- package/dist/types/validations/solana-hook.d.ts.map +1 -0
- package/dist/types/validations/solana-op-budget.d.ts +5 -0
- package/dist/types/validations/solana-op-budget.d.ts.map +1 -0
- package/dist/types/validations/solana-op-wrap.d.ts +4 -0
- package/dist/types/validations/solana-op-wrap.d.ts.map +1 -0
- package/dist/types/validations/solana-required-actions.d.ts +4 -0
- package/dist/types/validations/solana-required-actions.d.ts.map +1 -0
- package/dist/types/validations/solana-sign.d.ts +4 -0
- package/dist/types/validations/solana-sign.d.ts.map +1 -0
- package/dist/types/validations/solana-transaction.d.ts +5 -0
- package/dist/types/validations/solana-transaction.d.ts.map +1 -0
- package/dist/types/validations/trade-grouping.d.ts +22 -0
- package/dist/types/validations/trade-grouping.d.ts.map +1 -0
- package/dist/types/validations/trade-intent-consistency.d.ts +3 -0
- package/dist/types/validations/trade-intent-consistency.d.ts.map +1 -0
- package/dist/types/validations/trades.d.ts +3 -0
- package/dist/types/validations/trades.d.ts.map +1 -0
- package/dist/types/validator.d.ts +3 -0
- package/dist/types/validator.d.ts.map +1 -0
- package/dist/types/whitelists/environment-config.d.ts +4 -0
- package/dist/types/whitelists/environment-config.d.ts.map +1 -0
- package/dist/types/whitelists/evm/caveat-enforcers.d.ts +6 -0
- package/dist/types/whitelists/evm/caveat-enforcers.d.ts.map +1 -0
- package/dist/types/whitelists/evm/delegation-manager.d.ts +3 -0
- package/dist/types/whitelists/evm/delegation-manager.d.ts.map +1 -0
- package/dist/types/whitelists/evm/eip7702-delegation.d.ts +3 -0
- package/dist/types/whitelists/evm/eip7702-delegation.d.ts.map +1 -0
- package/dist/types/whitelists/evm/index.d.ts +6 -0
- package/dist/types/whitelists/evm/index.d.ts.map +1 -0
- package/dist/types/whitelists/evm/permit2.d.ts +3 -0
- package/dist/types/whitelists/evm/permit2.d.ts.map +1 -0
- package/dist/types/whitelists/evm/weth.d.ts +3 -0
- package/dist/types/whitelists/evm/weth.d.ts.map +1 -0
- package/dist/types/whitelists/solana/index.d.ts +3 -0
- package/dist/types/whitelists/solana/index.d.ts.map +1 -0
- package/dist/types/whitelists/solana/intent-signature.d.ts +9 -0
- package/dist/types/whitelists/solana/intent-signature.d.ts.map +1 -0
- package/dist/types/whitelists/solana/programs.d.ts +9 -0
- package/dist/types/whitelists/solana/programs.d.ts.map +1 -0
- package/dist/types/whitelists/subscription-to-chain-id.d.ts +4 -0
- package/dist/types/whitelists/subscription-to-chain-id.d.ts.map +1 -0
- package/dist/types/whitelists/types.d.ts +18 -0
- package/dist/types/whitelists/types.d.ts.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { hexToBytes } from "viem";
|
|
2
|
+
import { ViolationCode, SolanaActionKind, SolanaActionOperation, } from "../types/index.js";
|
|
3
|
+
import { computeSolanaIntentId } from "../helpers/solana-intent-id.js";
|
|
4
|
+
// Validates Sign (Intent) actions within Solana requiredActions
|
|
5
|
+
export function validateSolanaSignActions(actions, basePath, realChainId, quoteMode, intent, envConfig) {
|
|
6
|
+
const signActions = [];
|
|
7
|
+
for (let i = 0; i < actions.length; i++) {
|
|
8
|
+
if (actions[i].type === SolanaActionKind.Sign) {
|
|
9
|
+
signActions.push({ action: actions[i], index: i });
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
// In quote mode, Sign actions may be absent — skip validation
|
|
13
|
+
if (quoteMode)
|
|
14
|
+
return [];
|
|
15
|
+
const violations = [];
|
|
16
|
+
// HIGH: Exactly one Sign action must be present in execution mode
|
|
17
|
+
if (signActions.length === 0) {
|
|
18
|
+
return [{
|
|
19
|
+
code: ViolationCode.SolanaSignIntentMissing,
|
|
20
|
+
message: "Sign (Intent) action is required in execution mode",
|
|
21
|
+
path: `${basePath}.requiredActions`,
|
|
22
|
+
}];
|
|
23
|
+
}
|
|
24
|
+
if (signActions.length > 1) {
|
|
25
|
+
violations.push({
|
|
26
|
+
code: ViolationCode.SolanaSignIntentDuplicate,
|
|
27
|
+
message: `expected exactly 1 Sign action, found ${signActions.length}`,
|
|
28
|
+
path: `${basePath}.requiredActions`,
|
|
29
|
+
expected: 1,
|
|
30
|
+
actual: signActions.length,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
for (const { action, index } of signActions) {
|
|
34
|
+
const actionPath = `${basePath}.requiredActions[${index}]`;
|
|
35
|
+
violations.push(...validateSignActionsList(action, actionPath), ...validateSignIntentData(action, actionPath, realChainId, intent, envConfig));
|
|
36
|
+
}
|
|
37
|
+
return violations;
|
|
38
|
+
}
|
|
39
|
+
// HIGH: actions[] must contain exactly one element — Intent
|
|
40
|
+
function validateSignActionsList(action, actionPath) {
|
|
41
|
+
if (action.actions.length !== 1
|
|
42
|
+
|| action.actions[0] !== SolanaActionOperation.Intent) {
|
|
43
|
+
return [{
|
|
44
|
+
code: ViolationCode.SolanaSignIntentActionsInvalid,
|
|
45
|
+
message: "Sign action must have exactly one operation: [Intent]",
|
|
46
|
+
path: `${actionPath}.actions`,
|
|
47
|
+
expected: [SolanaActionOperation.Intent],
|
|
48
|
+
actual: action.actions,
|
|
49
|
+
}];
|
|
50
|
+
}
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
// CRITICAL: Verify that action.data.data contains the correct intent signature buffer
|
|
54
|
+
function validateSignIntentData(action, actionPath, realChainId, intent, envConfig) {
|
|
55
|
+
const dataHex = action.data.data;
|
|
56
|
+
let dataBytes;
|
|
57
|
+
try {
|
|
58
|
+
const prefixed = dataHex.startsWith("0x") ? dataHex : `0x${dataHex}`;
|
|
59
|
+
dataBytes = hexToBytes(prefixed);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
return [{
|
|
63
|
+
code: ViolationCode.SolanaSignIntentDataInvalid,
|
|
64
|
+
// CRITICAL: action.data.data must be a valid hex string
|
|
65
|
+
message: "Sign action data.data is not a valid hex string",
|
|
66
|
+
path: `${actionPath}.data.data`,
|
|
67
|
+
details: error,
|
|
68
|
+
}];
|
|
69
|
+
}
|
|
70
|
+
return validateSignatureBuffer(dataBytes, actionPath, realChainId, intent, envConfig.solanaSignatureConfig, envConfig.solanaIntentProgram);
|
|
71
|
+
}
|
|
72
|
+
// CRITICAL: Validates the signature buffer structure and intentId
|
|
73
|
+
function validateSignatureBuffer(dataBytes, actionPath, realChainId, intent, config, intentProgram) {
|
|
74
|
+
// Validate buffer format: prefix + chainId(u32LE) + label + intentId(32 bytes)
|
|
75
|
+
if (dataBytes.length !== config.expectedBufferLength) {
|
|
76
|
+
return [{
|
|
77
|
+
code: ViolationCode.SolanaSignIntentDataInvalid,
|
|
78
|
+
// CRITICAL: buffer length must match expected format
|
|
79
|
+
message: "Sign intent buffer has unexpected length"
|
|
80
|
+
+ ` (expected ${config.expectedBufferLength}, got ${dataBytes.length})`,
|
|
81
|
+
path: `${actionPath}.data.data`,
|
|
82
|
+
expected: config.expectedBufferLength,
|
|
83
|
+
actual: dataBytes.length,
|
|
84
|
+
}];
|
|
85
|
+
}
|
|
86
|
+
// Verify prefix bytes
|
|
87
|
+
let offset = 0;
|
|
88
|
+
if (!bytesEqual(dataBytes, offset, config.prefix)) {
|
|
89
|
+
return [{
|
|
90
|
+
code: ViolationCode.SolanaSignIntentDataInvalid,
|
|
91
|
+
// CRITICAL: prefix must match environment
|
|
92
|
+
message: "Sign intent buffer has invalid prefix",
|
|
93
|
+
path: `${actionPath}.data.data`,
|
|
94
|
+
}];
|
|
95
|
+
}
|
|
96
|
+
offset += config.prefix.length;
|
|
97
|
+
// Verify chainId bytes
|
|
98
|
+
if (!bytesEqual(dataBytes, offset, config.chainIdBytes)) {
|
|
99
|
+
return [{
|
|
100
|
+
code: ViolationCode.SolanaSignIntentDataInvalid,
|
|
101
|
+
// CRITICAL: chainId must match Solana real chain ID
|
|
102
|
+
message: "Sign intent buffer has invalid chainId",
|
|
103
|
+
path: `${actionPath}.data.data`,
|
|
104
|
+
}];
|
|
105
|
+
}
|
|
106
|
+
offset += 4;
|
|
107
|
+
// Verify "intents" label bytes
|
|
108
|
+
if (!bytesEqual(dataBytes, offset, config.label)) {
|
|
109
|
+
return [{
|
|
110
|
+
code: ViolationCode.SolanaSignIntentDataInvalid,
|
|
111
|
+
// CRITICAL: label must be "intents"
|
|
112
|
+
message: "Sign intent buffer has invalid label (expected \"intents\")",
|
|
113
|
+
path: `${actionPath}.data.data`,
|
|
114
|
+
}];
|
|
115
|
+
}
|
|
116
|
+
offset += config.label.length;
|
|
117
|
+
// Extract intentId from the buffer (last 32 bytes)
|
|
118
|
+
const bufferIntentId = dataBytes.slice(offset, offset + 32);
|
|
119
|
+
// Compute expected intentId from intent structure
|
|
120
|
+
return validateIntentId(bufferIntentId, actionPath, realChainId, intent, intentProgram);
|
|
121
|
+
}
|
|
122
|
+
// CRITICAL: Compute intentId from response intent and compare with buffer
|
|
123
|
+
function validateIntentId(bufferIntentId, actionPath, realChainId, intent, intentProgram) {
|
|
124
|
+
let computedHex;
|
|
125
|
+
try {
|
|
126
|
+
computedHex = computeSolanaIntentId(intent, realChainId, intentProgram);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
return [{
|
|
130
|
+
code: ViolationCode.SolanaSignIntentIdComputeError,
|
|
131
|
+
// CRITICAL: intentId computation failed
|
|
132
|
+
message: "failed to compute Solana intentId from intent structure",
|
|
133
|
+
path: `${actionPath}.data.data`,
|
|
134
|
+
details: error,
|
|
135
|
+
}];
|
|
136
|
+
}
|
|
137
|
+
// Convert buffer intentId to hex for comparison
|
|
138
|
+
const bufferHex = "0x" + bytesToHex(bufferIntentId);
|
|
139
|
+
if (bufferHex !== computedHex) {
|
|
140
|
+
return [{
|
|
141
|
+
code: ViolationCode.SolanaSignIntentIdMismatch,
|
|
142
|
+
// CRITICAL: intentId in sign buffer must match computed intentId
|
|
143
|
+
message: "Sign intent buffer contains intentId that does not match computed value",
|
|
144
|
+
path: `${actionPath}.data.data`,
|
|
145
|
+
expected: computedHex,
|
|
146
|
+
actual: bufferHex,
|
|
147
|
+
}];
|
|
148
|
+
}
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
// =============================================
|
|
152
|
+
// Helpers
|
|
153
|
+
// =============================================
|
|
154
|
+
function bytesEqual(data, offset, expected) {
|
|
155
|
+
for (let i = 0; i < expected.length; i++) {
|
|
156
|
+
if (data[offset + i] !== expected[i])
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
function bytesToHex(bytes) {
|
|
162
|
+
let hex = "";
|
|
163
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
164
|
+
hex += bytes[i].toString(16).padStart(2, "0");
|
|
165
|
+
}
|
|
166
|
+
return hex;
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=solana-sign.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana-sign.js","sourceRoot":"","sources":["../../../src/validations/solana-sign.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { ViolationCode, SolanaActionKind, SolanaActionOperation, } from "../types/index.js";
|
|
2
|
+
import { addressEquals } from "../helpers/address.js";
|
|
3
|
+
import { decodeSolanaVersionedTransaction } from "../helpers/solana-transaction-decode.js";
|
|
4
|
+
import { resolveInstructions, isClassicApprove, isCustomApprove, isSystemTransfer, isSyncNative, isCreateAtaIdempotent, isComputeBudget, isMemo, } from "../helpers/solana-instruction.js";
|
|
5
|
+
import { COMPUTE_BUDGET_PROGRAM, SPL_NATIVE_MINT, } from "../whitelists/solana/programs.js";
|
|
6
|
+
import { validateSolanaBudgetInstructions } from "./solana-op-budget.js";
|
|
7
|
+
import { validateSolanaWrapInstructions } from "./solana-op-wrap.js";
|
|
8
|
+
const ALLOWED_TX_ACTIONS = new Set([
|
|
9
|
+
SolanaActionOperation.Wrap,
|
|
10
|
+
SolanaActionOperation.Budget,
|
|
11
|
+
]);
|
|
12
|
+
// Validates Transaction actions (AA=false)
|
|
13
|
+
export function validateSolanaTransactionActions(actions, basePath, realChainId, quoteMode, srcChainAuthorityAddress, request, trades, envConfig) {
|
|
14
|
+
const violations = [];
|
|
15
|
+
for (let i = 0; i < actions.length; i++) {
|
|
16
|
+
if (actions[i].type !== SolanaActionKind.Transaction)
|
|
17
|
+
continue;
|
|
18
|
+
const action = actions[i];
|
|
19
|
+
const actionPath = `${basePath}.requiredActions[${i}]`;
|
|
20
|
+
violations.push(...validateActionsList(action, actionPath), ...validateWrapRequiresNativeToken(action, actionPath, trades, realChainId));
|
|
21
|
+
const decoded = decodeTransaction(action, actionPath);
|
|
22
|
+
if (!decoded.ok) {
|
|
23
|
+
violations.push(...decoded.violations);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const accountKeys = getStaticAccountKeys(decoded.transaction);
|
|
27
|
+
const resolved = resolveInstructions(decoded.transaction.message.compiledInstructions, accountKeys);
|
|
28
|
+
violations.push(...validateTransactionFeePayer(decoded.transaction, actionPath, realChainId, quoteMode, srcChainAuthorityAddress), ...validateTransactionComputeBudget(decoded.transaction, actionPath), ...validateAllowedInstructions(decoded.transaction, actionPath, envConfig.solanaTransactionAllowedPrograms, ViolationCode.SolanaTransactionForbiddenInstruction, "Transaction"), ...validateSolanaBudgetInstructions(action, resolved, actionPath, request, trades, realChainId, quoteMode, srcChainAuthorityAddress, envConfig), ...validateSolanaWrapInstructions(action, resolved, actionPath, trades, realChainId, quoteMode, srcChainAuthorityAddress), ...validateNoUnclassifiedInstructions(resolved, actionPath, buildClassifiers(envConfig.solanaIntentProgram, isComputeBudget)));
|
|
29
|
+
}
|
|
30
|
+
return violations;
|
|
31
|
+
}
|
|
32
|
+
// Validates SignTransaction actions (AA=true)
|
|
33
|
+
export function validateSolanaSignTransactionActions(actions, basePath, realChainId, quoteMode, srcChainAuthorityAddress, request, trades, envConfig) {
|
|
34
|
+
const violations = [];
|
|
35
|
+
for (let i = 0; i < actions.length; i++) {
|
|
36
|
+
if (actions[i].type !== SolanaActionKind.SignTransaction)
|
|
37
|
+
continue;
|
|
38
|
+
const action = actions[i];
|
|
39
|
+
const actionPath = `${basePath}.requiredActions[${i}]`;
|
|
40
|
+
violations.push(...validateActionsList(action, actionPath), ...validateWrapRequiresNativeToken(action, actionPath, trades, realChainId));
|
|
41
|
+
const decoded = decodeTransaction(action, actionPath);
|
|
42
|
+
if (!decoded.ok) {
|
|
43
|
+
violations.push(...decoded.violations);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const accountKeys = getStaticAccountKeys(decoded.transaction);
|
|
47
|
+
const resolved = resolveInstructions(decoded.transaction.message.compiledInstructions, accountKeys);
|
|
48
|
+
violations.push(...validateSignTransactionFeePayer(decoded.transaction, actionPath, realChainId, quoteMode, srcChainAuthorityAddress), ...validateAllowedInstructions(decoded.transaction, actionPath, envConfig.solanaSignTransactionAllowedPrograms, ViolationCode.SolanaSignTransactionForbiddenInstruction, "SignTransaction"), ...validateSolanaBudgetInstructions(action, resolved, actionPath, request, trades, realChainId, quoteMode, srcChainAuthorityAddress, envConfig), ...validateSolanaWrapInstructions(action, resolved, actionPath, trades, realChainId, quoteMode, srcChainAuthorityAddress), ...validateNoUnclassifiedInstructions(resolved, actionPath, buildClassifiers(envConfig.solanaIntentProgram, isMemo)));
|
|
49
|
+
}
|
|
50
|
+
return violations;
|
|
51
|
+
}
|
|
52
|
+
// =============================================
|
|
53
|
+
// Common validations for Transaction and SignTransaction
|
|
54
|
+
// =============================================
|
|
55
|
+
// HIGH: actions[] must only contain Wrap, Budget
|
|
56
|
+
function validateActionsList(action, actionPath) {
|
|
57
|
+
const invalid = action.actions.filter(a => !ALLOWED_TX_ACTIONS.has(a));
|
|
58
|
+
if (invalid.length === 0)
|
|
59
|
+
return [];
|
|
60
|
+
return [{
|
|
61
|
+
code: ViolationCode.SolanaTransactionActionsInvalid,
|
|
62
|
+
message: `actions[] contains disallowed operations: ${invalid.join(", ")}`,
|
|
63
|
+
path: `${actionPath}.actions`,
|
|
64
|
+
expected: [...ALLOWED_TX_ACTIONS],
|
|
65
|
+
actual: action.actions,
|
|
66
|
+
}];
|
|
67
|
+
}
|
|
68
|
+
// HIGH: If actions[] contains Wrap, at least one trade must use native SOL
|
|
69
|
+
function validateWrapRequiresNativeToken(action, actionPath, trades, realChainId) {
|
|
70
|
+
if (!action.actions.includes(SolanaActionOperation.Wrap))
|
|
71
|
+
return [];
|
|
72
|
+
const hasNativeTrade = trades.some(trade => addressEquals(realChainId, trade.srcChainTokenIn, SPL_NATIVE_MINT));
|
|
73
|
+
if (hasNativeTrade)
|
|
74
|
+
return [];
|
|
75
|
+
return [{
|
|
76
|
+
code: ViolationCode.SolanaWrapNotForNativeToken,
|
|
77
|
+
message: "Wrap operation present but no trade uses native SOL as srcChainTokenIn",
|
|
78
|
+
path: `${actionPath}.actions`,
|
|
79
|
+
actual: trades.map(t => t.srcChainTokenIn),
|
|
80
|
+
}];
|
|
81
|
+
}
|
|
82
|
+
// CRITICAL: Decode and validate VersionedTransaction(MessageV0)
|
|
83
|
+
function decodeTransaction(action, actionPath) {
|
|
84
|
+
return decodeSolanaVersionedTransaction(action.data.data, `${actionPath}.data.data`, ViolationCode.SolanaTransactionDecodeError, ViolationCode.SolanaTransactionVersionInvalid);
|
|
85
|
+
}
|
|
86
|
+
// =============================================
|
|
87
|
+
// Transaction-specific (AA=false)
|
|
88
|
+
// =============================================
|
|
89
|
+
// HIGH (execution mode): feePayer must equal srcChainAuthorityAddress
|
|
90
|
+
function validateTransactionFeePayer(transaction, actionPath, realChainId, quoteMode, srcChainAuthorityAddress) {
|
|
91
|
+
// NO NEED (quote): feePayer is a placeholder
|
|
92
|
+
if (quoteMode || !srcChainAuthorityAddress)
|
|
93
|
+
return [];
|
|
94
|
+
const feePayer = getFeePayer(transaction);
|
|
95
|
+
if (!feePayer)
|
|
96
|
+
return [];
|
|
97
|
+
if (!addressEquals(realChainId, feePayer, srcChainAuthorityAddress)) {
|
|
98
|
+
return [{
|
|
99
|
+
code: ViolationCode.SolanaTransactionFeePayerMismatch,
|
|
100
|
+
message: "Transaction feePayer must equal request.trades[].srcChainAuthorityAddress",
|
|
101
|
+
path: `${actionPath}.data.data`,
|
|
102
|
+
expected: srcChainAuthorityAddress,
|
|
103
|
+
actual: feePayer,
|
|
104
|
+
}];
|
|
105
|
+
}
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
// HIGH: compiledInstructions[] must contain at least 2 ComputeBudget instructions at the beginning
|
|
109
|
+
function validateTransactionComputeBudget(transaction, actionPath) {
|
|
110
|
+
const instructions = transaction.message.compiledInstructions;
|
|
111
|
+
const accountKeys = getStaticAccountKeys(transaction);
|
|
112
|
+
let computeBudgetCount = 0;
|
|
113
|
+
for (let i = 0; i < instructions.length; i++) {
|
|
114
|
+
const programId = accountKeys[instructions[i].programIdIndex];
|
|
115
|
+
if (!programId)
|
|
116
|
+
break;
|
|
117
|
+
if (programId === COMPUTE_BUDGET_PROGRAM) {
|
|
118
|
+
computeBudgetCount++;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
break; // ComputeBudget instructions must be at the beginning
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (computeBudgetCount < 2) {
|
|
125
|
+
return [{
|
|
126
|
+
code: ViolationCode.SolanaTransactionComputeBudgetMissing,
|
|
127
|
+
message: "Transaction must have at least 2 ComputeBudget instructions at the beginning",
|
|
128
|
+
path: `${actionPath}.data.data`,
|
|
129
|
+
expected: 2,
|
|
130
|
+
actual: computeBudgetCount,
|
|
131
|
+
}];
|
|
132
|
+
}
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
135
|
+
// CRITICAL: no instructions from disallowed programs
|
|
136
|
+
function validateAllowedInstructions(transaction, actionPath, allowedPrograms, violationCode, label) {
|
|
137
|
+
const accountKeys = getStaticAccountKeys(transaction);
|
|
138
|
+
const violations = [];
|
|
139
|
+
for (const ix of transaction.message.compiledInstructions) {
|
|
140
|
+
const programId = resolveProgramId(accountKeys, ix.programIdIndex);
|
|
141
|
+
if (programId === undefined) {
|
|
142
|
+
// CRITICAL: program ID resolved via Address Lookup Table — forbidden
|
|
143
|
+
violations.push({
|
|
144
|
+
code: violationCode,
|
|
145
|
+
message: "instruction references program via Address Lookup Table"
|
|
146
|
+
+ ` (index ${ix.programIdIndex}), forbidden in ${label}`,
|
|
147
|
+
path: `${actionPath}.data.data`,
|
|
148
|
+
actual: ix.programIdIndex,
|
|
149
|
+
});
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (!allowedPrograms.has(programId)) {
|
|
153
|
+
violations.push({
|
|
154
|
+
code: violationCode,
|
|
155
|
+
// CRITICAL: forbidden instruction program
|
|
156
|
+
message: `${label} contains instruction from disallowed program: ${programId}`,
|
|
157
|
+
path: `${actionPath}.data.data`,
|
|
158
|
+
actual: programId,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return violations;
|
|
163
|
+
}
|
|
164
|
+
// =============================================
|
|
165
|
+
// SignTransaction-specific (AA=true)
|
|
166
|
+
// =============================================
|
|
167
|
+
// CRITICAL (execution mode): feePayer must NOT be the user
|
|
168
|
+
function validateSignTransactionFeePayer(transaction, actionPath, realChainId, quoteMode, srcChainAuthorityAddress) {
|
|
169
|
+
// NO NEED (quote): feePayer is a placeholder
|
|
170
|
+
if (quoteMode || !srcChainAuthorityAddress)
|
|
171
|
+
return [];
|
|
172
|
+
const feePayer = getFeePayer(transaction);
|
|
173
|
+
if (!feePayer)
|
|
174
|
+
return [];
|
|
175
|
+
if (addressEquals(realChainId, feePayer, srcChainAuthorityAddress)) {
|
|
176
|
+
return [{
|
|
177
|
+
code: ViolationCode.SolanaSignTransactionFeePayerIsUser,
|
|
178
|
+
// CRITICAL: feePayer must NOT be the user
|
|
179
|
+
message: "SignTransaction feePayer must NOT be the user"
|
|
180
|
+
+ " (request.trades[].srcChainAuthorityAddress)",
|
|
181
|
+
path: `${actionPath}.data.data`,
|
|
182
|
+
actual: feePayer,
|
|
183
|
+
}];
|
|
184
|
+
}
|
|
185
|
+
return [];
|
|
186
|
+
}
|
|
187
|
+
// Builds classifiers for validateNoUnclassifiedInstructions.
|
|
188
|
+
// `leadClassifier` is isComputeBudget for Transaction, isMemo for SignTransaction.
|
|
189
|
+
function buildClassifiers(intentProgram, leadClassifier) {
|
|
190
|
+
return [
|
|
191
|
+
leadClassifier,
|
|
192
|
+
isClassicApprove,
|
|
193
|
+
(ix) => isCustomApprove(ix, intentProgram),
|
|
194
|
+
isSystemTransfer,
|
|
195
|
+
isSyncNative,
|
|
196
|
+
isCreateAtaIdempotent,
|
|
197
|
+
];
|
|
198
|
+
}
|
|
199
|
+
// CRITICAL: every instruction from an allowed program must be recognized by at least one classifier.
|
|
200
|
+
function validateNoUnclassifiedInstructions(resolved, actionPath, classifiers) {
|
|
201
|
+
const violations = [];
|
|
202
|
+
for (let i = 0; i < resolved.length; i++) {
|
|
203
|
+
const ix = resolved[i];
|
|
204
|
+
const classified = classifiers.some(classify => classify(ix));
|
|
205
|
+
if (!classified) {
|
|
206
|
+
violations.push({
|
|
207
|
+
code: ViolationCode.SolanaUnclassifiedInstruction,
|
|
208
|
+
message: `instruction [${i}] from program ${ix.programId}`
|
|
209
|
+
+ " was not recognized by any validator",
|
|
210
|
+
path: `${actionPath}.data.data`,
|
|
211
|
+
actual: ix.programId,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return violations;
|
|
216
|
+
}
|
|
217
|
+
// =============================================
|
|
218
|
+
// Helpers
|
|
219
|
+
// =============================================
|
|
220
|
+
function getFeePayer(transaction) {
|
|
221
|
+
const keys = transaction.message.staticAccountKeys;
|
|
222
|
+
if (keys.length === 0)
|
|
223
|
+
return undefined;
|
|
224
|
+
return keys[0].toBase58();
|
|
225
|
+
}
|
|
226
|
+
function getStaticAccountKeys(transaction) {
|
|
227
|
+
return transaction.message.staticAccountKeys.map((key) => key.toBase58());
|
|
228
|
+
}
|
|
229
|
+
// Returns the program ID string if it is in staticAccountKeys,
|
|
230
|
+
// or undefined if the index points beyond (Address Lookup Table).
|
|
231
|
+
function resolveProgramId(staticAccountKeys, programIdIndex) {
|
|
232
|
+
return staticAccountKeys[programIdIndex];
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=solana-transaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana-transaction.js","sourceRoot":"","sources":["../../../src/validations/solana-transaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { ViolationCode, } from "../types/index.js";
|
|
2
|
+
import { resolveChainId } from "../whitelists/subscription-to-chain-id.js";
|
|
3
|
+
import { addressEquals } from "../helpers/address.js";
|
|
4
|
+
// Groups request trades to match them later with response intents.
|
|
5
|
+
//
|
|
6
|
+
// Quote mode: groups by srcChainId only (addresses are placeholders).
|
|
7
|
+
//
|
|
8
|
+
// Execution mode: groups by (srcChainId, srcChainAuthorityAddress).
|
|
9
|
+
//
|
|
10
|
+
// NOTE: the API may further split a group into multiple intents based on
|
|
11
|
+
// fields like intent.executionMetadata, intent.dlnMetadata,
|
|
12
|
+
// intent.externalCallHash, etc. that are not present in the request, so one
|
|
13
|
+
// group can correspond to one or more response intents.
|
|
14
|
+
export function groupTrades(trades, quoteMode) {
|
|
15
|
+
const map = new Map();
|
|
16
|
+
const violations = [];
|
|
17
|
+
// Track already-reported unknown subscriptionIds to avoid duplicate violations
|
|
18
|
+
const reportedUnknown = new Set();
|
|
19
|
+
for (let i = 0; i < trades.length; i++) {
|
|
20
|
+
const trade = trades[i];
|
|
21
|
+
const realChainId = resolveChainId(trade.srcChainId);
|
|
22
|
+
if (realChainId === undefined) {
|
|
23
|
+
if (!reportedUnknown.has(trade.srcChainId)) {
|
|
24
|
+
reportedUnknown.add(trade.srcChainId);
|
|
25
|
+
// CRITICAL: unknown subscriptionId — cannot validate this trade
|
|
26
|
+
violations.push({
|
|
27
|
+
code: ViolationCode.UnknownSubscriptionId,
|
|
28
|
+
message: `srcChainId=${trade.srcChainId} is not a known subscriptionId`,
|
|
29
|
+
path: `request.trades[${i}].srcChainId`,
|
|
30
|
+
actual: trade.srcChainId,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const key = quoteMode
|
|
36
|
+
? String(trade.srcChainId)
|
|
37
|
+
: `${trade.srcChainId}:${trade.srcChainAuthorityAddress ?? ""}`;
|
|
38
|
+
let group = map.get(key);
|
|
39
|
+
if (!group) {
|
|
40
|
+
group = {
|
|
41
|
+
srcChainId: trade.srcChainId,
|
|
42
|
+
srcChainAuthorityAddress: quoteMode ? undefined : trade.srcChainAuthorityAddress,
|
|
43
|
+
realChainId,
|
|
44
|
+
tradeIndices: [],
|
|
45
|
+
trades: [],
|
|
46
|
+
};
|
|
47
|
+
map.set(key, group);
|
|
48
|
+
}
|
|
49
|
+
group.tradeIndices.push(i);
|
|
50
|
+
group.trades.push(trade);
|
|
51
|
+
}
|
|
52
|
+
return { groups: Array.from(map.values()), violations };
|
|
53
|
+
}
|
|
54
|
+
// Matches each response intent to its trade group.
|
|
55
|
+
//
|
|
56
|
+
// Quote mode: matches by intentChainId == group.srcChainId.
|
|
57
|
+
//
|
|
58
|
+
// Execution mode: additionally requires intentOwner == group.srcChainAuthorityAddress
|
|
59
|
+
// (case-insensitive).
|
|
60
|
+
//
|
|
61
|
+
// Multiple intents may match the same group. An intent that matches no group
|
|
62
|
+
// produces a violation.
|
|
63
|
+
export function matchIntentsToGroups(intents, groups, quoteMode) {
|
|
64
|
+
const contexts = [];
|
|
65
|
+
const violations = [];
|
|
66
|
+
for (let i = 0; i < intents.length; i++) {
|
|
67
|
+
const intentPayload = intents[i];
|
|
68
|
+
const intent = intentPayload.intent;
|
|
69
|
+
const matched = groups.find(g => {
|
|
70
|
+
if (g.srcChainId !== intent.intentChainId)
|
|
71
|
+
return false;
|
|
72
|
+
if (!quoteMode && g.srcChainAuthorityAddress !== undefined) {
|
|
73
|
+
return addressEquals(g.realChainId, g.srcChainAuthorityAddress, intent.intentOwner);
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
});
|
|
77
|
+
if (matched) {
|
|
78
|
+
contexts.push({
|
|
79
|
+
intentIndex: i,
|
|
80
|
+
intentPayload,
|
|
81
|
+
tradeGroup: matched,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
violations.push({
|
|
86
|
+
code: ViolationCode.IntentNotMatchedToTradeGroup,
|
|
87
|
+
message: `intent[${i}] (intentId=${intent.intentId}) does not match any trade group`,
|
|
88
|
+
path: `response.intents[${i}]`,
|
|
89
|
+
expected: undefined,
|
|
90
|
+
actual: intent,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
violations.push(...validateGroupCoverage(groups, contexts));
|
|
95
|
+
violations.push(...validateIntentDifferentiation(contexts));
|
|
96
|
+
return { contexts, violations };
|
|
97
|
+
}
|
|
98
|
+
// CRITICAL: every trade group must have at least one matching intent.
|
|
99
|
+
function validateGroupCoverage(groups, contexts) {
|
|
100
|
+
const coveredGroups = new Set(contexts.map(ctx => ctx.tradeGroup));
|
|
101
|
+
const violations = [];
|
|
102
|
+
for (const group of groups) {
|
|
103
|
+
if (!coveredGroups.has(group)) {
|
|
104
|
+
const tradeList = group.tradeIndices.join(", ");
|
|
105
|
+
violations.push({
|
|
106
|
+
code: ViolationCode.TradeGroupHasNoIntent,
|
|
107
|
+
message: `trade group (srcChainId=${group.srcChainId},`
|
|
108
|
+
+ ` authority=${group.srcChainAuthorityAddress ?? "quote"})`
|
|
109
|
+
+ ` has no matching intent`
|
|
110
|
+
+ ` (request trades: [${tradeList}])`,
|
|
111
|
+
path: "response.intents",
|
|
112
|
+
expected: group,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return violations;
|
|
117
|
+
}
|
|
118
|
+
// CRITICAL: intents matched to the same trade group must differ
|
|
119
|
+
// in at least one of: externalCallHash, dlnMetadata, executionMetadata.
|
|
120
|
+
// Duplicate intents within a group indicate an API bug or MITM attack.
|
|
121
|
+
function validateIntentDifferentiation(contexts) {
|
|
122
|
+
const byGroup = new Map();
|
|
123
|
+
for (const ctx of contexts) {
|
|
124
|
+
const list = byGroup.get(ctx.tradeGroup) ?? [];
|
|
125
|
+
list.push(ctx);
|
|
126
|
+
byGroup.set(ctx.tradeGroup, list);
|
|
127
|
+
}
|
|
128
|
+
const violations = [];
|
|
129
|
+
for (const [, groupContexts] of byGroup) {
|
|
130
|
+
if (groupContexts.length <= 1)
|
|
131
|
+
continue;
|
|
132
|
+
const seen = new Map();
|
|
133
|
+
for (const ctx of groupContexts) {
|
|
134
|
+
const key = intentDifferentiationKey(ctx.intentPayload.intent);
|
|
135
|
+
const firstIndex = seen.get(key);
|
|
136
|
+
if (firstIndex !== undefined) {
|
|
137
|
+
violations.push({
|
|
138
|
+
code: ViolationCode.DuplicateIntentsInTradeGroup,
|
|
139
|
+
message: `intents[${firstIndex}] and intents[${ctx.intentIndex}]`
|
|
140
|
+
+ ` are in the same trade group but do not differ`
|
|
141
|
+
+ ` in externalCallHash, dlnMetadata, or`
|
|
142
|
+
+ ` executionMetadata`,
|
|
143
|
+
path: `response.intents[${ctx.intentIndex}]`,
|
|
144
|
+
actual: ctx.intentPayload.intent,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
seen.set(key, ctx.intentIndex);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return violations;
|
|
153
|
+
}
|
|
154
|
+
function intentDifferentiationKey(intent) {
|
|
155
|
+
return [
|
|
156
|
+
intent.externalCallHash ?? "",
|
|
157
|
+
intent.dlnMetadata ?? "",
|
|
158
|
+
intent.executionMetadata ?? "",
|
|
159
|
+
].join("|");
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=trade-grouping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trade-grouping.js","sourceRoot":"","sources":["../../../src/validations/trade-grouping.ts"],"names":[],"mappings":"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"}
|