@debridge-finance/borderless-validation-sdk 0.0.0-dev-dee2389 → 0.0.0-dev-25d2153
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +164 -0
- package/dist/cjs/helpers/address.js +31 -18
- package/dist/cjs/helpers/address.js.map +1 -1
- package/dist/cjs/helpers/evm-action.js +3 -3
- package/dist/cjs/helpers/evm-action.js.map +1 -1
- package/dist/cjs/helpers/evm-gas-compensation-tx.js +102 -0
- package/dist/cjs/helpers/evm-gas-compensation-tx.js.map +1 -0
- package/dist/cjs/helpers/evm-intent-id.js +1 -1
- package/dist/cjs/helpers/evm-intent-id.js.map +1 -1
- package/dist/cjs/helpers/gas-compensation.js +36 -0
- package/dist/cjs/helpers/gas-compensation.js.map +1 -0
- package/dist/cjs/helpers/placeholder.js +174 -0
- package/dist/cjs/helpers/placeholder.js.map +1 -0
- package/dist/cjs/helpers/sets.js +13 -0
- package/dist/cjs/helpers/sets.js.map +1 -0
- package/dist/cjs/types/enums.js +26 -2
- package/dist/cjs/types/enums.js.map +1 -1
- package/dist/cjs/types/request.js +25 -2
- package/dist/cjs/types/request.js.map +1 -1
- package/dist/cjs/types/response.js +119 -3
- package/dist/cjs/types/response.js.map +1 -1
- package/dist/cjs/types/validation.js +72 -8
- package/dist/cjs/types/validation.js.map +1 -1
- package/dist/cjs/validations/compensation-hook.js +203 -0
- package/dist/cjs/validations/compensation-hook.js.map +1 -0
- package/dist/cjs/validations/evm-caveats.js +4 -14
- package/dist/cjs/validations/evm-caveats.js.map +1 -1
- package/dist/cjs/validations/evm-op-budget.js +3 -3
- package/dist/cjs/validations/evm-op-budget.js.map +1 -1
- package/dist/cjs/validations/evm-op-hook.js +410 -3
- package/dist/cjs/validations/evm-op-hook.js.map +1 -1
- package/dist/cjs/validations/evm-op-wrap.js +3 -3
- package/dist/cjs/validations/evm-op-wrap.js.map +1 -1
- package/dist/cjs/validations/evm-required-actions.js +4 -6
- package/dist/cjs/validations/evm-required-actions.js.map +1 -1
- package/dist/cjs/validations/evm-sign712-metamask.js +17 -94
- package/dist/cjs/validations/evm-sign712-metamask.js.map +1 -1
- package/dist/cjs/validations/evm-sign712-shared.js +116 -0
- package/dist/cjs/validations/evm-sign712-shared.js.map +1 -0
- package/dist/cjs/validations/evm-sign7702.js +34 -22
- package/dist/cjs/validations/evm-sign7702.js.map +1 -1
- package/dist/cjs/validations/hooks-common.js +247 -35
- package/dist/cjs/validations/hooks-common.js.map +1 -1
- package/dist/cjs/validations/intent-destinations.js +197 -0
- package/dist/cjs/validations/intent-destinations.js.map +1 -0
- package/dist/cjs/validations/intent-tokens.js +341 -0
- package/dist/cjs/validations/intent-tokens.js.map +1 -0
- package/dist/cjs/validations/intent.js +288 -0
- package/dist/cjs/validations/intent.js.map +1 -0
- package/dist/cjs/validations/required-actions.js +2 -5
- package/dist/cjs/validations/required-actions.js.map +1 -1
- package/dist/cjs/validations/solana-hook.js +32 -18
- package/dist/cjs/validations/solana-hook.js.map +1 -1
- package/dist/cjs/validations/trades.js +5 -0
- package/dist/cjs/validations/trades.js.map +1 -1
- package/dist/cjs/validator.js +8 -1
- package/dist/cjs/validator.js.map +1 -1
- package/dist/cjs/whitelists/environment-config.js +47 -15
- package/dist/cjs/whitelists/environment-config.js.map +1 -1
- package/dist/cjs/whitelists/evm/caveat-enforcers.js +21 -5
- package/dist/cjs/whitelists/evm/caveat-enforcers.js.map +1 -1
- package/dist/cjs/whitelists/evm/delegation-manager.js +7 -2
- package/dist/cjs/whitelists/evm/delegation-manager.js.map +1 -1
- package/dist/cjs/whitelists/evm/eip7702-delegation.js +7 -2
- package/dist/cjs/whitelists/evm/eip7702-delegation.js.map +1 -1
- package/dist/cjs/whitelists/evm/index.js +14 -1
- package/dist/cjs/whitelists/evm/index.js.map +1 -1
- package/dist/cjs/whitelists/evm/metamask-delegation-chains.js +16 -0
- package/dist/cjs/whitelists/evm/metamask-delegation-chains.js.map +1 -0
- package/dist/cjs/whitelists/evm/permit2.js +16 -12
- package/dist/cjs/whitelists/evm/permit2.js.map +1 -1
- package/dist/cjs/whitelists/evm/weth.js +16 -5
- package/dist/cjs/whitelists/evm/weth.js.map +1 -1
- package/dist/cjs/whitelists/solana/intent-signature.js +0 -1
- package/dist/cjs/whitelists/solana/intent-signature.js.map +1 -1
- package/dist/cjs/whitelists/subscription-to-chain-id.js +10 -0
- package/dist/cjs/whitelists/subscription-to-chain-id.js.map +1 -1
- package/dist/cjs/whitelists/types.js +13 -3
- package/dist/cjs/whitelists/types.js.map +1 -1
- package/dist/esm/helpers/address.js +28 -17
- package/dist/esm/helpers/address.js.map +1 -1
- package/dist/esm/helpers/evm-action.js +3 -3
- package/dist/esm/helpers/evm-action.js.map +1 -1
- package/dist/esm/helpers/evm-gas-compensation-tx.js +99 -0
- package/dist/esm/helpers/evm-gas-compensation-tx.js.map +1 -0
- package/dist/esm/helpers/evm-intent-id.js +1 -1
- package/dist/esm/helpers/evm-intent-id.js.map +1 -1
- package/dist/esm/helpers/gas-compensation.js +33 -0
- package/dist/esm/helpers/gas-compensation.js.map +1 -0
- package/dist/esm/helpers/placeholder.js +168 -0
- package/dist/esm/helpers/placeholder.js.map +1 -0
- package/dist/esm/helpers/sets.js +10 -0
- package/dist/esm/helpers/sets.js.map +1 -0
- package/dist/esm/types/enums.js +25 -1
- package/dist/esm/types/enums.js.map +1 -1
- package/dist/esm/types/request.js +26 -3
- package/dist/esm/types/request.js.map +1 -1
- package/dist/esm/types/response.js +118 -2
- package/dist/esm/types/response.js.map +1 -1
- package/dist/esm/types/validation.js +72 -8
- package/dist/esm/types/validation.js.map +1 -1
- package/dist/esm/validations/compensation-hook.js +200 -0
- package/dist/esm/validations/compensation-hook.js.map +1 -0
- package/dist/esm/validations/evm-caveats.js +4 -14
- package/dist/esm/validations/evm-caveats.js.map +1 -1
- package/dist/esm/validations/evm-op-budget.js +3 -3
- package/dist/esm/validations/evm-op-budget.js.map +1 -1
- package/dist/esm/validations/evm-op-hook.js +409 -2
- package/dist/esm/validations/evm-op-hook.js.map +1 -1
- package/dist/esm/validations/evm-op-wrap.js +3 -3
- package/dist/esm/validations/evm-op-wrap.js.map +1 -1
- package/dist/esm/validations/evm-required-actions.js +4 -6
- package/dist/esm/validations/evm-required-actions.js.map +1 -1
- package/dist/esm/validations/evm-sign712-metamask.js +17 -94
- package/dist/esm/validations/evm-sign712-metamask.js.map +1 -1
- package/dist/esm/validations/evm-sign712-shared.js +110 -0
- package/dist/esm/validations/evm-sign712-shared.js.map +1 -0
- package/dist/esm/validations/evm-sign7702.js +33 -22
- package/dist/esm/validations/evm-sign7702.js.map +1 -1
- package/dist/esm/validations/hooks-common.js +246 -36
- package/dist/esm/validations/hooks-common.js.map +1 -1
- package/dist/esm/validations/intent-destinations.js +194 -0
- package/dist/esm/validations/intent-destinations.js.map +1 -0
- package/dist/esm/validations/intent-tokens.js +338 -0
- package/dist/esm/validations/intent-tokens.js.map +1 -0
- package/dist/esm/validations/intent.js +285 -0
- package/dist/esm/validations/intent.js.map +1 -0
- package/dist/esm/validations/required-actions.js +2 -5
- package/dist/esm/validations/required-actions.js.map +1 -1
- package/dist/esm/validations/solana-hook.js +34 -20
- package/dist/esm/validations/solana-hook.js.map +1 -1
- package/dist/esm/validations/trades.js +5 -0
- package/dist/esm/validations/trades.js.map +1 -1
- package/dist/esm/validator.js +8 -1
- package/dist/esm/validator.js.map +1 -1
- package/dist/esm/whitelists/environment-config.js +47 -15
- package/dist/esm/whitelists/environment-config.js.map +1 -1
- package/dist/esm/whitelists/evm/caveat-enforcers.js +20 -4
- package/dist/esm/whitelists/evm/caveat-enforcers.js.map +1 -1
- package/dist/esm/whitelists/evm/delegation-manager.js +6 -1
- package/dist/esm/whitelists/evm/delegation-manager.js.map +1 -1
- package/dist/esm/whitelists/evm/eip7702-delegation.js +6 -1
- package/dist/esm/whitelists/evm/eip7702-delegation.js.map +1 -1
- package/dist/esm/whitelists/evm/index.js +4 -4
- package/dist/esm/whitelists/evm/index.js.map +1 -1
- package/dist/esm/whitelists/evm/metamask-delegation-chains.js +13 -0
- package/dist/esm/whitelists/evm/metamask-delegation-chains.js.map +1 -0
- package/dist/esm/whitelists/evm/permit2.js +9 -5
- package/dist/esm/whitelists/evm/permit2.js.map +1 -1
- package/dist/esm/whitelists/evm/weth.js +16 -5
- package/dist/esm/whitelists/evm/weth.js.map +1 -1
- package/dist/esm/whitelists/solana/intent-signature.js +0 -1
- package/dist/esm/whitelists/solana/intent-signature.js.map +1 -1
- package/dist/esm/whitelists/subscription-to-chain-id.js +9 -0
- package/dist/esm/whitelists/subscription-to-chain-id.js.map +1 -1
- package/dist/esm/whitelists/types.js +14 -5
- package/dist/esm/whitelists/types.js.map +1 -1
- package/dist/types/helpers/address.d.ts +5 -7
- package/dist/types/helpers/address.d.ts.map +1 -1
- package/dist/types/helpers/evm-gas-compensation-tx.d.ts +13 -0
- package/dist/types/helpers/evm-gas-compensation-tx.d.ts.map +1 -0
- package/dist/types/helpers/gas-compensation.d.ts +10 -0
- package/dist/types/helpers/gas-compensation.d.ts.map +1 -0
- package/dist/types/helpers/placeholder.d.ts +41 -0
- package/dist/types/helpers/placeholder.d.ts.map +1 -0
- package/dist/types/helpers/sets.d.ts +2 -0
- package/dist/types/helpers/sets.d.ts.map +1 -0
- package/dist/types/types/enums.d.ts +19 -1
- package/dist/types/types/enums.d.ts.map +1 -1
- package/dist/types/types/request.d.ts +19 -9
- package/dist/types/types/request.d.ts.map +1 -1
- package/dist/types/types/response.d.ts +365 -9
- package/dist/types/types/response.d.ts.map +1 -1
- package/dist/types/types/validation.d.ts +64 -8
- package/dist/types/types/validation.d.ts.map +1 -1
- package/dist/types/validations/compensation-hook.d.ts +3 -0
- package/dist/types/validations/compensation-hook.d.ts.map +1 -0
- package/dist/types/validations/evm-caveats.d.ts.map +1 -1
- package/dist/types/validations/evm-op-hook.d.ts +4 -2
- package/dist/types/validations/evm-op-hook.d.ts.map +1 -1
- package/dist/types/validations/evm-required-actions.d.ts.map +1 -1
- package/dist/types/validations/evm-sign712-metamask.d.ts.map +1 -1
- package/dist/types/validations/evm-sign712-shared.d.ts +7 -0
- package/dist/types/validations/evm-sign712-shared.d.ts.map +1 -0
- package/dist/types/validations/evm-sign7702.d.ts +2 -1
- package/dist/types/validations/evm-sign7702.d.ts.map +1 -1
- package/dist/types/validations/hooks-common.d.ts +1 -0
- package/dist/types/validations/hooks-common.d.ts.map +1 -1
- package/dist/types/validations/intent-destinations.d.ts +4 -0
- package/dist/types/validations/intent-destinations.d.ts.map +1 -0
- package/dist/types/validations/intent-tokens.d.ts +4 -0
- package/dist/types/validations/intent-tokens.d.ts.map +1 -0
- package/dist/types/validations/intent.d.ts +5 -0
- package/dist/types/validations/intent.d.ts.map +1 -0
- package/dist/types/validations/required-actions.d.ts +2 -1
- package/dist/types/validations/required-actions.d.ts.map +1 -1
- package/dist/types/validations/solana-hook.d.ts +4 -2
- package/dist/types/validations/solana-hook.d.ts.map +1 -1
- package/dist/types/validator.d.ts.map +1 -1
- package/dist/types/whitelists/environment-config.d.ts.map +1 -1
- package/dist/types/whitelists/evm/caveat-enforcers.d.ts +8 -0
- package/dist/types/whitelists/evm/caveat-enforcers.d.ts.map +1 -1
- package/dist/types/whitelists/evm/delegation-manager.d.ts +2 -0
- package/dist/types/whitelists/evm/delegation-manager.d.ts.map +1 -1
- package/dist/types/whitelists/evm/eip7702-delegation.d.ts +2 -0
- package/dist/types/whitelists/evm/eip7702-delegation.d.ts.map +1 -1
- package/dist/types/whitelists/evm/index.d.ts +4 -4
- package/dist/types/whitelists/evm/index.d.ts.map +1 -1
- package/dist/types/whitelists/evm/metamask-delegation-chains.d.ts +3 -0
- package/dist/types/whitelists/evm/metamask-delegation-chains.d.ts.map +1 -0
- package/dist/types/whitelists/evm/permit2.d.ts +1 -0
- package/dist/types/whitelists/evm/permit2.d.ts.map +1 -1
- package/dist/types/whitelists/evm/weth.d.ts.map +1 -1
- package/dist/types/whitelists/solana/intent-signature.d.ts.map +1 -1
- package/dist/types/whitelists/subscription-to-chain-id.d.ts +1 -0
- package/dist/types/whitelists/subscription-to-chain-id.d.ts.map +1 -1
- package/dist/types/whitelists/types.d.ts +1 -0
- package/dist/types/whitelists/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/cjs/validations/evm-op-gas-compensation.js +0 -152
- package/dist/cjs/validations/evm-op-gas-compensation.js.map +0 -1
- package/dist/esm/validations/evm-op-gas-compensation.js +0 -149
- package/dist/esm/validations/evm-op-gas-compensation.js.map +0 -1
- package/dist/types/validations/evm-op-gas-compensation.d.ts +0 -3
- package/dist/types/validations/evm-op-gas-compensation.d.ts.map +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# @debridge-finance/borderless-validation-sdk
|
|
2
|
+
|
|
3
|
+
Validation SDK for deBridge **borderless intents** API (`POST /v1.0/bundle`) responses.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
When a user submits a bundle request to the deBridge API, the response contains transactions and signable payloads (EIP-712 messages, permits, Solana transactions, etc.) that the user is expected to sign.
|
|
8
|
+
|
|
9
|
+
**Every field the user signs is a potential attack vector.** If the API is compromised (MITM, server bug, malicious rewrite), the user could unknowingly sign a transaction that drains their funds.
|
|
10
|
+
|
|
11
|
+
This SDK runs on the client and independently verifies that every signable field in the response matches the original request — before the user signs anything.
|
|
12
|
+
|
|
13
|
+
### Threats mitigated
|
|
14
|
+
|
|
15
|
+
- **MITM attacks** against the API endpoint.
|
|
16
|
+
- **Bugs on the API side** that produce subtly wrong responses.
|
|
17
|
+
- **Reduced API trust** — the client no longer has to take API responses on faith.
|
|
18
|
+
- **Regression safety net** when testing new API versions.
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @debridge-finance/borderless-validation-sdk
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Peer dependencies:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install viem zod bs58 @solana/web3.js
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Basic usage
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { createValidator, Environment } from "@debridge-finance/borderless-validation-sdk";
|
|
36
|
+
|
|
37
|
+
const validator = createValidator({ environment: Environment.Prod });
|
|
38
|
+
|
|
39
|
+
const url = "https://cross-chain-api.debridge.finance/v1.0/bundle";
|
|
40
|
+
|
|
41
|
+
const response = await fetch(url, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers: { "Content-Type": "application/json" },
|
|
44
|
+
body: JSON.stringify(request),
|
|
45
|
+
}).then(res => res.json());
|
|
46
|
+
|
|
47
|
+
const result = validator.validate(url, request, response);
|
|
48
|
+
|
|
49
|
+
if (!result.ok) {
|
|
50
|
+
console.error("Validation failed:", result.violations);
|
|
51
|
+
// Do NOT let the user sign anything.
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Safe to proceed with signing.
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### API
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
createValidator(config: { environment: Environment }): Validator
|
|
62
|
+
|
|
63
|
+
type Validator = {
|
|
64
|
+
validate(url: string, request: object, response: object): ValidationResult;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
type ValidationResult = {
|
|
68
|
+
ok: boolean; // true if no violations
|
|
69
|
+
violations: Violation[]; // all issues found
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type Violation = {
|
|
73
|
+
code: ViolationCode; // machine-readable identifier
|
|
74
|
+
message: string; // human-readable description
|
|
75
|
+
path: string; // JSON path of the offending field
|
|
76
|
+
expected?: unknown;
|
|
77
|
+
actual?: unknown;
|
|
78
|
+
details?: unknown;
|
|
79
|
+
};
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`validator.validate()` **never throws** — every error condition is reported as a `Violation`. Safe to call in any code path.
|
|
83
|
+
|
|
84
|
+
## Integration guide for UI teams
|
|
85
|
+
|
|
86
|
+
The SDK is designed to run **between** receiving the API response and presenting it to the user for signing. Wire it into that seam.
|
|
87
|
+
|
|
88
|
+
### 1. Where to call
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
┌──────────────┐ ┌─────────┐ ┌─────────────────-─┐ ┌──────────────┐
|
|
92
|
+
│ Build request│ ──▶ │ fetch() │ ──▶ │ validator.validate│ ──▶ │ Sign / submit│
|
|
93
|
+
└──────────────┘ └─────────┘ └──────────────────-┘ └──────────────┘
|
|
94
|
+
│
|
|
95
|
+
▼
|
|
96
|
+
ok ? proceed : block
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
- **Before `validate`:** the user has not yet seen or signed anything.
|
|
100
|
+
- **After `validate`:** if `result.ok === false`, **do not forward any signable payload** (intent message, permit, transaction) to the wallet. The API response cannot be trusted.
|
|
101
|
+
|
|
102
|
+
### 2. Choosing the environment
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
import { Environment } from "@debridge-finance/borderless-validation-sdk";
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- `Environment.Prod` — production.
|
|
109
|
+
- `Environment.Hanoi`, `Environment.Dubai`, `Environment.Madrid` — non-prod deployments (may have empty whitelists; ask the SDK team before use).
|
|
110
|
+
|
|
111
|
+
Pass the same environment your app is already configured for — don't make it user-selectable.
|
|
112
|
+
|
|
113
|
+
### 3. Pass the exact URL you called
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
const url = "https://cross-chain-api.debridge.finance/v1.0/bundle";
|
|
117
|
+
const response = await fetch(url, { ... });
|
|
118
|
+
const result = validator.validate(url, request, response);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The `url` argument is checked against a per-environment whitelist. Passing a hardcoded constant defeats the check — pass the same string you handed to `fetch`.
|
|
122
|
+
|
|
123
|
+
### 4. Handling violations
|
|
124
|
+
|
|
125
|
+
On `result.ok === false`:
|
|
126
|
+
|
|
127
|
+
1. **Block the signing flow.** Do not show a wallet popup or write any pending tx to state.
|
|
128
|
+
2. **Log the full `violations` array** to your error reporting system (Sentry / Datadog / etc.). Include `code`, `path`, `expected`, `actual`, `details`.
|
|
129
|
+
3. **Show the user a generic error.** Do not leak raw `Violation` data into the UI — messages are for developers, not end-users. A single "Quote is invalid, please retry" is enough.
|
|
130
|
+
4. **Do not retry automatically.** If the API is compromised, retries make it worse. Let the user manually trigger a retry.
|
|
131
|
+
|
|
132
|
+
### 5. Browser compatibility
|
|
133
|
+
|
|
134
|
+
The SDK is published as both CJS and ESM and uses only browser-compatible APIs (no `fs`, `crypto`, `Buffer`, `process`). It has been smoke-tested in a plain `<script type="module">` environment — see [`tmp/front/`](./tmp/front/) for a minimal example.
|
|
135
|
+
|
|
136
|
+
Tree-shaking: the ESM build preserves named exports. Importing only `createValidator` will not pull in unused validators.
|
|
137
|
+
|
|
138
|
+
### 6. Bundle size
|
|
139
|
+
|
|
140
|
+
Roughly 1 MB unpacked (a lot of it is source maps — drop them in production). The heaviest peer dep is `@solana/web3.js`; if your app only deals with EVM trades, your bundler's tree-shaking should eliminate most of it.
|
|
141
|
+
|
|
142
|
+
### 7. TypeScript
|
|
143
|
+
|
|
144
|
+
Full type declarations ship in `dist/types/`. `ValidatorConfig`, `ValidationResult`, `Violation`, and `ViolationCode` are all exported — use them directly, don't re-declare.
|
|
145
|
+
|
|
146
|
+
### 8. What NOT to do
|
|
147
|
+
|
|
148
|
+
- ❌ **Don't skip validation** because "the API is our own." Compromise detection is the whole point.
|
|
149
|
+
- ❌ **Don't mutate `request` or `response`** between the API call and `validate()` — the validator needs the exact payload the user received.
|
|
150
|
+
- ❌ **Don't interpret `violations[].message` programmatically** — message wording may change between versions. Branch on `code` instead.
|
|
151
|
+
- ❌ **Don't cache the validator if `environment` changes.** Create a new instance via `createValidator` for each environment.
|
|
152
|
+
|
|
153
|
+
## Development
|
|
154
|
+
|
|
155
|
+
See [`CLAUDE.md`](./CLAUDE.md) for project conventions, validation rules, and security guidelines.
|
|
156
|
+
|
|
157
|
+
- Unit tests: `npm test`
|
|
158
|
+
- Coverage: `npm run coverage`
|
|
159
|
+
- E2E tests (hit the staging API): `npm run test:e2e`
|
|
160
|
+
- Build: `npm run build`
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
BUSL-1.1
|
|
@@ -3,11 +3,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
exports.
|
|
6
|
+
exports.TRON_NATIVE_ADDRESS = void 0;
|
|
7
|
+
exports.getChainEngine = getChainEngine;
|
|
8
8
|
exports.isTronAddress = isTronAddress;
|
|
9
9
|
exports.tronAddressToEvmHex = tronAddressToEvmHex;
|
|
10
10
|
exports.normalizeAddress = normalizeAddress;
|
|
11
|
+
exports.detectChainEngine = detectChainEngine;
|
|
12
|
+
exports.normalizeAddressByValue = normalizeAddressByValue;
|
|
11
13
|
exports.addressEquals = addressEquals;
|
|
12
14
|
exports.isNativeToken = isNativeToken;
|
|
13
15
|
const viem_1 = require("viem");
|
|
@@ -16,18 +18,12 @@ const enums_1 = require("../types/enums");
|
|
|
16
18
|
const solana_1 = require("../whitelists/solana");
|
|
17
19
|
// Tron-specific addresses (Base58Check format)
|
|
18
20
|
exports.TRON_NATIVE_ADDRESS = "T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb";
|
|
19
|
-
|
|
20
|
-
(function (AddressFormat) {
|
|
21
|
-
AddressFormat[AddressFormat["EVM"] = 0] = "EVM";
|
|
22
|
-
AddressFormat[AddressFormat["Tron"] = 1] = "Tron";
|
|
23
|
-
AddressFormat[AddressFormat["Solana"] = 2] = "Solana";
|
|
24
|
-
})(AddressFormat || (exports.AddressFormat = AddressFormat = {}));
|
|
25
|
-
function getAddressFormat(chainId) {
|
|
21
|
+
function getChainEngine(chainId) {
|
|
26
22
|
if (chainId === enums_1.ChainId.Tron)
|
|
27
|
-
return
|
|
23
|
+
return enums_1.ChainEngine.Tron;
|
|
28
24
|
if (chainId === enums_1.ChainId.Solana)
|
|
29
|
-
return
|
|
30
|
-
return
|
|
25
|
+
return enums_1.ChainEngine.Solana;
|
|
26
|
+
return enums_1.ChainEngine.EVM;
|
|
31
27
|
}
|
|
32
28
|
function isTronAddress(address) {
|
|
33
29
|
if (!address)
|
|
@@ -50,10 +46,26 @@ function tronAddressToEvmHex(tronAddress) {
|
|
|
50
46
|
const addressBytes = decoded.slice(1, 21);
|
|
51
47
|
return (0, viem_1.bytesToHex)(addressBytes);
|
|
52
48
|
}
|
|
53
|
-
// Normalizes address for comparison based on chain
|
|
49
|
+
// Normalizes address for comparison based on chain engine
|
|
54
50
|
function normalizeAddress(chainId, address) {
|
|
55
|
-
const
|
|
56
|
-
|
|
51
|
+
const engine = getChainEngine(chainId);
|
|
52
|
+
return applyEngineNormalization(address, engine);
|
|
53
|
+
}
|
|
54
|
+
// Detects the chain engine from the address value alone (no chainId required).
|
|
55
|
+
// Useful when a chain is not fixed (e.g. destinationChainIds = "any").
|
|
56
|
+
function detectChainEngine(address) {
|
|
57
|
+
if (address.startsWith("0x"))
|
|
58
|
+
return enums_1.ChainEngine.EVM;
|
|
59
|
+
if (isTronAddress(address))
|
|
60
|
+
return enums_1.ChainEngine.Tron;
|
|
61
|
+
return enums_1.ChainEngine.Solana;
|
|
62
|
+
}
|
|
63
|
+
// Normalizes an address using only its own value — no chainId needed.
|
|
64
|
+
function normalizeAddressByValue(address) {
|
|
65
|
+
return applyEngineNormalization(address, detectChainEngine(address));
|
|
66
|
+
}
|
|
67
|
+
function applyEngineNormalization(address, engine) {
|
|
68
|
+
if (engine === enums_1.ChainEngine.Tron || engine === enums_1.ChainEngine.Solana) {
|
|
57
69
|
return address; // case-sensitive
|
|
58
70
|
}
|
|
59
71
|
return address.toLowerCase(); // EVM: case-insensitive
|
|
@@ -62,12 +74,13 @@ function normalizeAddress(chainId, address) {
|
|
|
62
74
|
function addressEquals(chainId, a, b) {
|
|
63
75
|
return normalizeAddress(chainId, a) === normalizeAddress(chainId, b);
|
|
64
76
|
}
|
|
65
|
-
// Checks if address is native token for the given chain
|
|
77
|
+
// Checks if address is the native token for the given chain.
|
|
66
78
|
function isNativeToken(address, chainId) {
|
|
67
|
-
|
|
79
|
+
const engine = getChainEngine(chainId);
|
|
80
|
+
if (engine === enums_1.ChainEngine.Tron) {
|
|
68
81
|
return address === exports.TRON_NATIVE_ADDRESS;
|
|
69
82
|
}
|
|
70
|
-
if (
|
|
83
|
+
if (engine === enums_1.ChainEngine.Solana) {
|
|
71
84
|
return address === solana_1.SYSTEM_PROGRAM;
|
|
72
85
|
}
|
|
73
86
|
return address.toLowerCase() === viem_1.zeroAddress;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"address.js","sourceRoot":"","sources":["../../../src/helpers/address.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"address.js","sourceRoot":"","sources":["../../../src/helpers/address.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,14 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.actionUsesTransactionCalls = actionUsesTransactionCalls;
|
|
4
4
|
exports.getTransactionCalls = getTransactionCalls;
|
|
5
5
|
const types_1 = require("../types");
|
|
6
|
-
// Transaction and
|
|
6
|
+
// Transaction and Sign712MetaMaskCaveats actions carry transactionCalls;
|
|
7
7
|
// Sign712 (Permit/Permit2) and Sign7702Authorization do not.
|
|
8
8
|
function actionUsesTransactionCalls(action) {
|
|
9
9
|
return action.type === types_1.EvmActionKind.Transaction
|
|
10
|
-
|| action.type === types_1.EvmActionKind.
|
|
10
|
+
|| action.type === types_1.EvmActionKind.Sign712MetaMaskCaveats;
|
|
11
11
|
}
|
|
12
12
|
// For Transaction-type actions (non-AA), the call is in action.data directly.
|
|
13
|
-
// For
|
|
13
|
+
// For Sign712MetaMaskCaveats-type actions (AA), the calls are in details.transactionCalls.
|
|
14
14
|
function getTransactionCalls(action) {
|
|
15
15
|
if (action.type === types_1.EvmActionKind.Transaction) {
|
|
16
16
|
return [action.data];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evm-action.js","sourceRoot":"","sources":["../../../src/helpers/evm-action.ts"],"names":[],"mappings":";;AAIA,gEAGC;AAID,kDAKC;AAhBD,oCAAgF;AAEhF,
|
|
1
|
+
{"version":3,"file":"evm-action.js","sourceRoot":"","sources":["../../../src/helpers/evm-action.ts"],"names":[],"mappings":";;AAIA,gEAGC;AAID,kDAKC;AAhBD,oCAAgF;AAEhF,yEAAyE;AACzE,6DAA6D;AAC7D,SAAgB,0BAA0B,CAAC,MAAyB;IAChE,OAAO,MAAM,CAAC,IAAI,KAAK,qBAAa,CAAC,WAAW;WACzC,MAAM,CAAC,IAAI,KAAK,qBAAa,CAAC,sBAAsB,CAAC;AAChE,CAAC;AAED,8EAA8E;AAC9E,2FAA2F;AAC3F,SAAgB,mBAAmB,CAAC,MAAyB;IACzD,IAAI,MAAM,CAAC,IAAI,KAAK,qBAAa,CAAC,WAAW,EAAE,CAAC;QAC5C,OAAO,CAAC,MAAM,CAAC,IAA0B,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,EAAE,gBAAgB,IAAI,EAAE,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateEvmGasCompensationTx = validateEvmGasCompensationTx;
|
|
4
|
+
const evm_calldata_1 = require("./evm-calldata");
|
|
5
|
+
const evm_token_1 = require("./evm-token");
|
|
6
|
+
const address_1 = require("./address");
|
|
7
|
+
// Validates an EVM `{to, data, value}` triplet that is expected to encode a
|
|
8
|
+
// gas-compensation transfer. `groups` are the gas-compensation groups
|
|
9
|
+
// associated with this triplet's source (already filtered to the relevant
|
|
10
|
+
// `(chainId, sender)` pair by the caller).
|
|
11
|
+
//
|
|
12
|
+
// Classification: dispatched on `triplet.data`:
|
|
13
|
+
// - `data === "0x"` → native compensation (data="0x", value > 0,
|
|
14
|
+
// and at least one group must carry a native token).
|
|
15
|
+
// - otherwise → ERC20 compensation (`triplet.to` matches some non-native
|
|
16
|
+
// group's tokenAddress, data is `transfer(...)`, value === "0").
|
|
17
|
+
function validateEvmGasCompensationTx(triplet, groups, realChainId, basePath, codes) {
|
|
18
|
+
if (triplet.data === "0x") {
|
|
19
|
+
return validateNativeCompensation(triplet, groups, basePath, codes);
|
|
20
|
+
}
|
|
21
|
+
return validateErc20Compensation(triplet, groups, realChainId, basePath, codes);
|
|
22
|
+
}
|
|
23
|
+
function validateNativeCompensation(triplet, groups, basePath, codes) {
|
|
24
|
+
const violations = [];
|
|
25
|
+
// CRITICAL: data="0x" implies native — must have at least one native group.
|
|
26
|
+
const hasNativeGroup = groups.some(g => (0, evm_token_1.isNativeToken)(g.tokenAddress, g.realChainId));
|
|
27
|
+
if (!hasNativeGroup) {
|
|
28
|
+
violations.push({
|
|
29
|
+
code: codes.dataInvalid,
|
|
30
|
+
message: "data=\"0x\" implies native compensation but no group has a native token",
|
|
31
|
+
path: `${basePath}.data`,
|
|
32
|
+
expected: groups.map(g => g.tokenAddress),
|
|
33
|
+
actual: "0x",
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// HIGH: native compensation value must parse and be > 0.
|
|
37
|
+
violations.push(...validateNativeValue(triplet.value, basePath, codes));
|
|
38
|
+
return violations;
|
|
39
|
+
}
|
|
40
|
+
function validateNativeValue(rawValue, basePath, codes) {
|
|
41
|
+
try {
|
|
42
|
+
if (BigInt(rawValue) <= 0n) {
|
|
43
|
+
return [{
|
|
44
|
+
code: codes.valueInvalid,
|
|
45
|
+
message: "native compensation must have value > 0",
|
|
46
|
+
path: `${basePath}.value`,
|
|
47
|
+
actual: rawValue,
|
|
48
|
+
}];
|
|
49
|
+
}
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
return [{
|
|
54
|
+
code: codes.valueInvalid,
|
|
55
|
+
message: "native compensation value is not a valid number",
|
|
56
|
+
path: `${basePath}.value`,
|
|
57
|
+
actual: rawValue,
|
|
58
|
+
details: error,
|
|
59
|
+
}];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function validateErc20Compensation(triplet, groups, realChainId, basePath, codes) {
|
|
63
|
+
const violations = [];
|
|
64
|
+
// CRITICAL: `to` must equal some non-native group's tokenAddress.
|
|
65
|
+
const erc20Groups = groups.filter(g => !(0, evm_token_1.isNativeToken)(g.tokenAddress, g.realChainId));
|
|
66
|
+
const matches = erc20Groups.some(g => (0, address_1.normalizeAddress)(g.realChainId, g.tokenAddress)
|
|
67
|
+
=== (0, address_1.normalizeAddress)(realChainId, triplet.to));
|
|
68
|
+
if (!matches) {
|
|
69
|
+
violations.push({
|
|
70
|
+
code: codes.toMismatch,
|
|
71
|
+
message: "ERC20 compensation `to` does not match any group's tokenAddress",
|
|
72
|
+
path: `${basePath}.to`,
|
|
73
|
+
expected: erc20Groups.map(g => g.tokenAddress),
|
|
74
|
+
actual: triplet.to,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// CRITICAL: data must be a valid ERC20 transfer calldata.
|
|
78
|
+
try {
|
|
79
|
+
(0, evm_calldata_1.decodeTransferCalldata)(triplet.data);
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
violations.push({
|
|
83
|
+
code: codes.dataInvalid,
|
|
84
|
+
message: "ERC20 compensation data is not a valid transfer calldata",
|
|
85
|
+
path: `${basePath}.data`,
|
|
86
|
+
actual: triplet.data,
|
|
87
|
+
details: error,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
// HIGH: ERC20 compensation must have value="0".
|
|
91
|
+
if (triplet.value !== "0") {
|
|
92
|
+
violations.push({
|
|
93
|
+
code: codes.valueInvalid,
|
|
94
|
+
message: "ERC20 compensation must have value=\"0\"",
|
|
95
|
+
path: `${basePath}.value`,
|
|
96
|
+
expected: "0",
|
|
97
|
+
actual: triplet.value,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
return violations;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=evm-gas-compensation-tx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evm-gas-compensation-tx.js","sourceRoot":"","sources":["../../../src/helpers/evm-gas-compensation-tx.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@ function convertToIntentStruct(intent) {
|
|
|
20
20
|
intentTimestamp: BigInt(intent.intentTimestamp),
|
|
21
21
|
srcAllowedSender: (intent.srcAllowedSender ?? []),
|
|
22
22
|
executionMetadata: (intent.executionMetadata ?? viem_1.zeroHash),
|
|
23
|
-
isAnyDlnMetadataAllowed:
|
|
23
|
+
isAnyDlnMetadataAllowed: !intent.dlnMetadata,
|
|
24
24
|
dlnMetadata: (intent.dlnMetadata ?? "0x"),
|
|
25
25
|
externalCallHash: (intent.externalCallHash ?? viem_1.zeroHash),
|
|
26
26
|
combinedInteractions: "0x",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evm-intent-id.js","sourceRoot":"","sources":["../../../src/helpers/evm-intent-id.ts"],"names":[],"mappings":";;AAIA,0CAIC;AARD,+BAA6E;AAE7E,2DAA+D;AAE/D,SAAgB,eAAe,CAAC,MAAsB;IAClD,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAA,0BAAmB,EAAC,4CAAwB,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACxE,OAAO,IAAA,gBAAS,EAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,qBAAqB,CAAC,MAAsB;IACjD,OAAO;QACH,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,WAAW,EAAE,MAAM,CAAC,WAA4B;QAChD,eAAe,EAAE,uBAAuB,CAAC,MAAM,CAAC,eAAe,CAAC;QAChE,UAAU,EAAE,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC;QACjD,SAAS,EAAE,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC;QAC9C,SAAS,EAAE,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC;QAC9C,mBAAmB,EAAE,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC;QACvD,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC;QAC/C,gBAAgB,EAAE,CAAC,MAAM,CAAC,gBAAgB,IAAI,EAAE,CAAoB;QACpE,iBAAiB,EAAE,CAAC,MAAM,CAAC,iBAAiB,IAAI,eAAQ,CAAkB;QAC1E,uBAAuB,EAAE,
|
|
1
|
+
{"version":3,"file":"evm-intent-id.js","sourceRoot":"","sources":["../../../src/helpers/evm-intent-id.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractGasCompensationGroups = extractGasCompensationGroups;
|
|
4
|
+
const address_1 = require("./address");
|
|
5
|
+
const subscription_to_chain_id_1 = require("../whitelists/subscription-to-chain-id");
|
|
6
|
+
// Groups `gasCompensationInfo` entries from request.preHooks by
|
|
7
|
+
// (chainId, tokenAddress, sender). One compensation hook per
|
|
8
|
+
// unique group is expected to be appended to response.preHooks.
|
|
9
|
+
// Groups with an unknown subscription chainId are skipped — they'll surface as
|
|
10
|
+
// `UnknownSubscriptionId` via the trade-grouping pass.
|
|
11
|
+
function extractGasCompensationGroups(request) {
|
|
12
|
+
const seen = new Set();
|
|
13
|
+
const groups = [];
|
|
14
|
+
for (const hook of request.preHooks ?? []) {
|
|
15
|
+
const info = hook.gasCompensationInfo;
|
|
16
|
+
if (!info)
|
|
17
|
+
continue;
|
|
18
|
+
const realChainId = (0, subscription_to_chain_id_1.resolveChainId)(info.chainId);
|
|
19
|
+
if (realChainId === undefined)
|
|
20
|
+
continue;
|
|
21
|
+
const key = `${realChainId}`
|
|
22
|
+
+ `:${(0, address_1.normalizeAddress)(realChainId, info.tokenAddress)}`
|
|
23
|
+
+ `:${(0, address_1.normalizeAddress)(realChainId, info.sender)}`;
|
|
24
|
+
if (seen.has(key))
|
|
25
|
+
continue;
|
|
26
|
+
seen.add(key);
|
|
27
|
+
groups.push({
|
|
28
|
+
chainId: info.chainId,
|
|
29
|
+
realChainId,
|
|
30
|
+
tokenAddress: info.tokenAddress,
|
|
31
|
+
sender: info.sender,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return groups;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=gas-compensation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gas-compensation.js","sourceRoot":"","sources":["../../../src/helpers/gas-compensation.ts"],"names":[],"mappings":";;AAiBA,oEA8BC;AA7CD,uCAA6C;AAC7C,qFAAwE;AASxE,gEAAgE;AAChE,6DAA6D;AAC7D,gEAAgE;AAChE,+EAA+E;AAC/E,uDAAuD;AACvD,SAAgB,4BAA4B,CACxC,OAA8B;IAE9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,mBAAmB,CAAC;QACtC,IAAI,CAAC,IAAI;YAAE,SAAS;QAEpB,MAAM,WAAW,GAAG,IAAA,yCAAc,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,WAAW,KAAK,SAAS;YAAE,SAAS;QAExC,MAAM,GAAG,GAAG,GAAG,WAAW,EAAE;cACtB,IAAI,IAAA,0BAAgB,EAAC,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,EAAE;cACtD,IAAI,IAAA,0BAAgB,EAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAEvD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAE5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEd,MAAM,CAAC,IAAI,CAAC;YACR,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,WAAW;YACX,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,MAAM,EAAE,IAAI,CAAC,MAAM;SACtB,CAAC,CAAC;IACP,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlaceholderResolutionErrorReason = exports.HookMode = exports.SOLANA_DEFAULT_PLACEHOLDER_BYTE_COUNT = exports.EVM_DEFAULT_PLACEHOLDER_BYTE_COUNT = void 0;
|
|
4
|
+
exports.encodePlaceholderAmount = encodePlaceholderAmount;
|
|
5
|
+
exports.computeCumulativeTradeAmount = computeCumulativeTradeAmount;
|
|
6
|
+
exports.resolveEagerPlaceholders = resolveEagerPlaceholders;
|
|
7
|
+
const enums_1 = require("../types/enums");
|
|
8
|
+
const address_1 = require("./address");
|
|
9
|
+
const MIN_PLACEHOLDER_BYTE_COUNT = 1;
|
|
10
|
+
const MAX_PLACEHOLDER_BYTE_COUNT = 32;
|
|
11
|
+
exports.EVM_DEFAULT_PLACEHOLDER_BYTE_COUNT = MAX_PLACEHOLDER_BYTE_COUNT;
|
|
12
|
+
exports.SOLANA_DEFAULT_PLACEHOLDER_BYTE_COUNT = 8;
|
|
13
|
+
var HookMode;
|
|
14
|
+
(function (HookMode) {
|
|
15
|
+
HookMode[HookMode["PreHooks"] = 0] = "PreHooks";
|
|
16
|
+
HookMode[HookMode["PostHooks"] = 1] = "PostHooks";
|
|
17
|
+
})(HookMode || (exports.HookMode = HookMode = {}));
|
|
18
|
+
var PlaceholderResolutionErrorReason;
|
|
19
|
+
(function (PlaceholderResolutionErrorReason) {
|
|
20
|
+
PlaceholderResolutionErrorReason[PlaceholderResolutionErrorReason["MissingTokenOrAddress"] = 0] = "MissingTokenOrAddress";
|
|
21
|
+
PlaceholderResolutionErrorReason[PlaceholderResolutionErrorReason["NegativeAmount"] = 1] = "NegativeAmount";
|
|
22
|
+
PlaceholderResolutionErrorReason[PlaceholderResolutionErrorReason["Overflow"] = 2] = "Overflow";
|
|
23
|
+
PlaceholderResolutionErrorReason[PlaceholderResolutionErrorReason["InvalidByteCount"] = 3] = "InvalidByteCount";
|
|
24
|
+
PlaceholderResolutionErrorReason[PlaceholderResolutionErrorReason["InvalidAdditionalAmount"] = 4] = "InvalidAdditionalAmount";
|
|
25
|
+
PlaceholderResolutionErrorReason[PlaceholderResolutionErrorReason["NoMatchingTradeOrAdditional"] = 5] = "NoMatchingTradeOrAdditional";
|
|
26
|
+
})(PlaceholderResolutionErrorReason || (exports.PlaceholderResolutionErrorReason = PlaceholderResolutionErrorReason = {}));
|
|
27
|
+
// Encodes a non-negative integer as a zero-padded hex string (no "0x" prefix),
|
|
28
|
+
// fitting exactly `byteCount` bytes, using the chain engine's endianness.
|
|
29
|
+
// Solana: little-endian. EVM/Tron: big-endian.
|
|
30
|
+
// `byteCount` must be an integer in
|
|
31
|
+
// [MIN_PLACEHOLDER_BYTE_COUNT, MAX_PLACEHOLDER_BYTE_COUNT].
|
|
32
|
+
function encodePlaceholderAmount(amount, byteCount, engine) {
|
|
33
|
+
if (!isValidByteCount(byteCount)) {
|
|
34
|
+
return { ok: false, reason: PlaceholderResolutionErrorReason.InvalidByteCount };
|
|
35
|
+
}
|
|
36
|
+
if (amount < 0n) {
|
|
37
|
+
return { ok: false, reason: PlaceholderResolutionErrorReason.NegativeAmount };
|
|
38
|
+
}
|
|
39
|
+
const maxValue = (1n << BigInt(byteCount * 8)) - 1n;
|
|
40
|
+
if (amount > maxValue) {
|
|
41
|
+
return { ok: false, reason: PlaceholderResolutionErrorReason.Overflow };
|
|
42
|
+
}
|
|
43
|
+
if (engine === enums_1.ChainEngine.Solana) { // Use little-endian for Solana
|
|
44
|
+
const bytes = [];
|
|
45
|
+
let value = amount;
|
|
46
|
+
for (let i = 0; i < byteCount; i++) {
|
|
47
|
+
bytes.push((value & 0xffn).toString(16).padStart(2, "0"));
|
|
48
|
+
value >>= 8n;
|
|
49
|
+
}
|
|
50
|
+
return { ok: true, hex: bytes.join("") };
|
|
51
|
+
}
|
|
52
|
+
// Use big-endian (EVM/Tron): simple hex conversion with left-padding.
|
|
53
|
+
return { ok: true, hex: amount.toString(16).padStart(byteCount * 2, "0") };
|
|
54
|
+
}
|
|
55
|
+
function isValidByteCount(byteCount) {
|
|
56
|
+
return Number.isInteger(byteCount)
|
|
57
|
+
&& byteCount >= MIN_PLACEHOLDER_BYTE_COUNT
|
|
58
|
+
&& byteCount <= MAX_PLACEHOLDER_BYTE_COUNT;
|
|
59
|
+
}
|
|
60
|
+
// Sums the trade amount matching the placeholder's (chainId, tokenAddress, address).
|
|
61
|
+
// preHooks: sums trade.srcChainTokenIn.amount across trades where
|
|
62
|
+
// trade.srcChainTokenIn.{chainId,address} and trade.srcChainAuthorityAddress match.
|
|
63
|
+
// postHooks: sums trade.dstChainTokenOut.amount across trades where
|
|
64
|
+
// trade.dstChainTokenOut.{chainId,address} and trade.dstChainTokenOutRecipient match.
|
|
65
|
+
// In quote mode authority/recipient is undefined — such trades are skipped.
|
|
66
|
+
function computeCumulativeTradeAmount(trades, mode, chainId, tokenAddress, address) {
|
|
67
|
+
let sum = 0n;
|
|
68
|
+
let matchCount = 0;
|
|
69
|
+
for (const trade of trades) {
|
|
70
|
+
const tradeChainId = mode === HookMode.PreHooks
|
|
71
|
+
? trade.srcChainTokenIn.chainId
|
|
72
|
+
: trade.dstChainTokenOut.chainId;
|
|
73
|
+
if (tradeChainId !== chainId)
|
|
74
|
+
continue;
|
|
75
|
+
const tradeAuthority = mode === HookMode.PreHooks
|
|
76
|
+
? trade.srcChainAuthorityAddress
|
|
77
|
+
: trade.dstChainTokenOutRecipient;
|
|
78
|
+
if (tradeAuthority === undefined)
|
|
79
|
+
continue;
|
|
80
|
+
const tradeToken = mode === HookMode.PreHooks
|
|
81
|
+
? trade.srcChainTokenIn.address
|
|
82
|
+
: trade.dstChainTokenOut.address;
|
|
83
|
+
if (!(0, address_1.addressEquals)(chainId, tradeToken, tokenAddress))
|
|
84
|
+
continue;
|
|
85
|
+
if (!(0, address_1.addressEquals)(chainId, tradeAuthority, address))
|
|
86
|
+
continue;
|
|
87
|
+
const amount = mode === HookMode.PreHooks
|
|
88
|
+
? trade.srcChainTokenIn.amount
|
|
89
|
+
: trade.dstChainTokenOut.amount;
|
|
90
|
+
sum += BigInt(amount);
|
|
91
|
+
matchCount++;
|
|
92
|
+
}
|
|
93
|
+
return { cumulative: sum, matchCount };
|
|
94
|
+
}
|
|
95
|
+
// Applies eager-placeholder substitution to a hex string (calldata or value).
|
|
96
|
+
// Markers: `{name}` or `{name.N}` (N = byte count).
|
|
97
|
+
// Deferred placeholders are not touched — their markers remain in the output.
|
|
98
|
+
// If any eager placeholder cannot be resolved, its marker is left intact and the
|
|
99
|
+
// error is collected into `errors`; callers decide how to report it.
|
|
100
|
+
function resolveEagerPlaceholders(data, hookChainId, placeholders, trades, mode) {
|
|
101
|
+
const engine = (0, address_1.getChainEngine)(hookChainId);
|
|
102
|
+
const defaultByteCount = engine === enums_1.ChainEngine.Solana
|
|
103
|
+
? exports.SOLANA_DEFAULT_PLACEHOLDER_BYTE_COUNT
|
|
104
|
+
: exports.EVM_DEFAULT_PLACEHOLDER_BYTE_COUNT;
|
|
105
|
+
let result = data;
|
|
106
|
+
const errors = [];
|
|
107
|
+
for (const placeholder of placeholders) {
|
|
108
|
+
if (placeholder.type === enums_1.PlaceholderType.Deferred)
|
|
109
|
+
continue;
|
|
110
|
+
// Eager placeholder — type is either explicitly 'eager' or undefined (default).
|
|
111
|
+
if (placeholder.tokenAddress === undefined
|
|
112
|
+
|| placeholder.address === undefined) {
|
|
113
|
+
// Zod guards this at the schema level; defensive branch for callers
|
|
114
|
+
// that bypass structural validation.
|
|
115
|
+
errors.push({
|
|
116
|
+
nameVariable: placeholder.nameVariable,
|
|
117
|
+
reason: PlaceholderResolutionErrorReason.MissingTokenOrAddress,
|
|
118
|
+
});
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
let additional = 0n;
|
|
122
|
+
if (placeholder.additionalAmount !== undefined) {
|
|
123
|
+
try {
|
|
124
|
+
additional = BigInt(placeholder.additionalAmount);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
errors.push({
|
|
128
|
+
nameVariable: placeholder.nameVariable,
|
|
129
|
+
reason: PlaceholderResolutionErrorReason.InvalidAdditionalAmount,
|
|
130
|
+
details: error,
|
|
131
|
+
});
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const { cumulative, matchCount } = computeCumulativeTradeAmount(trades, mode, hookChainId, placeholder.tokenAddress, placeholder.address);
|
|
136
|
+
const expectedAmount = cumulative + additional;
|
|
137
|
+
const nameEscaped = escapeRegex(placeholder.nameVariable);
|
|
138
|
+
const markerRegex = new RegExp(`\\{${nameEscaped}(?:\\.(\\d+))?\\}`, "g");
|
|
139
|
+
// MEDIUM: when no trade matches and no `additionalAmount` is supplied,
|
|
140
|
+
// the API rejects the request. Here we are mirroring this logic.
|
|
141
|
+
if (matchCount === 0
|
|
142
|
+
&& placeholder.additionalAmount === undefined
|
|
143
|
+
&& markerRegex.test(result)) {
|
|
144
|
+
errors.push({
|
|
145
|
+
nameVariable: placeholder.nameVariable,
|
|
146
|
+
reason: PlaceholderResolutionErrorReason.NoMatchingTradeOrAdditional,
|
|
147
|
+
});
|
|
148
|
+
// Reset RegExp.lastIndex before the `replace` below.
|
|
149
|
+
markerRegex.lastIndex = 0;
|
|
150
|
+
// Skip substitution — leave marker in `result` so calldata comparison
|
|
151
|
+
// surfaces any mutated value as a separate violation.
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
result = result.replace(markerRegex, (match, byteCountStr) => {
|
|
155
|
+
const byteCount = byteCountStr
|
|
156
|
+
? parseInt(byteCountStr, 10)
|
|
157
|
+
: defaultByteCount;
|
|
158
|
+
const encoded = encodePlaceholderAmount(expectedAmount, byteCount, engine);
|
|
159
|
+
if (!encoded.ok) {
|
|
160
|
+
errors.push({
|
|
161
|
+
nameVariable: placeholder.nameVariable,
|
|
162
|
+
reason: encoded.reason,
|
|
163
|
+
});
|
|
164
|
+
return match;
|
|
165
|
+
}
|
|
166
|
+
return encoded.hex;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
return { resolved: result, errors };
|
|
170
|
+
}
|
|
171
|
+
function escapeRegex(s) {
|
|
172
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=placeholder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"placeholder.js","sourceRoot":"","sources":["../../../src/helpers/placeholder.ts"],"names":[],"mappings":"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"}
|