@augustdigital/sdk 9.8.0 → 9.9.0
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 +57 -0
- package/lib/adapters/evm/index.d.ts +23 -5
- package/lib/adapters/evm/index.js +25 -4
- package/lib/core/analytics/method-taxonomy.js +2 -0
- package/lib/core/analytics/version.d.ts +1 -1
- package/lib/core/analytics/version.js +1 -1
- package/lib/core/attribution.d.ts +37 -5
- package/lib/core/attribution.js +39 -3
- package/lib/core/base.class.d.ts +6 -0
- package/lib/core/constants/swap-router.d.ts +21 -4
- package/lib/core/constants/swap-router.js +22 -5
- package/lib/core/helpers/swap-router.d.ts +66 -5
- package/lib/core/helpers/swap-router.js +158 -7
- package/lib/main.d.ts +21 -3
- package/lib/main.js +20 -3
- package/lib/modules/vaults/getters.d.ts +287 -14
- package/lib/modules/vaults/getters.js +452 -45
- package/lib/modules/vaults/main.d.ts +18 -1
- package/lib/modules/vaults/main.js +23 -0
- package/lib/modules/vaults/write.actions.d.ts +119 -29
- package/lib/modules/vaults/write.actions.js +384 -77
- package/lib/sdk.d.ts +11674 -11107
- package/lib/services/layerzero/deposits.d.ts +6 -0
- package/lib/services/layerzero/deposits.js +8 -0
- package/lib/services/subgraph/schema.d.ts +5 -2
- package/lib/services/subgraph/schema.js +22 -10
- package/lib/services/subgraph/vaults.d.ts +23 -1
- package/lib/services/subgraph/vaults.js +65 -0
- package/lib/types/subgraph.d.ts +10 -0
- package/lib/types/vaults.d.ts +38 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -82,6 +82,63 @@ new AugustSDK({ appName: 'Acme Trader', providers: { /* ... */ } });
|
|
|
82
82
|
new AugustSDK({ appName: 'acme-trader', providers: { /* ... */ } });
|
|
83
83
|
```
|
|
84
84
|
|
|
85
|
+
### Origin-Code Attribution (SwapRouter)
|
|
86
|
+
|
|
87
|
+
An integrator with an origin (referral / fee-sharing) code registered on the SwapRouter sets it once on the
|
|
88
|
+
SDK instance. Deposits made through the SDK then carry it on-chain:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
const sdk = new AugustSDK({
|
|
92
|
+
appName: 'acme-trader',
|
|
93
|
+
providers: { 1: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY' },
|
|
94
|
+
attribution: {
|
|
95
|
+
originCode: '0x…', // bytes32 registered on the SwapRouter with addOrigin
|
|
96
|
+
strictOrigin: false, // optional: true throws instead of falling back
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Check the code before you ship it.
|
|
101
|
+
const { registered, originFeeBps, collector } = await sdk.getOriginInfo({
|
|
102
|
+
chainId: 1,
|
|
103
|
+
originCode: '0x…',
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
- **Ethereum mainnet only.** The instance code is sent on chain 1 (`ORIGIN_ATTRIBUTION_CHAINS`) and on no other
|
|
108
|
+
chain, even where a SwapRouter is configured.
|
|
109
|
+
- **Where it applies.** `vaultDeposit` sends a deposit through `SwapRouter.deposit` with the code when
|
|
110
|
+
`sdk.evm.getDepositRoute()` returns `via: 'router'`: the vault is registered on the router, the vault accepts
|
|
111
|
+
the asset as-is (its reference asset, or a Tokenized Vault V2 whitelisted asset — never swapped), the router
|
|
112
|
+
whitelists the asset, the deposit is not a permit, native-token or adapter deposit, and the code is
|
|
113
|
+
registered. `swapRouterDeposit`, `swapAndDeposit`, `depositViaSwapRouter` and `depositNativeViaSwapRouter`
|
|
114
|
+
send it too.
|
|
115
|
+
- **Precedence.** An `originCode` passed to a router method wins, then the instance code, then the all-zero
|
|
116
|
+
sentinel (no origin fee). Pass the zero sentinel to opt one call out.
|
|
117
|
+
- **Fallback.** When the code cannot be applied — it is not registered, the chain is not mainnet, the router
|
|
118
|
+
does not whitelist the asset, the vault does not accept it or is not registered on the router, or it is a
|
|
119
|
+
permit, native-token or adapter deposit — `vaultDeposit` takes the vault's native path and logs
|
|
120
|
+
`vaultDeposit:attribution-skipped` with the reason (Sentry tag `sdk.attribution.origin=skipped`). The router
|
|
121
|
+
methods send the zero sentinel for an unregistered instance code and log `<method>:attribution-skipped`.
|
|
122
|
+
With `strictOrigin: true` an unregistered instance code throws `AugustValidationError` before any approval
|
|
123
|
+
instead. An `originCode` passed to a router method that is not registered always throws
|
|
124
|
+
`AugustValidationError` before any approval.
|
|
125
|
+
- **Approve `route.spender`, not the vault.** A routed deposit is pulled by the SwapRouter. `vaultDeposit` and
|
|
126
|
+
`approve` handle this; if you send approvals yourself, read the spender first:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
const route = await sdk.evm.getDepositRoute({ target: vault, depositAsset: usdc });
|
|
130
|
+
// route.spender is the SwapRouter when route.via === 'router', else the vault (or adapter wrapper)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- **Gas.** Measured on a mainnet fork (repeat 1,000 USDC deposits into Core USDC): direct deposit 102,067 gas;
|
|
134
|
+
router with a 0% code 161,744 (+59.7k); router with a 1% code 173,135 (+71.1k). A routed deposit also needs a
|
|
135
|
+
one-time approval of the router per token.
|
|
136
|
+
- **Zero-fee codes.** A code registered with a 0 bps fee is valid for attribution only, but the router emits no
|
|
137
|
+
`OriginFeeApplied` event for it. Its deposits are attributable only from the transaction calldata and SDK
|
|
138
|
+
telemetry.
|
|
139
|
+
- **Process-global.** `attribution` is process-global: the last `AugustSDK` constructed wins, and one
|
|
140
|
+
constructed without `attribution` clears it. Run one attribution configuration per process.
|
|
141
|
+
|
|
85
142
|
## Architecture
|
|
86
143
|
|
|
87
144
|
```
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type IContractWriteOptions, type INativeDepositOptions, type ApproveResult, type IClaimWithdrawalOptions } from '../../modules/vaults/write.actions';
|
|
1
|
+
import { type IContractWriteOptions, type INativeDepositOptions, type ApproveResult, type IClaimWithdrawalOptions, type IGetDepositRouteOptions } from '../../modules/vaults/write.actions';
|
|
2
2
|
import type { ISwapAndDepositOptions, ISwapRouterDirectDepositOptions, ISwapRouterNativeDepositOptions, ISwapRouterDepositOptions, ISwapRouterDepositResultOptions } from '../../types';
|
|
3
3
|
import { type IPreviewDepositOptions, type IPreviewRedeemOptions, type IAllowanceOptions, type IBalanceOfOptions, type IMaxDepositOptions, type IGetIdleLiquidityOptions, type ILagDurationOptions, type IGetWithdrawalEpochOptions, type IWithdrawalEpoch, type IGetBurnableAmountByReceiverOptions, type IGetRequirementByDateOptions, type IGetScheduledTransactionsByDateOptions, type IScheduledTransactionsByDate } from '../../modules/vaults/read.actions';
|
|
4
4
|
import { type CompatibleSigner } from '../../core/helpers/signer';
|
|
@@ -74,7 +74,9 @@ declare class EVMAdapter {
|
|
|
74
74
|
/**
|
|
75
75
|
* Deposit into an August vault. Routes automatically: V1 single-asset vaults
|
|
76
76
|
* deposit the underlying directly; V2 multi-asset vaults route through the
|
|
77
|
-
* adapter for non-underlying `depositAsset`.
|
|
77
|
+
* adapter for non-underlying `depositAsset`. With `attribution.originCode`
|
|
78
|
+
* configured, eligible deposits go through the SwapRouter instead (see
|
|
79
|
+
* {@link EVMAdapter.getDepositRoute}). If allowance is insufficient
|
|
78
80
|
* the method submits an approve transaction first (the approve step always
|
|
79
81
|
* waits for confirmation to close a race window, regardless of `wait`).
|
|
80
82
|
*
|
|
@@ -98,6 +100,22 @@ declare class EVMAdapter {
|
|
|
98
100
|
* ```
|
|
99
101
|
*/
|
|
100
102
|
vaultDeposit(options: IContractWriteOptions): Promise<string>;
|
|
103
|
+
/**
|
|
104
|
+
* Resolve whether a deposit goes through the SwapRouter with the instance
|
|
105
|
+
* origin code or takes the vault's native path, and the address to approve
|
|
106
|
+
* (`route.spender`, not necessarily the vault). See {@link getDepositRoute}.
|
|
107
|
+
*
|
|
108
|
+
* @param options - {@link IGetDepositRouteOptions}.
|
|
109
|
+
* @returns `{ via, spender, reason? }` — `reason` explains a native route.
|
|
110
|
+
* @throws AugustValidationError on an invalid target, or an unregistered
|
|
111
|
+
* code under `attribution.strictOrigin`.
|
|
112
|
+
* @throws AugustSDKError when a backend, vault or router read fails.
|
|
113
|
+
* @example
|
|
114
|
+
* ```ts
|
|
115
|
+
* const { via, spender } = await augustSdk.evm.getDepositRoute({ target: vault });
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
getDepositRoute(options: IGetDepositRouteOptions): Promise<import("../../modules/vaults/write.actions").IDepositRoute>;
|
|
101
119
|
/**
|
|
102
120
|
* Submit a redemption request against a vault. Shares are escrowed and the
|
|
103
121
|
* underlying assets are released asynchronously by the protocol; callers
|
|
@@ -194,9 +212,9 @@ declare class EVMAdapter {
|
|
|
194
212
|
/**
|
|
195
213
|
* Deposit into a vault through the on-chain `SwapRouter`, choosing the router
|
|
196
214
|
* path from `depositAsset` (direct deposit, native wrap, or a swap to the
|
|
197
|
-
* reference asset). The
|
|
198
|
-
*
|
|
199
|
-
*
|
|
215
|
+
* reference asset). The explicit, opt-in swap entry point —
|
|
216
|
+
* {@link vaultDeposit} never swaps — so a native-deposit vault is never
|
|
217
|
+
* accidentally swapped.
|
|
200
218
|
*
|
|
201
219
|
* Reads the vault's reference asset + decimals on-chain, resolves the swap
|
|
202
220
|
* quote and fail-closes on aggregator/whitelist drift, and sends the ERC-20
|
|
@@ -119,7 +119,9 @@ class EVMAdapter {
|
|
|
119
119
|
/**
|
|
120
120
|
* Deposit into an August vault. Routes automatically: V1 single-asset vaults
|
|
121
121
|
* deposit the underlying directly; V2 multi-asset vaults route through the
|
|
122
|
-
* adapter for non-underlying `depositAsset`.
|
|
122
|
+
* adapter for non-underlying `depositAsset`. With `attribution.originCode`
|
|
123
|
+
* configured, eligible deposits go through the SwapRouter instead (see
|
|
124
|
+
* {@link EVMAdapter.getDepositRoute}). If allowance is insufficient
|
|
123
125
|
* the method submits an approve transaction first (the approve step always
|
|
124
126
|
* waits for confirmation to close a race window, regardless of `wait`).
|
|
125
127
|
*
|
|
@@ -146,6 +148,25 @@ class EVMAdapter {
|
|
|
146
148
|
const signer = await this._getSigner();
|
|
147
149
|
return (0, write_actions_1.vaultDeposit)(signer, options);
|
|
148
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Resolve whether a deposit goes through the SwapRouter with the instance
|
|
153
|
+
* origin code or takes the vault's native path, and the address to approve
|
|
154
|
+
* (`route.spender`, not necessarily the vault). See {@link getDepositRoute}.
|
|
155
|
+
*
|
|
156
|
+
* @param options - {@link IGetDepositRouteOptions}.
|
|
157
|
+
* @returns `{ via, spender, reason? }` — `reason` explains a native route.
|
|
158
|
+
* @throws AugustValidationError on an invalid target, or an unregistered
|
|
159
|
+
* code under `attribution.strictOrigin`.
|
|
160
|
+
* @throws AugustSDKError when a backend, vault or router read fails.
|
|
161
|
+
* @example
|
|
162
|
+
* ```ts
|
|
163
|
+
* const { via, spender } = await augustSdk.evm.getDepositRoute({ target: vault });
|
|
164
|
+
* ```
|
|
165
|
+
*/
|
|
166
|
+
async getDepositRoute(options) {
|
|
167
|
+
const signer = await this._getSigner();
|
|
168
|
+
return (0, write_actions_1.getDepositRoute)(signer, options);
|
|
169
|
+
}
|
|
149
170
|
/**
|
|
150
171
|
* Submit a redemption request against a vault. Shares are escrowed and the
|
|
151
172
|
* underlying assets are released asynchronously by the protocol; callers
|
|
@@ -257,9 +278,9 @@ class EVMAdapter {
|
|
|
257
278
|
/**
|
|
258
279
|
* Deposit into a vault through the on-chain `SwapRouter`, choosing the router
|
|
259
280
|
* path from `depositAsset` (direct deposit, native wrap, or a swap to the
|
|
260
|
-
* reference asset). The
|
|
261
|
-
*
|
|
262
|
-
*
|
|
281
|
+
* reference asset). The explicit, opt-in swap entry point —
|
|
282
|
+
* {@link vaultDeposit} never swaps — so a native-deposit vault is never
|
|
283
|
+
* accidentally swapped.
|
|
263
284
|
*
|
|
264
285
|
* Reads the vault's reference asset + decimals on-chain, resolves the swap
|
|
265
286
|
* quote and fail-closes on aggregator/whitelist drift, and sends the ERC-20
|
|
@@ -52,6 +52,8 @@ exports.METHOD_CATEGORIES = {
|
|
|
52
52
|
getSwapRouterDepositResult: 'read.vault',
|
|
53
53
|
getSwapRouterWhitelistedTokens: 'read.vault',
|
|
54
54
|
getSwapRouterEligibleVaults: 'read.vault',
|
|
55
|
+
getOriginInfo: 'read.vault',
|
|
56
|
+
getDepositRoute: 'read.vault',
|
|
55
57
|
getVaultPositions: 'read.position',
|
|
56
58
|
getVaultUserHistory: 'read.position',
|
|
57
59
|
getUserHistory: 'read.position',
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
export declare const ERC8021_MARKER = "80218021802180218021802180218021";
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* ERC-8021 builder-code attribution and the SwapRouter origin code — independent; set either or both.
|
|
24
24
|
*
|
|
25
25
|
* @example
|
|
26
26
|
* ```typescript
|
|
@@ -36,9 +36,10 @@ export interface IAttributionConfig {
|
|
|
36
36
|
/**
|
|
37
37
|
* Builder codes to embed in the suffix, e.g. from base.dev registration
|
|
38
38
|
* (`bc_…`). ASCII strings of 1–64 characters each; the comma-joined list
|
|
39
|
-
* must fit in 255 bytes (schema 0 length prefix is a single byte).
|
|
39
|
+
* must fit in 255 bytes (schema 0 length prefix is a single byte). Omit to
|
|
40
|
+
* send no ERC-8021 suffix.
|
|
40
41
|
*/
|
|
41
|
-
builderCodes
|
|
42
|
+
builderCodes?: string[];
|
|
42
43
|
/**
|
|
43
44
|
* EVM chain IDs to attribute. Omit to attribute writes on every EVM chain
|
|
44
45
|
* (the suffix is inert on chains without an ERC-8021 indexer and costs
|
|
@@ -53,6 +54,22 @@ export interface IAttributionConfig {
|
|
|
53
54
|
* receives the suffix anyway cannot be transacted on from a Ledger at all.
|
|
54
55
|
*/
|
|
55
56
|
chains?: number[];
|
|
57
|
+
/**
|
|
58
|
+
* SwapRouter origin (referral / fee-sharing) code: the `bytes32` registered
|
|
59
|
+
* via the router's `addOrigin`, as `0x` + 64 hex chars. Every Ethereum
|
|
60
|
+
* mainnet SwapRouter deposit carries it unless the call passes its own
|
|
61
|
+
* `originCode`; it is never sent on another chain. Omit to send the
|
|
62
|
+
* all-zero sentinel (no origin fee). Unaffected by `chains`. An
|
|
63
|
+
* unregistered code reverts with `InvalidOrigin` — check it with
|
|
64
|
+
* `getOriginInfo` first.
|
|
65
|
+
*/
|
|
66
|
+
originCode?: `0x${string}`;
|
|
67
|
+
/**
|
|
68
|
+
* When `true`, a deposit route that would use the SwapRouter with an
|
|
69
|
+
* `originCode` not registered there throws `AugustValidationError` before
|
|
70
|
+
* any transaction, instead of falling back to the vault's native path.
|
|
71
|
+
*/
|
|
72
|
+
strictOrigin?: boolean;
|
|
56
73
|
}
|
|
57
74
|
/**
|
|
58
75
|
* Build an ERC-8021 schema-0 attribution suffix from builder codes.
|
|
@@ -78,16 +95,31 @@ export declare function buildAttributionSuffix(codes: string[]): string;
|
|
|
78
95
|
*
|
|
79
96
|
* Called unconditionally on every `AugustSDK` construction — an instance
|
|
80
97
|
* that omits `attribution` passes `null` and RESETS the state, so a prior
|
|
81
|
-
* instance's builder codes never leak into a later instance
|
|
82
|
-
* process (same semantics as `setPublicApiBaseUrl`).
|
|
98
|
+
* instance's builder codes or origin code never leak into a later instance
|
|
99
|
+
* in the same process (same semantics as `setPublicApiBaseUrl`).
|
|
83
100
|
*
|
|
84
101
|
* @param config Attribution config from the SDK constructor, or `null` to
|
|
85
102
|
* disable attribution.
|
|
86
103
|
* @throws Error when the config's builder codes fail validation — thrown
|
|
87
104
|
* synchronously from the constructor so misconfiguration is caught at
|
|
88
105
|
* init, not on the first write.
|
|
106
|
+
* @throws {@link AugustValidationError} when `originCode` is not a 32-byte
|
|
107
|
+
* hex string.
|
|
89
108
|
*/
|
|
90
109
|
export declare function setAttribution(config: IAttributionConfig | null): void;
|
|
110
|
+
/**
|
|
111
|
+
* Whether {@link IAttributionConfig.strictOrigin} is set on the SDK instance.
|
|
112
|
+
*
|
|
113
|
+
* @returns `true` when an unregistered origin code must fail a deposit.
|
|
114
|
+
*/
|
|
115
|
+
export declare function isStrictOrigin(): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* The SwapRouter origin code configured on the SDK instance via
|
|
118
|
+
* {@link IAttributionConfig.originCode}.
|
|
119
|
+
*
|
|
120
|
+
* @returns The `bytes32` code, or `null` when none is configured.
|
|
121
|
+
*/
|
|
122
|
+
export declare function getOriginCode(): `0x${string}` | null;
|
|
91
123
|
/**
|
|
92
124
|
* Whether attribution is configured at all, independent of any chain gate.
|
|
93
125
|
*
|
package/lib/core/attribution.js
CHANGED
|
@@ -18,9 +18,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
18
18
|
exports.ERC8021_MARKER = void 0;
|
|
19
19
|
exports.buildAttributionSuffix = buildAttributionSuffix;
|
|
20
20
|
exports.setAttribution = setAttribution;
|
|
21
|
+
exports.isStrictOrigin = isStrictOrigin;
|
|
22
|
+
exports.getOriginCode = getOriginCode;
|
|
21
23
|
exports.isAttributionEnabled = isAttributionEnabled;
|
|
22
24
|
exports.getAttributionSuffix = getAttributionSuffix;
|
|
23
25
|
exports.appendAttributionSuffix = appendAttributionSuffix;
|
|
26
|
+
const swap_router_1 = require("./constants/swap-router");
|
|
27
|
+
const errors_1 = require("./errors");
|
|
24
28
|
/**
|
|
25
29
|
* The 16-byte ERC-8021 suffix terminator. The last 16 bytes of an attributed
|
|
26
30
|
* transaction's calldata are always this marker; parsers read backwards from
|
|
@@ -71,31 +75,63 @@ function buildAttributionSuffix(codes) {
|
|
|
71
75
|
}
|
|
72
76
|
let activeSuffix = null;
|
|
73
77
|
let activeChains = null;
|
|
78
|
+
let activeOriginCode = null;
|
|
79
|
+
let activeStrictOrigin = false;
|
|
74
80
|
/**
|
|
75
81
|
* Set (or clear) the process-global attribution config.
|
|
76
82
|
*
|
|
77
83
|
* Called unconditionally on every `AugustSDK` construction — an instance
|
|
78
84
|
* that omits `attribution` passes `null` and RESETS the state, so a prior
|
|
79
|
-
* instance's builder codes never leak into a later instance
|
|
80
|
-
* process (same semantics as `setPublicApiBaseUrl`).
|
|
85
|
+
* instance's builder codes or origin code never leak into a later instance
|
|
86
|
+
* in the same process (same semantics as `setPublicApiBaseUrl`).
|
|
81
87
|
*
|
|
82
88
|
* @param config Attribution config from the SDK constructor, or `null` to
|
|
83
89
|
* disable attribution.
|
|
84
90
|
* @throws Error when the config's builder codes fail validation — thrown
|
|
85
91
|
* synchronously from the constructor so misconfiguration is caught at
|
|
86
92
|
* init, not on the first write.
|
|
93
|
+
* @throws {@link AugustValidationError} when `originCode` is not a 32-byte
|
|
94
|
+
* hex string.
|
|
87
95
|
*/
|
|
88
96
|
function setAttribution(config) {
|
|
89
97
|
if (!config) {
|
|
90
98
|
activeSuffix = null;
|
|
91
99
|
activeChains = null;
|
|
100
|
+
activeOriginCode = null;
|
|
101
|
+
activeStrictOrigin = false;
|
|
92
102
|
return;
|
|
93
103
|
}
|
|
94
|
-
|
|
104
|
+
const { originCode } = config;
|
|
105
|
+
if (originCode !== undefined && !swap_router_1.ORIGIN_CODE_PATTERN.test(originCode)) {
|
|
106
|
+
throw new errors_1.AugustValidationError('INVALID_INPUT', `August SDK: attribution.originCode must be a 32-byte hex string (0x + 64 hex chars), got ${String(originCode).length} chars. Pass the bytes32 code registered on the SwapRouter via addOrigin.`, { context: { expectedLength: 66 } });
|
|
107
|
+
}
|
|
108
|
+
activeSuffix =
|
|
109
|
+
config.builderCodes === undefined
|
|
110
|
+
? null
|
|
111
|
+
: buildAttributionSuffix(config.builderCodes);
|
|
95
112
|
activeChains =
|
|
96
113
|
Array.isArray(config.chains) && config.chains.length > 0
|
|
97
114
|
? config.chains
|
|
98
115
|
: null;
|
|
116
|
+
activeOriginCode = originCode ?? null;
|
|
117
|
+
activeStrictOrigin = config.strictOrigin === true;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Whether {@link IAttributionConfig.strictOrigin} is set on the SDK instance.
|
|
121
|
+
*
|
|
122
|
+
* @returns `true` when an unregistered origin code must fail a deposit.
|
|
123
|
+
*/
|
|
124
|
+
function isStrictOrigin() {
|
|
125
|
+
return activeStrictOrigin;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The SwapRouter origin code configured on the SDK instance via
|
|
129
|
+
* {@link IAttributionConfig.originCode}.
|
|
130
|
+
*
|
|
131
|
+
* @returns The `bytes32` code, or `null` when none is configured.
|
|
132
|
+
*/
|
|
133
|
+
function getOriginCode() {
|
|
134
|
+
return activeOriginCode;
|
|
99
135
|
}
|
|
100
136
|
/**
|
|
101
137
|
* Whether attribution is configured at all, independent of any chain gate.
|
package/lib/core/base.class.d.ts
CHANGED
|
@@ -120,12 +120,18 @@ export interface IAugustBase {
|
|
|
120
120
|
* offchain indexers (base.dev) can credit the transaction to your app.
|
|
121
121
|
* Omit to send unattributed transactions (the default).
|
|
122
122
|
*
|
|
123
|
+
* `attribution.originCode` sets the SwapRouter origin (referral /
|
|
124
|
+
* fee-sharing) code that every Ethereum mainnet SwapRouter deposit made
|
|
125
|
+
* through the SDK carries unless the call passes its own.
|
|
126
|
+
*
|
|
123
127
|
* Note: this is a process-global override applied on EVERY construction —
|
|
124
128
|
* the last `AugustSDK` instantiated is authoritative, and one that omits
|
|
125
129
|
* `attribution` RESETS it (same semantics as `publicApiBaseUrl`).
|
|
126
130
|
*
|
|
127
131
|
* @throws Throws synchronously from the constructor when the builder codes
|
|
128
132
|
* are malformed — see {@link IAttributionConfig}.
|
|
133
|
+
* @throws AugustValidationError synchronously from the constructor when
|
|
134
|
+
* `originCode` is not a 32-byte hex string.
|
|
129
135
|
*/
|
|
130
136
|
attribution?: IAttributionConfig;
|
|
131
137
|
}
|
|
@@ -31,10 +31,11 @@ export declare const SWAP_ROUTER_NAMES: Readonly<Record<number, string>>;
|
|
|
31
31
|
* deposit surface for a vault; and
|
|
32
32
|
* - {@link swapRouterDeposit}, optionally, as a fail-fast eligibility check.
|
|
33
33
|
*
|
|
34
|
-
* It is deliberately **NOT** read by {@link vaultDeposit}: `vaultDeposit`
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
34
|
+
* It is deliberately **NOT** read by {@link vaultDeposit}: `vaultDeposit` never
|
|
35
|
+
* swaps, and uses the SwapRouter only for a direct deposit carrying a
|
|
36
|
+
* configured origin code (see `getDepositRoute`). That separation is what
|
|
37
|
+
* stops a natively-accepted asset from being silently swapped — the
|
|
38
|
+
* regression that implicit auto-routing caused. Any-token swap
|
|
38
39
|
* deposits are the explicit, opt-in job of {@link swapRouterDeposit}.
|
|
39
40
|
*
|
|
40
41
|
* Membership requires the vault to be registered on-chain
|
|
@@ -93,6 +94,22 @@ export declare const ORIGIN_CODES: {
|
|
|
93
94
|
/** All-zero sentinel — no origin fee. */
|
|
94
95
|
readonly default: `0x${string}`;
|
|
95
96
|
};
|
|
97
|
+
/**
|
|
98
|
+
* Shape of a SwapRouter origin code: `0x` followed by exactly 64 hex chars
|
|
99
|
+
* (a `bytes32`). Shared by every origin-code entry point so the constructor
|
|
100
|
+
* option, the per-call override and the registration read validate the same
|
|
101
|
+
* way.
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
104
|
+
export declare const ORIGIN_CODE_PATTERN: RegExp;
|
|
105
|
+
/**
|
|
106
|
+
* Chains on which the SDK sends the instance origin code
|
|
107
|
+
* (`attribution.originCode`). Ethereum mainnet only: it is the one SwapRouter
|
|
108
|
+
* deployment whose origin registry has been verified. On any other chain the
|
|
109
|
+
* instance code is never sent, even where a SwapRouter is configured; an
|
|
110
|
+
* `originCode` passed to a call is still sent.
|
|
111
|
+
*/
|
|
112
|
+
export declare const ORIGIN_ATTRIBUTION_CHAINS: readonly number[];
|
|
96
113
|
/**
|
|
97
114
|
* Maximum number of swap legs the contract accepts in a single
|
|
98
115
|
* `swapAndDeposit` call. Mirrors the on-chain `MAX_SWAPS` constant; reading
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SWAP_ROUTER_DEX_AGGREGATOR = exports.SWAP_ROUTER_WRAPPED_NATIVE = exports.SWAP_ROUTER_MAX_SWAPS = exports.ORIGIN_CODES = exports.SWAP_ROUTER_DEPLOY_BLOCKS = exports.VAULTS_USING_SWAP_ROUTER = exports.SWAP_ROUTER_ELIGIBLE_VAULTS = exports.SWAP_ROUTER_NAMES = exports.SWAP_ROUTER_ADDRESSES = void 0;
|
|
3
|
+
exports.SWAP_ROUTER_DEX_AGGREGATOR = exports.SWAP_ROUTER_WRAPPED_NATIVE = exports.SWAP_ROUTER_MAX_SWAPS = exports.ORIGIN_ATTRIBUTION_CHAINS = exports.ORIGIN_CODE_PATTERN = exports.ORIGIN_CODES = exports.SWAP_ROUTER_DEPLOY_BLOCKS = exports.VAULTS_USING_SWAP_ROUTER = exports.SWAP_ROUTER_ELIGIBLE_VAULTS = exports.SWAP_ROUTER_NAMES = exports.SWAP_ROUTER_ADDRESSES = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Address of the `SwapRouter` periphery contract on each supported chain.
|
|
6
6
|
*
|
|
@@ -39,10 +39,11 @@ exports.SWAP_ROUTER_NAMES = {
|
|
|
39
39
|
* deposit surface for a vault; and
|
|
40
40
|
* - {@link swapRouterDeposit}, optionally, as a fail-fast eligibility check.
|
|
41
41
|
*
|
|
42
|
-
* It is deliberately **NOT** read by {@link vaultDeposit}: `vaultDeposit`
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
42
|
+
* It is deliberately **NOT** read by {@link vaultDeposit}: `vaultDeposit` never
|
|
43
|
+
* swaps, and uses the SwapRouter only for a direct deposit carrying a
|
|
44
|
+
* configured origin code (see `getDepositRoute`). That separation is what
|
|
45
|
+
* stops a natively-accepted asset from being silently swapped — the
|
|
46
|
+
* regression that implicit auto-routing caused. Any-token swap
|
|
46
47
|
* deposits are the explicit, opt-in job of {@link swapRouterDeposit}.
|
|
47
48
|
*
|
|
48
49
|
* Membership requires the vault to be registered on-chain
|
|
@@ -109,6 +110,22 @@ exports.ORIGIN_CODES = {
|
|
|
109
110
|
/** All-zero sentinel — no origin fee. */
|
|
110
111
|
default: '0x0000000000000000000000000000000000000000000000000000000000000000',
|
|
111
112
|
};
|
|
113
|
+
/**
|
|
114
|
+
* Shape of a SwapRouter origin code: `0x` followed by exactly 64 hex chars
|
|
115
|
+
* (a `bytes32`). Shared by every origin-code entry point so the constructor
|
|
116
|
+
* option, the per-call override and the registration read validate the same
|
|
117
|
+
* way.
|
|
118
|
+
* @internal
|
|
119
|
+
*/
|
|
120
|
+
exports.ORIGIN_CODE_PATTERN = /^0x[0-9a-fA-F]{64}$/;
|
|
121
|
+
/**
|
|
122
|
+
* Chains on which the SDK sends the instance origin code
|
|
123
|
+
* (`attribution.originCode`). Ethereum mainnet only: it is the one SwapRouter
|
|
124
|
+
* deployment whose origin registry has been verified. On any other chain the
|
|
125
|
+
* instance code is never sent, even where a SwapRouter is configured; an
|
|
126
|
+
* `originCode` passed to a call is still sent.
|
|
127
|
+
*/
|
|
128
|
+
exports.ORIGIN_ATTRIBUTION_CHAINS = [1];
|
|
112
129
|
/**
|
|
113
130
|
* Maximum number of swap legs the contract accepts in a single
|
|
114
131
|
* `swapAndDeposit` call. Mirrors the on-chain `MAX_SWAPS` constant; reading
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Signer, type Wallet } from 'ethers';
|
|
2
|
-
import type { IAddress, ISwapRouterDepositResult, ISwapRouterDepositResultOptions } from '../../types';
|
|
2
|
+
import type { IAddress, IContractRunner, IGetOriginInfoOptions, IOriginInfo, ISwapRouterDepositResult, ISwapRouterDepositResultOptions } from '../../types';
|
|
3
3
|
/**
|
|
4
4
|
* Resolve the `SwapRouter` address for a chain.
|
|
5
5
|
*
|
|
@@ -39,7 +39,7 @@ export declare function getSwapRouterName(chainId: number): string | undefined;
|
|
|
39
39
|
*
|
|
40
40
|
* This gates the (flag-controlled) swap-router deposit UI and can fail-fast a
|
|
41
41
|
* {@link swapRouterDeposit} call. It does **not** affect {@link vaultDeposit},
|
|
42
|
-
* which
|
|
42
|
+
* which never swaps (see `getDepositRoute` for when it uses the router).
|
|
43
43
|
*
|
|
44
44
|
* @param vaultAddress - August vault address.
|
|
45
45
|
* @returns `true` when the vault is in {@link SWAP_ROUTER_ELIGIBLE_VAULTS}.
|
|
@@ -62,18 +62,24 @@ export declare const vaultUsesSwapRouter: typeof isSwapRouterEligible;
|
|
|
62
62
|
/**
|
|
63
63
|
* Normalize an optional origin code to the value to send on-chain.
|
|
64
64
|
*
|
|
65
|
-
* Returns the caller-supplied code when present
|
|
66
|
-
*
|
|
65
|
+
* Returns the caller-supplied code when present (an explicit all-zero
|
|
66
|
+
* sentinel opts one call out), otherwise the SDK instance's
|
|
67
|
+
* `attribution.originCode` when `chainId` is in
|
|
68
|
+
* {@link ORIGIN_ATTRIBUTION_CHAINS} (Ethereum mainnet only), otherwise the
|
|
69
|
+
* default (all-zero) sentinel from {@link ORIGIN_CODES}. Validates that any
|
|
67
70
|
* supplied code is exactly 32 bytes (66 chars including the `0x` prefix);
|
|
68
71
|
* the on-chain SwapRouter reverts with `InvalidOrigin` otherwise, but
|
|
69
72
|
* surfacing the failure here as a typed SDK error gives partners a
|
|
70
73
|
* grepable Sentry event instead of a generic `execution reverted`.
|
|
71
74
|
*
|
|
72
75
|
* @param provided - Optional caller-supplied origin code.
|
|
76
|
+
* @param chainId - Chain the deposit is sent on. The instance code is never
|
|
77
|
+
* returned without it, or on a chain outside
|
|
78
|
+
* {@link ORIGIN_ATTRIBUTION_CHAINS}.
|
|
73
79
|
* @returns The 32-byte origin code to pass to the router.
|
|
74
80
|
* @throws {@link AugustValidationError} when `provided` is not a 32-byte hex string.
|
|
75
81
|
*/
|
|
76
|
-
export declare function resolveOriginCode(provided?: `0x${string}
|
|
82
|
+
export declare function resolveOriginCode(provided?: `0x${string}`, chainId?: number): `0x${string}`;
|
|
77
83
|
/**
|
|
78
84
|
* Resolves the real, post-execution outcome of a SwapRouter deposit from its
|
|
79
85
|
* mined transaction receipt. The SwapRouter contract itself emits no
|
|
@@ -108,6 +114,61 @@ export declare function resolveOriginCode(provided?: `0x${string}`): `0x${string
|
|
|
108
114
|
* ```
|
|
109
115
|
*/
|
|
110
116
|
export declare function getSwapRouterDepositResult(signer: Signer | Wallet, { txHash, vault }: ISwapRouterDepositResultOptions): Promise<ISwapRouterDepositResult | null>;
|
|
117
|
+
/**
|
|
118
|
+
* Read how an origin code is registered on a chain's `SwapRouter`: whether it
|
|
119
|
+
* exists, its origin fee, and its fee collector.
|
|
120
|
+
*
|
|
121
|
+
* Check a partner code with this before configuring it as
|
|
122
|
+
* `attribution.originCode` — the router reverts every deposit carrying an
|
|
123
|
+
* unregistered code with `InvalidOrigin`. A code is registered when its
|
|
124
|
+
* collector is non-zero (`addOrigin` always sets one); a zero-fee code is
|
|
125
|
+
* still registered but never emits `OriginFeeApplied`. Cached per (chain,
|
|
126
|
+
* router, code) for 5 minutes.
|
|
127
|
+
*
|
|
128
|
+
* @param options - {@link IGetOriginInfoOptions}.
|
|
129
|
+
* @returns {@link IOriginInfo}; `registered: false` with a zero fee and
|
|
130
|
+
* collector, and no RPC, on a chain with no SwapRouter deployment.
|
|
131
|
+
* @throws {@link AugustValidationError} when `originCode` is not a 32-byte hex
|
|
132
|
+
* string.
|
|
133
|
+
* @throws {@link AugustSDKError} when the `origins(bytes32)` read fails.
|
|
134
|
+
* @worstCaseRpcCalls 1 — one `origins(bytes32)` call; none on a cache hit.
|
|
135
|
+
* @example
|
|
136
|
+
* ```ts
|
|
137
|
+
* const info = await getOriginInfo({ chainId: 1, originCode, rpcUrl });
|
|
138
|
+
* if (!info.registered) throw new Error('origin code is not registered');
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export declare function getOriginInfo({ chainId, originCode, rpcUrl, }: IGetOriginInfoOptions): Promise<IOriginInfo>;
|
|
142
|
+
/**
|
|
143
|
+
* {@link getOriginInfo} without input validation, reading through a caller
|
|
144
|
+
* runner (created lazily, only on a cache miss). Shared with the deposit-route
|
|
145
|
+
* resolver so both hit the same cache entry.
|
|
146
|
+
* @internal
|
|
147
|
+
*/
|
|
148
|
+
export declare function readOriginInfo(chainId: number, originCode: `0x${string}`, runner: () => IContractRunner): Promise<IOriginInfo>;
|
|
149
|
+
/**
|
|
150
|
+
* Read a vault's `SwapRouter` registration (`vaultInfo`), cached for 5
|
|
151
|
+
* minutes like the other router reads.
|
|
152
|
+
*
|
|
153
|
+
* @returns The router's `referenceAsset` for the vault (the zero address when
|
|
154
|
+
* it is not registered) and its `vaultType`; `undefined` on a chain with no
|
|
155
|
+
* SwapRouter.
|
|
156
|
+
* @internal
|
|
157
|
+
*/
|
|
158
|
+
export declare function readSwapRouterVaultInfo(runner: IContractRunner, chainId: number, vault: IAddress): Promise<{
|
|
159
|
+
referenceAsset: IAddress;
|
|
160
|
+
vaultType: number;
|
|
161
|
+
} | undefined>;
|
|
162
|
+
/**
|
|
163
|
+
* Read whether a chain's `SwapRouter` whitelists `token`
|
|
164
|
+
* (`whitelistedTokens`), cached for 5 minutes like the other router reads.
|
|
165
|
+
* `SwapRouter.deposit` reverts `InputTokenNotWhitelisted` for any token it
|
|
166
|
+
* does not whitelist, the vault's reference asset included.
|
|
167
|
+
*
|
|
168
|
+
* @returns `false` on a chain with no SwapRouter.
|
|
169
|
+
* @internal
|
|
170
|
+
*/
|
|
171
|
+
export declare function readSwapRouterTokenWhitelisted(runner: IContractRunner, chainId: number, token: IAddress): Promise<boolean>;
|
|
111
172
|
/**
|
|
112
173
|
* Resolve the ERC-20 tokens currently whitelisted for the `SwapRouter` on a
|
|
113
174
|
* chain — the any-token set a UI can offer as swap-and-deposit inputs.
|