@augustdigital/sdk 8.5.0 → 8.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +207 -117
- package/lib/adapters/evm/index.d.ts +4 -4
- package/lib/adapters/evm/index.js +2 -0
- package/lib/adapters/solana/constants.d.ts +1 -1
- package/lib/adapters/solana/getters.d.ts +1 -1
- package/lib/adapters/solana/index.d.ts +4 -4
- package/lib/adapters/solana/index.js +4 -0
- package/lib/adapters/solana/types.d.ts +1 -1
- package/lib/adapters/solana/utils.d.ts +3 -3
- package/lib/adapters/solana/vault.actions.d.ts +4 -4
- package/lib/adapters/stellar/actions.d.ts +1 -1
- package/lib/adapters/stellar/index.d.ts +24 -2
- package/lib/adapters/stellar/index.js +25 -2
- package/lib/adapters/stellar/soroban.d.ts +1 -1
- package/lib/adapters/stellar/soroban.js +1 -1
- package/lib/adapters/stellar/submit.d.ts +20 -3
- package/lib/adapters/stellar/submit.js +74 -8
- package/lib/adapters/sui/getters.d.ts +1 -1
- package/lib/adapters/sui/index.d.ts +1 -1
- package/lib/adapters/sui/index.js +2 -0
- package/lib/adapters/sui/transformer.d.ts +2 -2
- package/lib/adapters/sui/transformer.js +1 -0
- package/lib/adapters/sui/types.d.ts +1 -1
- package/lib/core/analytics/instrumentation.js +7 -11
- package/lib/core/analytics/sentry-runtime.js +1 -1
- package/lib/core/analytics/sentry.d.ts +3 -3
- package/lib/core/analytics/sentry.js +31 -5
- package/lib/core/analytics/types.d.ts +1 -1
- package/lib/core/analytics/user-identity.d.ts +2 -2
- package/lib/core/analytics/user-identity.js +1 -1
- package/lib/core/analytics/version.d.ts +1 -1
- package/lib/core/analytics/version.js +1 -1
- package/lib/core/base.class.d.ts +3 -3
- package/lib/core/base.class.js +10 -4
- package/lib/core/constants/adapters.d.ts +1 -1
- package/lib/core/constants/core.d.ts +2 -0
- package/lib/core/constants/core.js +6 -0
- package/lib/core/constants/swap-router.d.ts +37 -1
- package/lib/core/constants/swap-router.js +41 -1
- package/lib/core/constants/vaults.d.ts +1 -1
- package/lib/core/constants/web3.d.ts +1 -1
- package/lib/core/constants/web3.js +0 -3
- package/lib/core/errors/index.d.ts +2 -2
- package/lib/core/errors/index.js +9 -0
- package/lib/core/fetcher.d.ts +39 -39
- package/lib/core/fetcher.js +75 -57
- package/lib/core/helpers/adapters.d.ts +1 -1
- package/lib/core/helpers/chain-error.d.ts +66 -0
- package/lib/core/helpers/chain-error.js +174 -0
- package/lib/core/helpers/core.d.ts +21 -18
- package/lib/core/helpers/core.js +22 -20
- package/lib/core/helpers/explorer-link.d.ts +1 -1
- package/lib/core/helpers/signer.d.ts +1 -1
- package/lib/core/helpers/swap-router.d.ts +1 -1
- package/lib/core/helpers/vault-version.d.ts +1 -1
- package/lib/core/helpers/vaults.d.ts +1 -1
- package/lib/core/helpers/web3.d.ts +2 -2
- package/lib/core/helpers/web3.js +9 -9
- package/lib/core/index.d.ts +1 -0
- package/lib/core/index.js +1 -0
- package/lib/core/vault-metadata.d.ts +1 -1
- package/lib/core/version-check.js +1 -1
- package/lib/evm/methods/crossChainVault.js +1 -1
- package/lib/evm/types/crossChain.js +1 -1
- package/lib/main.d.ts +1 -1
- package/lib/main.js +7 -0
- package/lib/modules/sub-accounts/fetcher.d.ts +2 -2
- package/lib/modules/sub-accounts/main.d.ts +2 -2
- package/lib/modules/sub-accounts/main.js +1 -1
- package/lib/modules/sub-accounts/utils.d.ts +1 -1
- package/lib/modules/vaults/adapter.helpers.d.ts +3 -3
- package/lib/modules/vaults/fetcher.d.ts +25 -0
- package/lib/modules/vaults/fetcher.js +51 -1
- package/lib/modules/vaults/getters.d.ts +50 -50
- package/lib/modules/vaults/getters.js +68 -67
- package/lib/modules/vaults/main.js +3 -1
- package/lib/modules/vaults/read.actions.d.ts +2 -2
- package/lib/modules/vaults/read.actions.js +26 -12
- package/lib/modules/vaults/utils/call-data-decoder.d.ts +1 -1
- package/lib/modules/vaults/utils.d.ts +19 -3
- package/lib/modules/vaults/utils.js +39 -6
- package/lib/modules/vaults/write.actions.js +73 -7
- package/lib/polyfills.js +3 -3
- package/lib/sdk.d.ts +1409 -1198
- package/lib/services/coingecko/fetcher.d.ts +10 -9
- package/lib/services/coingecko/fetcher.js +22 -18
- package/lib/services/debank/fetcher.d.ts +1 -1
- package/lib/services/debank/utils.d.ts +1 -1
- package/lib/services/debank/utils.js +1 -1
- package/lib/services/layerzero/deposits.d.ts +1 -1
- package/lib/services/layerzero/redeems.d.ts +1 -1
- package/lib/services/octavfi/fetcher.d.ts +1 -1
- package/lib/services/octavfi/types.d.ts +1 -1
- package/lib/services/octavfi/utils.d.ts +2 -2
- package/lib/services/subgraph/fetcher.js +1 -1
- package/lib/services/subgraph/vaults.js +86 -3
- package/lib/services/swap-quotes/index.d.ts +9 -0
- package/lib/services/swap-quotes/index.js +2 -1
- package/lib/services/swap-quotes/paraswap.d.ts +8 -0
- package/lib/services/swap-quotes/paraswap.js +8 -0
- package/lib/types/pools.d.ts +2 -2
- package/lib/types/staking.d.ts +1 -1
- package/lib/types/sub-accounts.d.ts +1 -1
- package/lib/types/subgraph.d.ts +10 -1
- package/lib/types/vaults.d.ts +26 -0
- package/lib/types/web3.d.ts +1 -1
- package/lib/types/webserver.d.ts +2 -2
- package/package.json +1 -1
|
@@ -10,12 +10,67 @@ const stellar_sdk_1 = require("@stellar/stellar-sdk");
|
|
|
10
10
|
const core_1 = require("../../core");
|
|
11
11
|
const soroban_1 = require("./soroban");
|
|
12
12
|
const constants_1 = require("./constants");
|
|
13
|
+
/**
|
|
14
|
+
* Best-effort decode of the transaction-level result code (the XDR union
|
|
15
|
+
* discriminant, e.g. `"txBadSeq"`, `"txTooLate"`) from a Soroban
|
|
16
|
+
* `TransactionResult`. Typed `unknown` and probed structurally so it stays
|
|
17
|
+
* robust to RPC/SDK shape drift; returns `undefined` for anything that isn't a
|
|
18
|
+
* decoded union, so callers fall back to the stringified XDR in the message.
|
|
19
|
+
*/
|
|
20
|
+
function extractTxResultCode(result) {
|
|
21
|
+
try {
|
|
22
|
+
const decoded = result;
|
|
23
|
+
if (typeof decoded?.result !== 'function')
|
|
24
|
+
return undefined;
|
|
25
|
+
// `|| undefined`: an empty discriminant shares the clean "no code" path.
|
|
26
|
+
return decoded.result().switch().name || undefined;
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
// Only reached on a malformed / shape-drifted union (the non-union case
|
|
30
|
+
// already returned above). Breadcrumb it so decoder rot stays detectable;
|
|
31
|
+
// the caller still throws with the stringified XDR in the message.
|
|
32
|
+
core_1.Logger.log.warn('extractTxResultCode', { decodeError: String(e) });
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* `JSON.stringify` that never throws. A real `xdr.TransactionResult` can hold
|
|
38
|
+
* `bigint` fields (e.g. `feeCharged`), which make `JSON.stringify` throw a
|
|
39
|
+
* `TypeError` — that would escape and replace the `AugustSDKError` this detail
|
|
40
|
+
* is only meant to enrich. Returns `''` on failure so the caller falls back to
|
|
41
|
+
* the status; the decoded `resultCode` still carries the precise reason.
|
|
42
|
+
*/
|
|
43
|
+
function safeStringify(value) {
|
|
44
|
+
try {
|
|
45
|
+
return JSON.stringify(value) ?? '';
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return '';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
13
51
|
/**
|
|
14
52
|
* Submit a signed Soroban transaction and poll until confirmed.
|
|
15
53
|
*
|
|
16
|
-
* @param signedXdr Base64-encoded XDR of the signed transaction
|
|
17
|
-
* @param network Stellar network name
|
|
18
|
-
* @returns
|
|
54
|
+
* @param signedXdr - Base64-encoded XDR of the signed transaction
|
|
55
|
+
* @param network - Stellar network name
|
|
56
|
+
* @returns The transaction hash once the network confirms it as successful
|
|
57
|
+
* @throws {@link AugustTimeoutError} when the transaction is not confirmed
|
|
58
|
+
* within the poll budget (`MAX_POLL_ATTEMPTS`).
|
|
59
|
+
* @throws {@link AugustSDKError} when the RPC rejects the submission or the
|
|
60
|
+
* transaction confirms as failed. Its `context` carries `{ network, status }`
|
|
61
|
+
* plus, when the result XDR decodes, a `resultCode` string holding the
|
|
62
|
+
* transaction-level reason (e.g. `"txBadSeq"`, `"txTooLate"`); `resultCode`
|
|
63
|
+
* is `undefined` when the code cannot be decoded.
|
|
64
|
+
* @example
|
|
65
|
+
* ```ts
|
|
66
|
+
* try {
|
|
67
|
+
* const hash = await submitStellarTransaction(signedXdr, 'mainnet');
|
|
68
|
+
* } catch (err) {
|
|
69
|
+
* if (err instanceof AugustSDKError && err.context?.resultCode === 'txBadSeq') {
|
|
70
|
+
* // stale sequence number — rebuild the transaction and resubmit
|
|
71
|
+
* }
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
19
74
|
*/
|
|
20
75
|
async function submitStellarTransaction(signedXdr, network) {
|
|
21
76
|
const { rpcUrl, passphrase } = (0, soroban_1.resolveNetworkConfig)(network);
|
|
@@ -23,11 +78,13 @@ async function submitStellarTransaction(signedXdr, network) {
|
|
|
23
78
|
const tx = stellar_sdk_1.TransactionBuilder.fromXDR(signedXdr, passphrase);
|
|
24
79
|
const sendResult = await server.sendTransaction(tx);
|
|
25
80
|
if (sendResult.status === 'ERROR') {
|
|
26
|
-
const
|
|
81
|
+
const errorResult = 'errorResult' in sendResult ? sendResult.errorResult : undefined;
|
|
82
|
+
const resultCode = extractTxResultCode(errorResult);
|
|
83
|
+
const detail = errorResult ? safeStringify(errorResult) : '';
|
|
27
84
|
const msg = `Transaction submission failed: ${detail || sendResult.status}`;
|
|
28
|
-
core_1.Logger.log.error('submitStellarTransaction', msg, { network });
|
|
85
|
+
core_1.Logger.log.error('submitStellarTransaction', msg, { network, resultCode });
|
|
29
86
|
throw new core_1.AugustSDKError('UNKNOWN', msg, {
|
|
30
|
-
context: { network, status: sendResult.status },
|
|
87
|
+
context: { network, status: sendResult.status, resultCode },
|
|
31
88
|
});
|
|
32
89
|
}
|
|
33
90
|
// Only PENDING (and DUPLICATE) mean the tx was accepted by the RPC.
|
|
@@ -66,14 +123,23 @@ async function submitStellarTransaction(signedXdr, network) {
|
|
|
66
123
|
if (getResult.status === 'SUCCESS') {
|
|
67
124
|
return sendResult.hash;
|
|
68
125
|
}
|
|
69
|
-
const
|
|
126
|
+
const resultXdr = 'resultXdr' in getResult ? getResult.resultXdr : undefined;
|
|
127
|
+
const resultCode = extractTxResultCode(resultXdr);
|
|
128
|
+
const detail = resultXdr ? safeStringify(resultXdr) : '';
|
|
129
|
+
const failDetail = detail ? ` (${detail})` : '';
|
|
70
130
|
const msg = `Transaction failed: ${getResult.status}${failDetail}`;
|
|
71
131
|
core_1.Logger.log.error('submitStellarTransaction', msg, {
|
|
72
132
|
hash: sendResult.hash,
|
|
73
133
|
network,
|
|
134
|
+
resultCode,
|
|
74
135
|
});
|
|
75
136
|
throw new core_1.AugustSDKError('UNKNOWN', msg, {
|
|
76
|
-
context: {
|
|
137
|
+
context: {
|
|
138
|
+
hash: sendResult.hash,
|
|
139
|
+
network,
|
|
140
|
+
status: getResult.status,
|
|
141
|
+
resultCode,
|
|
142
|
+
},
|
|
77
143
|
});
|
|
78
144
|
}
|
|
79
145
|
//# sourceMappingURL=submit.js.map
|
|
@@ -7,7 +7,7 @@ import * as SuiConstants from './constants';
|
|
|
7
7
|
import * as SuiGetters from './getters';
|
|
8
8
|
import * as SuiUtils from './utils';
|
|
9
9
|
import { transformEmberVaultToIVault, transformEmberVaultsToIVaults } from './transformer';
|
|
10
|
-
import { IEmberVault, IFetchEmberVaultsOptions } from './types';
|
|
10
|
+
import type { IEmberVault, IFetchEmberVaultsOptions } from './types';
|
|
11
11
|
export declare const Sui: {
|
|
12
12
|
utils: typeof SuiUtils;
|
|
13
13
|
constants: typeof SuiConstants;
|
|
@@ -123,15 +123,11 @@ function trackMethodCall(methodName, metrics, args) {
|
|
|
123
123
|
// Counters: SUM(invocation) → total calls; SUM(error)/SUM(invocation) → error rate.
|
|
124
124
|
sdk.setMeasurement('sdk.method.invocation', 1, 'none');
|
|
125
125
|
sdk.setMeasurement('sdk.method.error', metrics.success ? 0 : 1, 'none');
|
|
126
|
-
//
|
|
126
|
+
// Only sticky-tag the last method name — useful for attributing errors that fire
|
|
127
|
+
// outside an active SDK span. sdk.category and sdk.chain are already recorded as
|
|
128
|
+
// span attributes on each call, so mutating the global scope with them here would
|
|
129
|
+
// just contaminate subsequent unrelated events with stale values.
|
|
127
130
|
sdk.setTag('sdk.last_method', methodName);
|
|
128
|
-
if (metrics.category) {
|
|
129
|
-
sdk.setTag('sdk.category', metrics.category);
|
|
130
|
-
}
|
|
131
|
-
if (metrics.chainId !== undefined) {
|
|
132
|
-
sdk.setTag('sdk.chain', (0, chain_name_1.chainIdToTagValue)(metrics.chainId));
|
|
133
|
-
sdk.setTag('sdk.last_chainId', metrics.chainId.toString());
|
|
134
|
-
}
|
|
135
131
|
}
|
|
136
132
|
catch {
|
|
137
133
|
// Silently fail - analytics should never break SDK
|
|
@@ -223,9 +219,9 @@ function trackSyncMethodCall(methodName, metrics, args) {
|
|
|
223
219
|
...args,
|
|
224
220
|
},
|
|
225
221
|
});
|
|
226
|
-
//
|
|
227
|
-
|
|
228
|
-
|
|
222
|
+
// Measurements omitted: sync methods have no span of their own, so setMeasurement
|
|
223
|
+
// would attach to whatever parent transaction happens to be active on the scope,
|
|
224
|
+
// overwriting its counters. The breadcrumb above already captures success/failure.
|
|
229
225
|
sdk.setTag('sdk.last_sync_method', methodName);
|
|
230
226
|
if (metrics.category) {
|
|
231
227
|
sdk.setTag('sdk.category', metrics.category);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type * as Sentry from '@sentry/browser';
|
|
2
|
-
import { IEnv } from '../../types';
|
|
3
|
-
import { IAnalyticsConfig } from './types';
|
|
2
|
+
import type { IEnv } from '../../types';
|
|
3
|
+
import type { IAnalyticsConfig } from './types';
|
|
4
4
|
/**
|
|
5
5
|
* Initialize Sentry with SDK-specific configuration. Idempotent: re-calls
|
|
6
6
|
* only refresh user identity and the cached API-key hash.
|
|
7
7
|
*
|
|
8
8
|
* @param config - Analytics configuration. Pass `tracesSampleRate` to
|
|
9
|
-
* override the
|
|
9
|
+
* override the default of `0.1`.
|
|
10
10
|
* @param environment - Current environment (DEV or PROD).
|
|
11
11
|
* @param walletAddress - Optional wallet address for user identification.
|
|
12
12
|
* @param apiKey - Optional API key (hashed for identification).
|
|
@@ -138,7 +138,7 @@ function createSentrySink() {
|
|
|
138
138
|
* only refresh user identity and the cached API-key hash.
|
|
139
139
|
*
|
|
140
140
|
* @param config - Analytics configuration. Pass `tracesSampleRate` to
|
|
141
|
-
* override the
|
|
141
|
+
* override the default of `0.1`.
|
|
142
142
|
* @param environment - Current environment (DEV or PROD).
|
|
143
143
|
* @param walletAddress - Optional wallet address for user identification.
|
|
144
144
|
* @param apiKey - Optional API key (hashed for identification).
|
|
@@ -214,17 +214,36 @@ function initializeSentry(config, environment, walletAddress, apiKey, appName) {
|
|
|
214
214
|
const rawSampleRate = typeof config.tracesSampleRate === 'number' &&
|
|
215
215
|
Number.isFinite(config.tracesSampleRate)
|
|
216
216
|
? config.tracesSampleRate
|
|
217
|
-
: 1.0
|
|
217
|
+
: 0.1; // Phase 2 default — verified partners can opt into 1.0 explicitly
|
|
218
218
|
const tracesSampleRate = Math.max(0, Math.min(1, rawSampleRate));
|
|
219
219
|
sdk.init({
|
|
220
220
|
dsn: constants_1.SENTRY_DSN,
|
|
221
|
-
// TODO(post-verified-partner): ramp default down to ~0.1.
|
|
222
221
|
tracesSampleRate,
|
|
223
222
|
enableTracing: true,
|
|
224
223
|
environment: environment.toLowerCase(),
|
|
225
224
|
release: `august-sdk@${getSDKVersion()}`,
|
|
226
225
|
sendDefaultPii: true,
|
|
227
|
-
|
|
226
|
+
// SDK errors route through Logger.setSentrySink → captureException directly,
|
|
227
|
+
// so captureConsoleIntegration is redundant here. Omitting it also prevents
|
|
228
|
+
// consumer app console.error calls from being billed as SDK error events (the
|
|
229
|
+
// global sdk:'august-digital' tag would otherwise cause them to pass beforeSend).
|
|
230
|
+
integrations: [],
|
|
231
|
+
// Drop classes of event that are never SDK signal, as a backstop to the
|
|
232
|
+
// call-site demotions (see `logChainError` / `isUserRejectionError`).
|
|
233
|
+
// Scope is deliberately narrow: only categories that are noise in EVERY
|
|
234
|
+
// code path. Generic contract reverts (`CALL_EXCEPTION` / "missing revert
|
|
235
|
+
// data") are intentionally NOT listed — a reverted *write* tx is a real
|
|
236
|
+
// error we keep at `error` level, and only read-path reverts are demoted
|
|
237
|
+
// (surgically, at the call site).
|
|
238
|
+
ignoreErrors: [
|
|
239
|
+
// Wallet user-rejections are normal product behaviour, not an SDK fault.
|
|
240
|
+
/user rejected/i,
|
|
241
|
+
/user denied/i,
|
|
242
|
+
'ACTION_REJECTED',
|
|
243
|
+
// Local dev/test node leaking into a prod DSN: :8545 is the canonical
|
|
244
|
+
// Anvil/Hardhat port and is never a production RPC endpoint.
|
|
245
|
+
/ECONNREFUSED .*:8545/,
|
|
246
|
+
],
|
|
228
247
|
beforeSend(event) {
|
|
229
248
|
// Only send events tagged as SDK-related
|
|
230
249
|
if (event.tags?.sdk !== 'august-digital') {
|
|
@@ -233,7 +252,14 @@ function initializeSentry(config, environment, walletAddress, apiKey, appName) {
|
|
|
233
252
|
return event;
|
|
234
253
|
},
|
|
235
254
|
beforeSendTransaction(transaction) {
|
|
236
|
-
//
|
|
255
|
+
// Sub-sample the high-frequency network bookkeeping category (switchNetwork,
|
|
256
|
+
// updateWallet, clearWallet, setSigner) to 10% of whatever tracesSampleRate
|
|
257
|
+
// already passed — these fire on every wallet/chain update and are low signal
|
|
258
|
+
// for the partner-usage dashboard relative to read/write calls.
|
|
259
|
+
if (transaction.tags?.['sdk.category'] === 'network' &&
|
|
260
|
+
Math.random() > 0.1) {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
237
263
|
return transaction;
|
|
238
264
|
},
|
|
239
265
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IEnv } from '../../types';
|
|
2
|
-
import { IUserIdentity } from './types';
|
|
1
|
+
import type { IEnv } from '../../types';
|
|
2
|
+
import type { IUserIdentity } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Mask an API key, keeping only the last 5 characters visible.
|
|
5
5
|
* Example: "abcdefghij12345" -> "**********12345"
|
|
@@ -95,7 +95,7 @@ function generateFingerprint() {
|
|
|
95
95
|
* @returns User identity object
|
|
96
96
|
*/
|
|
97
97
|
function createUserIdentity(apiKey, walletAddress, environment = 'PROD') {
|
|
98
|
-
let domain
|
|
98
|
+
let domain;
|
|
99
99
|
try {
|
|
100
100
|
if (typeof window !== 'undefined' && window.location) {
|
|
101
101
|
domain = window.location.hostname;
|
package/lib/core/base.class.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ISolanaConfig, IAddress, IChainId, IEnv, IProvidersConfig, IWSMonitorHeaders } from '../types';
|
|
2
|
-
import { IAnalyticsConfig } from './analytics';
|
|
3
|
-
import { IVersionCheckConfig } from './version-check';
|
|
1
|
+
import type { ISolanaConfig, IAddress, IChainId, IEnv, IProvidersConfig, IWSMonitorHeaders } from '../types';
|
|
2
|
+
import { type IAnalyticsConfig } from './analytics';
|
|
3
|
+
import { type IVersionCheckConfig } from './version-check';
|
|
4
4
|
interface IKeys {
|
|
5
5
|
august?: string;
|
|
6
6
|
graph?: string;
|
package/lib/core/base.class.js
CHANGED
|
@@ -38,6 +38,16 @@ function validateAppName(value) {
|
|
|
38
38
|
* network switching, and authentication state.
|
|
39
39
|
*/
|
|
40
40
|
class AugustBase {
|
|
41
|
+
keys;
|
|
42
|
+
monitoring = {
|
|
43
|
+
'x-user-id': undefined,
|
|
44
|
+
'x-environment': undefined,
|
|
45
|
+
};
|
|
46
|
+
authorized;
|
|
47
|
+
activeNetwork;
|
|
48
|
+
providers;
|
|
49
|
+
/** Validated app-name slug from the constructor. */
|
|
50
|
+
appName;
|
|
41
51
|
/**
|
|
42
52
|
* Initialize base SDK with provider configuration and API keys.
|
|
43
53
|
* Sets up the first provider as the active network by default.
|
|
@@ -46,10 +56,6 @@ class AugustBase {
|
|
|
46
56
|
* length range — see {@link IAugustBase.appName}.
|
|
47
57
|
*/
|
|
48
58
|
constructor({ appName, providers = {}, keys, monitoring, analytics, versionCheck, timeoutMs, }) {
|
|
49
|
-
this.monitoring = {
|
|
50
|
-
'x-user-id': undefined,
|
|
51
|
-
'x-environment': undefined,
|
|
52
|
-
};
|
|
53
59
|
// Validate first so the failure mode is a clear, actionable error before
|
|
54
60
|
// any provider / analytics side effects run.
|
|
55
61
|
this.appName = validateAppName(appName);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* This file contains configurations for vaults that support deposits with alternative tokens
|
|
5
5
|
* through wrapper contracts, swap adapters, or native token deposits.
|
|
6
6
|
*/
|
|
7
|
-
import { IVaultAdapterConfig, IAddress } from '../../types';
|
|
7
|
+
import type { IVaultAdapterConfig, IAddress } from '../../types';
|
|
8
8
|
/**
|
|
9
9
|
* Pool/Vault names for adapter routing
|
|
10
10
|
*/
|
|
@@ -70,6 +70,8 @@ export declare const WEBSERVER_ENDPOINTS: {
|
|
|
70
70
|
summary: (vaultAddress: IAddress) => string;
|
|
71
71
|
withdrawals: (chain: string, vaultAddress: IAddress) => string;
|
|
72
72
|
debank: (vaultAddress: IAddress) => string;
|
|
73
|
+
userHistory: (vaultAddress: IAddress, wallet: IAddress) => string;
|
|
74
|
+
archivedVaults: string;
|
|
73
75
|
};
|
|
74
76
|
points: {
|
|
75
77
|
byUserAddress: (userAddress: IAddress) => string;
|
|
@@ -73,6 +73,12 @@ exports.WEBSERVER_ENDPOINTS = {
|
|
|
73
73
|
summary: (vaultAddress) => `/tokenized_vault/vault_summary/${(0, ethers_1.getAddress)(vaultAddress)}`,
|
|
74
74
|
withdrawals: (chain, vaultAddress) => `/withdrawals/${chain}/${(0, ethers_1.getAddress)(vaultAddress)}`,
|
|
75
75
|
debank: (vaultAddress) => `/tokenized_vault/${(0, ethers_1.getAddress)(vaultAddress)}/debank`,
|
|
76
|
+
// Mongo-backed deposit/withdraw history for archived vaults whose
|
|
77
|
+
// subgraph has been (or will be) retired. See fetchArchivedVaults.
|
|
78
|
+
userHistory: (vaultAddress, wallet) => `/upshift/vault_history/${(0, ethers_1.getAddress)(vaultAddress)}?wallet=${(0, ethers_1.getAddress)(wallet)}`,
|
|
79
|
+
// Vaults whose history is served from the snapshot (source of truth for
|
|
80
|
+
// routing — a vault appears only after its backfill completes).
|
|
81
|
+
archivedVaults: '/upshift/vault_history/archived',
|
|
76
82
|
},
|
|
77
83
|
points: {
|
|
78
84
|
byUserAddress: (userAddress) => `/upshift/points/${(0, ethers_1.getAddress)(userAddress)}`,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IAddress } from '../../types';
|
|
1
|
+
import type { IAddress } from '../../types';
|
|
2
2
|
/**
|
|
3
3
|
* Address of the `SwapRouter` periphery contract on each supported chain.
|
|
4
4
|
*
|
|
@@ -52,3 +52,39 @@ export declare const SWAP_ROUTER_MAX_SWAPS = 9;
|
|
|
52
52
|
* the contract's `depositNativeToken` / `swapAndDepositNativeToken` accept.
|
|
53
53
|
*/
|
|
54
54
|
export declare const SWAP_ROUTER_WRAPPED_NATIVE: Readonly<Record<number, IAddress>>;
|
|
55
|
+
/**
|
|
56
|
+
* The DEX aggregator whitelisted on each chain's `SwapRouter` via
|
|
57
|
+
* `enableRouter`, plus the single aggregator contract method every swap leg is
|
|
58
|
+
* pinned to and that method's 4-byte selector.
|
|
59
|
+
*
|
|
60
|
+
* This is the single source of truth tying the off-chain swap-leg builder to
|
|
61
|
+
* the on-chain router whitelist. The two MUST agree or `swapAndDeposit` reverts
|
|
62
|
+
* with `InvalidRouter()` (router not whitelisted) or `InvalidNotWhitelisted()`
|
|
63
|
+
* (selector not authorized). It is consumed in three places:
|
|
64
|
+
*
|
|
65
|
+
* - `dispatchViaSwapRouter` asks {@link fetchSwapQuote} to pin the aggregator to
|
|
66
|
+
* `contractMethod`, then asserts the returned quote's `router` and payload
|
|
67
|
+
* selector match this entry before broadcasting — failing closed rather than
|
|
68
|
+
* letting the user pay gas for a transaction the contract will reject.
|
|
69
|
+
* - The CI check `scripts/verify-swap-router-aggregator.mjs` asserts the
|
|
70
|
+
* deployed `SwapRouter` actually has `tokenTransferProxies[router] != 0` and
|
|
71
|
+
* `isAuthorizedSelector(router, selector) == true` for every entry here, so
|
|
72
|
+
* config drift is caught at release time, not by a user's failed deposit.
|
|
73
|
+
*
|
|
74
|
+
* Pinning to one generic method matters: the aggregator otherwise picks a route
|
|
75
|
+
* method per quote (e.g. a direct `swapExactAmountInOnUniswapV3`) that varies
|
|
76
|
+
* with market conditions, producing a different selector each time. Pinning
|
|
77
|
+
* collapses that to one stable selector so the on-chain whitelist needs only
|
|
78
|
+
* that selector and never drifts as routing changes.
|
|
79
|
+
*
|
|
80
|
+
* `router` is the address the aggregator's calldata targets (ParaSwap v6.2
|
|
81
|
+
* pulls tokens to the Augustus contract itself, so the SwapRouter's
|
|
82
|
+
* `tokenTransferProxies[router]` is the router address). `selector` is
|
|
83
|
+
* `bytes4(keccak256("<contractMethod>(...)"))`. Verify both against the
|
|
84
|
+
* deployed router before adding a chain — a wrong value reverts at deposit time.
|
|
85
|
+
*/
|
|
86
|
+
export declare const SWAP_ROUTER_DEX_AGGREGATOR: Readonly<Record<number, {
|
|
87
|
+
router: IAddress;
|
|
88
|
+
contractMethod: string;
|
|
89
|
+
selector: `0x${string}`;
|
|
90
|
+
}>>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SWAP_ROUTER_WRAPPED_NATIVE = exports.SWAP_ROUTER_MAX_SWAPS = exports.ORIGIN_CODES = exports.VAULTS_USING_SWAP_ROUTER = exports.SWAP_ROUTER_ADDRESSES = void 0;
|
|
3
|
+
exports.SWAP_ROUTER_DEX_AGGREGATOR = exports.SWAP_ROUTER_WRAPPED_NATIVE = exports.SWAP_ROUTER_MAX_SWAPS = exports.ORIGIN_CODES = exports.VAULTS_USING_SWAP_ROUTER = exports.SWAP_ROUTER_ADDRESSES = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Address of the `SwapRouter` periphery contract on each supported chain.
|
|
6
6
|
*
|
|
@@ -65,4 +65,44 @@ exports.SWAP_ROUTER_MAX_SWAPS = 9;
|
|
|
65
65
|
exports.SWAP_ROUTER_WRAPPED_NATIVE = {
|
|
66
66
|
1: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
|
|
67
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* The DEX aggregator whitelisted on each chain's `SwapRouter` via
|
|
70
|
+
* `enableRouter`, plus the single aggregator contract method every swap leg is
|
|
71
|
+
* pinned to and that method's 4-byte selector.
|
|
72
|
+
*
|
|
73
|
+
* This is the single source of truth tying the off-chain swap-leg builder to
|
|
74
|
+
* the on-chain router whitelist. The two MUST agree or `swapAndDeposit` reverts
|
|
75
|
+
* with `InvalidRouter()` (router not whitelisted) or `InvalidNotWhitelisted()`
|
|
76
|
+
* (selector not authorized). It is consumed in three places:
|
|
77
|
+
*
|
|
78
|
+
* - `dispatchViaSwapRouter` asks {@link fetchSwapQuote} to pin the aggregator to
|
|
79
|
+
* `contractMethod`, then asserts the returned quote's `router` and payload
|
|
80
|
+
* selector match this entry before broadcasting — failing closed rather than
|
|
81
|
+
* letting the user pay gas for a transaction the contract will reject.
|
|
82
|
+
* - The CI check `scripts/verify-swap-router-aggregator.mjs` asserts the
|
|
83
|
+
* deployed `SwapRouter` actually has `tokenTransferProxies[router] != 0` and
|
|
84
|
+
* `isAuthorizedSelector(router, selector) == true` for every entry here, so
|
|
85
|
+
* config drift is caught at release time, not by a user's failed deposit.
|
|
86
|
+
*
|
|
87
|
+
* Pinning to one generic method matters: the aggregator otherwise picks a route
|
|
88
|
+
* method per quote (e.g. a direct `swapExactAmountInOnUniswapV3`) that varies
|
|
89
|
+
* with market conditions, producing a different selector each time. Pinning
|
|
90
|
+
* collapses that to one stable selector so the on-chain whitelist needs only
|
|
91
|
+
* that selector and never drifts as routing changes.
|
|
92
|
+
*
|
|
93
|
+
* `router` is the address the aggregator's calldata targets (ParaSwap v6.2
|
|
94
|
+
* pulls tokens to the Augustus contract itself, so the SwapRouter's
|
|
95
|
+
* `tokenTransferProxies[router]` is the router address). `selector` is
|
|
96
|
+
* `bytes4(keccak256("<contractMethod>(...)"))`. Verify both against the
|
|
97
|
+
* deployed router before adding a chain — a wrong value reverts at deposit time.
|
|
98
|
+
*/
|
|
99
|
+
exports.SWAP_ROUTER_DEX_AGGREGATOR = {
|
|
100
|
+
// ParaSwap AugustusV6.2 (Velora). `swapExactAmountIn` is the generic
|
|
101
|
+
// executor method; its selector is 0xe3ead59e.
|
|
102
|
+
1: {
|
|
103
|
+
router: '0x6A000F20005980200259B80c5102003040001068',
|
|
104
|
+
contractMethod: 'swapExactAmountIn',
|
|
105
|
+
selector: '0xe3ead59e',
|
|
106
|
+
},
|
|
107
|
+
};
|
|
68
108
|
//# sourceMappingURL=swap-router.js.map
|
|
@@ -145,8 +145,5 @@ exports.FALLBACK_RPC_URLS = {
|
|
|
145
145
|
747474: ['https://rpc.katana.network'],
|
|
146
146
|
4114: ['https://rpc.mainnet.citrea.xyz'],
|
|
147
147
|
25363: ['https://rpc.fluent.xyz'],
|
|
148
|
-
// [-1]: [
|
|
149
|
-
// "https://devnet.helius-rpc.com/?api-key=5f652958-74ed-42e4-a874-0ac8056ac02c"
|
|
150
|
-
// ]
|
|
151
148
|
};
|
|
152
149
|
//# sourceMappingURL=web3.js.map
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
/** Stable error codes attached to SDK errors. */
|
|
18
|
-
export type AugustErrorCode = 'AUTH_MISSING_KEY' | 'AUTH_INVALID_KEY' | 'AUTH_FORBIDDEN' | 'AUTH_UNAUTHORIZED' | 'INVALID_URL' | 'INVALID_INPUT' | 'INVALID_CHAIN' | 'INVALID_ADDRESS' | 'NETWORK_ERROR' | 'TIMEOUT' | 'RATE_LIMITED' | 'SERVER_ERROR' | 'UNKNOWN';
|
|
18
|
+
export type AugustErrorCode = 'AUTH_MISSING_KEY' | 'AUTH_INVALID_KEY' | 'AUTH_FORBIDDEN' | 'AUTH_UNAUTHORIZED' | 'INVALID_URL' | 'INVALID_INPUT' | 'INVALID_CHAIN' | 'INVALID_ADDRESS' | 'ACCOUNT_NOT_FUNDED' | 'NETWORK_ERROR' | 'TIMEOUT' | 'RATE_LIMITED' | 'SERVER_ERROR' | 'UNKNOWN';
|
|
19
19
|
/** Options accepted by every SDK error constructor. */
|
|
20
20
|
export interface AugustErrorOptions {
|
|
21
21
|
/** Original error preserved for stack-trace chaining. */
|
|
@@ -54,7 +54,7 @@ export declare class AugustTimeoutError extends AugustSDKError {
|
|
|
54
54
|
}
|
|
55
55
|
/** Caller-side input failed validation. */
|
|
56
56
|
export declare class AugustValidationError extends AugustSDKError {
|
|
57
|
-
constructor(code: Extract<AugustErrorCode, 'INVALID_URL' | 'INVALID_INPUT' | 'INVALID_CHAIN' | 'INVALID_ADDRESS'>, message: string, options?: AugustErrorOptions);
|
|
57
|
+
constructor(code: Extract<AugustErrorCode, 'INVALID_URL' | 'INVALID_INPUT' | 'INVALID_CHAIN' | 'INVALID_ADDRESS' | 'ACCOUNT_NOT_FUNDED'>, message: string, options?: AugustErrorOptions);
|
|
58
58
|
}
|
|
59
59
|
/** Backend rate-limited the request (HTTP 429 or equivalent). */
|
|
60
60
|
export declare class AugustRateLimitError extends AugustSDKError {
|
package/lib/core/errors/index.js
CHANGED
|
@@ -20,6 +20,9 @@ exports.AugustServerError = exports.AugustRateLimitError = exports.AugustValidat
|
|
|
20
20
|
exports.isAugustSDKError = isAugustSDKError;
|
|
21
21
|
/** Base class for all SDK errors. */
|
|
22
22
|
class AugustSDKError extends Error {
|
|
23
|
+
code;
|
|
24
|
+
correlationId;
|
|
25
|
+
context;
|
|
23
26
|
constructor(code, message, options = {}) {
|
|
24
27
|
super(message);
|
|
25
28
|
this.name = 'AugustSDKError';
|
|
@@ -77,6 +80,8 @@ class AugustNetworkError extends AugustSDKError {
|
|
|
77
80
|
exports.AugustNetworkError = AugustNetworkError;
|
|
78
81
|
/** Request exceeded its deadline. */
|
|
79
82
|
class AugustTimeoutError extends AugustSDKError {
|
|
83
|
+
/** Time elapsed (ms) before the request was aborted. */
|
|
84
|
+
timeoutMs;
|
|
80
85
|
constructor(message, timeoutMs, options) {
|
|
81
86
|
super('TIMEOUT', message, options);
|
|
82
87
|
this.name = 'AugustTimeoutError';
|
|
@@ -97,6 +102,8 @@ class AugustValidationError extends AugustSDKError {
|
|
|
97
102
|
exports.AugustValidationError = AugustValidationError;
|
|
98
103
|
/** Backend rate-limited the request (HTTP 429 or equivalent). */
|
|
99
104
|
class AugustRateLimitError extends AugustSDKError {
|
|
105
|
+
/** Suggested wait before retrying, in milliseconds. */
|
|
106
|
+
retryAfterMs;
|
|
100
107
|
constructor(message, options) {
|
|
101
108
|
super('RATE_LIMITED', message, options);
|
|
102
109
|
this.name = 'AugustRateLimitError';
|
|
@@ -112,6 +119,8 @@ class AugustRateLimitError extends AugustSDKError {
|
|
|
112
119
|
exports.AugustRateLimitError = AugustRateLimitError;
|
|
113
120
|
/** Backend returned a non-OK status that isn't auth, rate-limit, or timeout. */
|
|
114
121
|
class AugustServerError extends AugustSDKError {
|
|
122
|
+
/** HTTP status code returned by the backend. */
|
|
123
|
+
status;
|
|
115
124
|
constructor(status, message, options) {
|
|
116
125
|
super('SERVER_ERROR', message, options);
|
|
117
126
|
this.name = 'AugustServerError';
|