@augustdigital/sdk 9.5.0 → 9.7.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 +1 -1
- package/lib/adapters/evm/index.d.ts +1 -1
- package/lib/adapters/evm/index.js +29 -29
- package/lib/adapters/solana/types.d.ts +8 -0
- package/lib/adapters/solana/vault.actions.d.ts +6 -1
- package/lib/adapters/solana/vault.actions.js +99 -21
- package/lib/core/analytics/app-name.js +1 -1
- package/lib/core/analytics/constants.d.ts +10 -0
- package/lib/core/analytics/constants.js +17 -1
- package/lib/core/analytics/index.d.ts +7 -4
- package/lib/core/analytics/index.js +8 -4
- package/lib/core/analytics/instrumentation.js +8 -4
- package/lib/core/analytics/method-taxonomy.js +13 -0
- package/lib/core/analytics/metrics.d.ts +25 -10
- package/lib/core/analytics/metrics.js +41 -15
- package/lib/core/analytics/sentry.d.ts +24 -3
- package/lib/core/analytics/sentry.js +49 -18
- package/lib/core/analytics/types.d.ts +11 -4
- package/lib/core/analytics/user-identity.d.ts +19 -5
- package/lib/core/analytics/user-identity.js +35 -21
- package/lib/core/analytics/version.d.ts +1 -1
- package/lib/core/analytics/version.js +1 -1
- package/lib/core/auth/verify.js +7 -3
- package/lib/core/base.class.d.ts +8 -1
- package/lib/core/base.class.js +7 -1
- package/lib/core/constants/core.d.ts +3 -0
- package/lib/core/constants/core.js +3 -0
- package/lib/core/constants/swap-router.d.ts +16 -0
- package/lib/core/constants/swap-router.js +16 -0
- package/lib/core/errors/index.d.ts +36 -1
- package/lib/core/errors/index.js +40 -1
- package/lib/core/fetcher.d.ts +24 -5
- package/lib/core/fetcher.js +43 -7
- package/lib/main.d.ts +6 -0
- package/lib/main.js +6 -0
- package/lib/modules/api/main.d.ts +6 -6
- package/lib/modules/api/main.js +6 -6
- package/lib/modules/sub-accounts/main.d.ts +7 -1
- package/lib/modules/sub-accounts/main.js +7 -1
- package/lib/modules/vaults/getters.d.ts +151 -10
- package/lib/modules/vaults/getters.js +226 -30
- package/lib/modules/vaults/main.d.ts +5 -0
- package/lib/modules/vaults/main.js +5 -0
- package/lib/modules/vaults/write.actions.d.ts +57 -1
- package/lib/modules/vaults/write.actions.js +86 -2
- package/lib/sdk.d.ts +13171 -12810
- package/lib/services/debank/fetcher.js +1 -1
- package/lib/services/subgraph/vaults.d.ts +18 -1
- package/lib/services/subgraph/vaults.js +19 -3
- package/lib/types/vaults.d.ts +5 -0
- package/package.json +2 -2
|
@@ -64,6 +64,7 @@ exports.METHOD_CATEGORIES = {
|
|
|
64
64
|
getVaultWithdrawals: 'read.redemption',
|
|
65
65
|
getWithdrawalRequestsWithStatus: 'read.redemption',
|
|
66
66
|
previewRedemption: 'read.redemption',
|
|
67
|
+
previewRwaRedemption: 'read.redemption',
|
|
67
68
|
getBurnableAmountByReceiver: 'read.redemption',
|
|
68
69
|
getRequirementByDate: 'read.redemption',
|
|
69
70
|
getScheduledTransactionsByDate: 'read.redemption',
|
|
@@ -94,6 +95,7 @@ exports.METHOD_CATEGORIES = {
|
|
|
94
95
|
// sees program-targeting calls instead of dropping them into 'unknown'.
|
|
95
96
|
getProgram: 'read.solana',
|
|
96
97
|
getProgramId: 'read.solana',
|
|
98
|
+
setWalletProvider: 'network',
|
|
97
99
|
// submitTransaction broadcasts a signed Soroban tx — it mutates on-chain
|
|
98
100
|
// state and belongs in the write bucket even though Stellar adapter call
|
|
99
101
|
// shape mirrors the read helpers (returns a hash, takes signed XDR).
|
|
@@ -102,8 +104,19 @@ exports.METHOD_CATEGORIES = {
|
|
|
102
104
|
// convertToShares is a read-only Soroban simulation despite its mutative-
|
|
103
105
|
// sounding name — runs through queryContract, no broadcast.
|
|
104
106
|
convertToShares: 'read.stellar',
|
|
107
|
+
// Offline helpers on the public adapter surface, classified under the
|
|
108
|
+
// chain's read bucket like getProgram/getProgramId above rather than
|
|
109
|
+
// leaking into 'unknown'.
|
|
110
|
+
isStellarAddress: 'read.stellar',
|
|
111
|
+
getExplorerLink: 'read.stellar',
|
|
105
112
|
getEmberVaults: 'read.sui',
|
|
106
113
|
getEmberTVL: 'read.sui',
|
|
114
|
+
convertFromE9: 'read.sui',
|
|
115
|
+
calculateUtilization: 'read.sui',
|
|
116
|
+
isSuiAddress: 'read.sui',
|
|
117
|
+
isSuiVault: 'read.sui',
|
|
118
|
+
transformEmberVaultToIVault: 'read.sui',
|
|
119
|
+
transformEmberVaultsToIVaults: 'read.sui',
|
|
107
120
|
vaultAllowance: 'read.evm',
|
|
108
121
|
sendersWhitelistAddress: 'read.evm',
|
|
109
122
|
isWhitelisted: 'read.evm',
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Aggregated cache statistics for monitoring.
|
|
3
|
-
*/
|
|
4
|
-
declare let cacheStats: {
|
|
5
|
-
hits: number;
|
|
6
|
-
misses: number;
|
|
7
|
-
sets: number;
|
|
8
|
-
};
|
|
9
1
|
/**
|
|
10
2
|
* Track API response times and status.
|
|
11
3
|
*
|
|
@@ -23,11 +15,34 @@ export declare function trackApiCall(endpoint: string, method: string, startTime
|
|
|
23
15
|
*/
|
|
24
16
|
export declare function trackNetworkSwitch(chainId: number): void;
|
|
25
17
|
/**
|
|
26
|
-
*
|
|
18
|
+
* Track the outcome of an API-key verification check (e.g. `verifyAugustKey`).
|
|
19
|
+
* Records success/failure as a breadcrumb and a low-cardinality tag so
|
|
20
|
+
* verification failures are visible in the dashboard without leaking the key
|
|
21
|
+
* itself — callers must never pass the raw key value.
|
|
22
|
+
*
|
|
23
|
+
* @param keyType - Which key was verified (e.g. `'august'`)
|
|
24
|
+
* @param success - Whether the key was accepted
|
|
25
|
+
*/
|
|
26
|
+
export declare function trackKeyVerification(keyType: string, success: boolean): void;
|
|
27
|
+
declare let cacheStats: {
|
|
28
|
+
hits: number;
|
|
29
|
+
misses: number;
|
|
30
|
+
sets: number;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Cache statistics snapshot. The SDK never recorded cache hits, misses, or
|
|
34
|
+
* sets, so every field is always `0`.
|
|
35
|
+
*
|
|
36
|
+
* @deprecated Always returns zeros. Kept only for API compatibility and will
|
|
37
|
+
* be removed in the next major release; there is no replacement.
|
|
27
38
|
*/
|
|
28
39
|
export declare function getCacheStats(): typeof cacheStats;
|
|
29
40
|
/**
|
|
30
|
-
* Reset cache statistics
|
|
41
|
+
* Reset the cache statistics snapshot to zeros. The SDK never records any, so
|
|
42
|
+
* this has no observable effect.
|
|
43
|
+
*
|
|
44
|
+
* @deprecated Has no effect. Kept only for API compatibility and will be
|
|
45
|
+
* removed in the next major release; there is no replacement.
|
|
31
46
|
*/
|
|
32
47
|
export declare function resetCacheStats(): void;
|
|
33
48
|
export {};
|
|
@@ -2,19 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.trackApiCall = trackApiCall;
|
|
4
4
|
exports.trackNetworkSwitch = trackNetworkSwitch;
|
|
5
|
+
exports.trackKeyVerification = trackKeyVerification;
|
|
5
6
|
exports.getCacheStats = getCacheStats;
|
|
6
7
|
exports.resetCacheStats = resetCacheStats;
|
|
7
8
|
const chain_name_1 = require("./chain-name");
|
|
8
9
|
const sentry_runtime_1 = require("./sentry-runtime");
|
|
9
10
|
const sentry_1 = require("./sentry");
|
|
10
|
-
/**
|
|
11
|
-
* Aggregated cache statistics for monitoring.
|
|
12
|
-
*/
|
|
13
|
-
let cacheStats = {
|
|
14
|
-
hits: 0,
|
|
15
|
-
misses: 0,
|
|
16
|
-
sets: 0,
|
|
17
|
-
};
|
|
18
11
|
/**
|
|
19
12
|
* Track API response times and status.
|
|
20
13
|
*
|
|
@@ -47,11 +40,7 @@ function trackApiCall(endpoint, method, startTime, status, server) {
|
|
|
47
40
|
server,
|
|
48
41
|
},
|
|
49
42
|
});
|
|
50
|
-
// Set measurement for performance tracking
|
|
51
43
|
sdk.setMeasurement('api.duration', duration, 'millisecond');
|
|
52
|
-
// Update tags for filtering
|
|
53
|
-
sdk.setTag('api.last_endpoint', normalizedEndpoint);
|
|
54
|
-
sdk.setTag('api.server', server);
|
|
55
44
|
}
|
|
56
45
|
catch {
|
|
57
46
|
// Silently fail - analytics should never break SDK
|
|
@@ -76,13 +65,41 @@ function trackNetworkSwitch(chainId) {
|
|
|
76
65
|
level: 'info',
|
|
77
66
|
data: { chainId, chain: chainLabel },
|
|
78
67
|
});
|
|
79
|
-
sdk.setTag('active.chainId', chainId.toString());
|
|
80
68
|
sdk.setTag('sdk.chain', chainLabel);
|
|
81
69
|
}
|
|
82
70
|
catch {
|
|
83
71
|
// Silently fail - analytics should never break SDK
|
|
84
72
|
}
|
|
85
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Track the outcome of an API-key verification check (e.g. `verifyAugustKey`).
|
|
76
|
+
* Records success/failure as a breadcrumb and a low-cardinality tag so
|
|
77
|
+
* verification failures are visible in the dashboard without leaking the key
|
|
78
|
+
* itself — callers must never pass the raw key value.
|
|
79
|
+
*
|
|
80
|
+
* @param keyType - Which key was verified (e.g. `'august'`)
|
|
81
|
+
* @param success - Whether the key was accepted
|
|
82
|
+
*/
|
|
83
|
+
function trackKeyVerification(keyType, success) {
|
|
84
|
+
if (!(0, sentry_1.isAnalyticsEnabled)())
|
|
85
|
+
return;
|
|
86
|
+
try {
|
|
87
|
+
const sdk = (0, sentry_runtime_1.getSentrySDK)();
|
|
88
|
+
if (!sdk)
|
|
89
|
+
return;
|
|
90
|
+
sdk.addBreadcrumb({
|
|
91
|
+
category: 'auth.verify',
|
|
92
|
+
message: `${keyType} key verification ${success ? 'succeeded' : 'failed'}`,
|
|
93
|
+
level: success ? 'info' : 'warning',
|
|
94
|
+
data: { keyType, success },
|
|
95
|
+
});
|
|
96
|
+
sdk.setTag('auth.last_verified_key_type', keyType);
|
|
97
|
+
sdk.setTag('auth.last_verification_result', success ? 'success' : 'failure');
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Silently fail - analytics should never break SDK
|
|
101
|
+
}
|
|
102
|
+
}
|
|
86
103
|
/**
|
|
87
104
|
* Normalize endpoint URLs for aggregation.
|
|
88
105
|
* Replaces dynamic segments (addresses, IDs) with placeholders.
|
|
@@ -101,14 +118,23 @@ function normalizeEndpoint(endpoint) {
|
|
|
101
118
|
// Replace numeric IDs in paths
|
|
102
119
|
.replace(/\/\d+(?=\/|$)/g, '/:id'));
|
|
103
120
|
}
|
|
121
|
+
let cacheStats = { hits: 0, misses: 0, sets: 0 };
|
|
104
122
|
/**
|
|
105
|
-
*
|
|
123
|
+
* Cache statistics snapshot. The SDK never recorded cache hits, misses, or
|
|
124
|
+
* sets, so every field is always `0`.
|
|
125
|
+
*
|
|
126
|
+
* @deprecated Always returns zeros. Kept only for API compatibility and will
|
|
127
|
+
* be removed in the next major release; there is no replacement.
|
|
106
128
|
*/
|
|
107
129
|
function getCacheStats() {
|
|
108
130
|
return { ...cacheStats };
|
|
109
131
|
}
|
|
110
132
|
/**
|
|
111
|
-
* Reset cache statistics
|
|
133
|
+
* Reset the cache statistics snapshot to zeros. The SDK never records any, so
|
|
134
|
+
* this has no observable effect.
|
|
135
|
+
*
|
|
136
|
+
* @deprecated Has no effect. Kept only for API compatibility and will be
|
|
137
|
+
* removed in the next major release; there is no replacement.
|
|
112
138
|
*/
|
|
113
139
|
function resetCacheStats() {
|
|
114
140
|
cacheStats = { hits: 0, misses: 0, sets: 0 };
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import type * as Sentry from '@sentry/browser';
|
|
2
2
|
import type { IEnv } from '../../types';
|
|
3
3
|
import type { IAnalyticsConfig } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* The August SDK build version, read from the generated `version.ts`.
|
|
6
|
+
* Falls back to `'development'` in an unbuilt checkout, where that file does
|
|
7
|
+
* not exist. Shared by the Sentry `release` tag and the
|
|
8
|
+
* `x-august-sdk-version` request header so the two can never disagree.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare function getSDKVersion(): string;
|
|
4
13
|
/**
|
|
5
14
|
* Clear the error dedupe bookkeeping. Test-only — the rate limiter is process
|
|
6
15
|
* lifetime state and would otherwise leak between test cases.
|
|
@@ -19,7 +28,8 @@ export declare function resetErrorDedupe(): void;
|
|
|
19
28
|
* error rather than silently anonymous events.
|
|
20
29
|
*
|
|
21
30
|
* @param config - Analytics configuration. Pass `tracesSampleRate` to
|
|
22
|
-
* override the default of `0.1
|
|
31
|
+
* override the default of `0.1`, and `surface` to label the emitting
|
|
32
|
+
* surface (`sdk.surface` tag; defaults to `'sdk'`).
|
|
23
33
|
* @param environment - Current environment (DEV or PROD).
|
|
24
34
|
* @param appName - App-name slug, required. Set as the global `app.name`
|
|
25
35
|
* tag on every event and used to derive `partner.id`. Identifier-shaped:
|
|
@@ -51,6 +61,16 @@ export declare function clearUser(): void;
|
|
|
51
61
|
* Check if analytics is enabled and initialized.
|
|
52
62
|
*/
|
|
53
63
|
export declare function isAnalyticsEnabled(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Identity tags resolved by `initializeSentry`, for `withMethodTracking` to
|
|
66
|
+
* copy onto each span as attributes. Sentry's span dataset carries scope tags
|
|
67
|
+
* on the root span only, so without this copy child `sdk.method` rows cannot
|
|
68
|
+
* be filtered by `app.name` or `partner.id`.
|
|
69
|
+
*
|
|
70
|
+
* @returns The tag snapshot, or `{}` until analytics has been enabled.
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
73
|
+
export declare function getSpanAttributes(): Readonly<Record<string, string>>;
|
|
54
74
|
/**
|
|
55
75
|
* Get the current Sentry instance for advanced usage.
|
|
56
76
|
* Returns null if analytics is disabled.
|
|
@@ -67,12 +87,13 @@ export declare function resetAnalytics(): void;
|
|
|
67
87
|
* surface. No-ops when analytics is disabled.
|
|
68
88
|
*
|
|
69
89
|
* @param error - Thrown value. Non-Error values are wrapped.
|
|
70
|
-
* @param options - `surface` ('cli' | 'sdk' | 'react' | string)
|
|
90
|
+
* @param options - `surface` ('cli' | 'mcp' | 'sdk' | 'react' | string)
|
|
91
|
+
* overriding the init-time `sdk.surface` tag for this event, extra `tags`,
|
|
71
92
|
* `extra` data, and a `flushTimeoutMs` to await before resolving (needed
|
|
72
93
|
* in Node when the process is about to exit).
|
|
73
94
|
*/
|
|
74
95
|
export declare function captureSdkException(error: unknown, options?: {
|
|
75
|
-
surface?: 'cli' | 'sdk' | 'react' | string;
|
|
96
|
+
surface?: 'cli' | 'mcp' | 'sdk' | 'react' | string;
|
|
76
97
|
tags?: Record<string, string>;
|
|
77
98
|
extra?: Record<string, unknown>;
|
|
78
99
|
flushTimeoutMs?: number;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSDKVersion = getSDKVersion;
|
|
3
4
|
exports.resetErrorDedupe = resetErrorDedupe;
|
|
4
5
|
exports.initializeSentry = initializeSentry;
|
|
5
6
|
exports.updateUser = updateUser;
|
|
6
7
|
exports.clearUser = clearUser;
|
|
7
8
|
exports.isAnalyticsEnabled = isAnalyticsEnabled;
|
|
9
|
+
exports.getSpanAttributes = getSpanAttributes;
|
|
8
10
|
exports.getSentry = getSentry;
|
|
9
11
|
exports.resetAnalytics = resetAnalytics;
|
|
10
12
|
exports.captureSdkException = captureSdkException;
|
|
@@ -22,9 +24,15 @@ let isEnabled = true;
|
|
|
22
24
|
let currentIdentity = null;
|
|
23
25
|
/** Cached API key for identity updates */
|
|
24
26
|
let cachedApiKey;
|
|
27
|
+
/** Identity tags resolved at init, mirrored onto every `sdk.method` span. */
|
|
28
|
+
let spanAttributes = {};
|
|
25
29
|
/**
|
|
26
|
-
*
|
|
27
|
-
* Falls back to 'development'
|
|
30
|
+
* The August SDK build version, read from the generated `version.ts`.
|
|
31
|
+
* Falls back to `'development'` in an unbuilt checkout, where that file does
|
|
32
|
+
* not exist. Shared by the Sentry `release` tag and the
|
|
33
|
+
* `x-august-sdk-version` request header so the two can never disagree.
|
|
34
|
+
*
|
|
35
|
+
* @internal
|
|
28
36
|
*/
|
|
29
37
|
function getSDKVersion() {
|
|
30
38
|
try {
|
|
@@ -326,7 +334,8 @@ function createSentrySink() {
|
|
|
326
334
|
* error rather than silently anonymous events.
|
|
327
335
|
*
|
|
328
336
|
* @param config - Analytics configuration. Pass `tracesSampleRate` to
|
|
329
|
-
* override the default of `0.1
|
|
337
|
+
* override the default of `0.1`, and `surface` to label the emitting
|
|
338
|
+
* surface (`sdk.surface` tag; defaults to `'sdk'`).
|
|
330
339
|
* @param environment - Current environment (DEV or PROD).
|
|
331
340
|
* @param appName - App-name slug, required. Set as the global `app.name`
|
|
332
341
|
* tag on every event and used to derive `partner.id`. Identifier-shaped:
|
|
@@ -463,17 +472,6 @@ function initializeSentry(config, environment, appName, walletAddress, apiKey) {
|
|
|
463
472
|
}
|
|
464
473
|
return event;
|
|
465
474
|
},
|
|
466
|
-
beforeSendTransaction(transaction) {
|
|
467
|
-
// Sub-sample the high-frequency network bookkeeping category (switchNetwork,
|
|
468
|
-
// updateWallet, clearWallet, setSigner) to 10% of whatever tracesSampleRate
|
|
469
|
-
// already passed — these fire on every wallet/chain update and are low signal
|
|
470
|
-
// for the partner-usage dashboard relative to read/write calls.
|
|
471
|
-
if (transaction.tags?.['sdk.category'] === 'network' &&
|
|
472
|
-
Math.random() > 0.1) {
|
|
473
|
-
return null;
|
|
474
|
-
}
|
|
475
|
-
return transaction;
|
|
476
|
-
},
|
|
477
475
|
});
|
|
478
476
|
// Set initial user identity
|
|
479
477
|
updateUser(walletAddress, environment);
|
|
@@ -500,13 +498,32 @@ function initializeSentry(config, environment, appName, walletAddress, apiKey) {
|
|
|
500
498
|
* dashboards, and alert rules keep resolving; remove in the next major.
|
|
501
499
|
*/
|
|
502
500
|
safeSetTag('sdk.version', sdkVersion);
|
|
503
|
-
|
|
501
|
+
const runtime = (0, sentry_runtime_1.getSentryRuntime)();
|
|
502
|
+
safeSetTag('sdk.runtime', runtime);
|
|
504
503
|
// `app.name` is the dimension we filter on in Sentry to attribute
|
|
505
504
|
// events to a specific consuming application — see SDK quickstart docs.
|
|
506
505
|
safeSetTag('app.name', validatedAppName);
|
|
507
506
|
// `unverified:` prefix until the backend API-key → partner-id endpoint exists.
|
|
508
|
-
|
|
509
|
-
safeSetTag('partner.
|
|
507
|
+
const partnerId = `unverified:${validatedAppName}`;
|
|
508
|
+
safeSetTag('partner.id', partnerId);
|
|
509
|
+
// First-party apps are labelled so `partner.tier:unverified` already
|
|
510
|
+
// means "external integrator" before verification exists.
|
|
511
|
+
const partnerTier = constants_1.FIRST_PARTY_APP_NAMES.has(validatedAppName)
|
|
512
|
+
? 'internal'
|
|
513
|
+
: 'unverified';
|
|
514
|
+
safeSetTag('partner.tier', partnerTier);
|
|
515
|
+
const surface = config.surface ?? 'sdk';
|
|
516
|
+
safeSetTag('sdk.surface', surface);
|
|
517
|
+
// Scope tags land only on the root span of a trace; child `sdk.method`
|
|
518
|
+
// spans get these copied on as attributes by `withMethodTracking`.
|
|
519
|
+
spanAttributes = {
|
|
520
|
+
'app.name': validatedAppName,
|
|
521
|
+
'partner.id': partnerId,
|
|
522
|
+
'partner.tier': partnerTier,
|
|
523
|
+
'sdk.runtime': runtime,
|
|
524
|
+
'sdk.surface': surface,
|
|
525
|
+
'august.sdk_version': sdkVersion,
|
|
526
|
+
};
|
|
510
527
|
// Bridge the SDK's structured logger into Sentry now that the SDK is live.
|
|
511
528
|
// Without this, Logger.log.error/warn are no-ops in production (no
|
|
512
529
|
// SDKLogger/structured logger is wired by default), so SDK-internal
|
|
@@ -594,6 +611,18 @@ function clearUser() {
|
|
|
594
611
|
function isAnalyticsEnabled() {
|
|
595
612
|
return isEnabled && isInitialized;
|
|
596
613
|
}
|
|
614
|
+
/**
|
|
615
|
+
* Identity tags resolved by `initializeSentry`, for `withMethodTracking` to
|
|
616
|
+
* copy onto each span as attributes. Sentry's span dataset carries scope tags
|
|
617
|
+
* on the root span only, so without this copy child `sdk.method` rows cannot
|
|
618
|
+
* be filtered by `app.name` or `partner.id`.
|
|
619
|
+
*
|
|
620
|
+
* @returns The tag snapshot, or `{}` until analytics has been enabled.
|
|
621
|
+
* @internal
|
|
622
|
+
*/
|
|
623
|
+
function getSpanAttributes() {
|
|
624
|
+
return spanAttributes;
|
|
625
|
+
}
|
|
597
626
|
/**
|
|
598
627
|
* Get the current Sentry instance for advanced usage.
|
|
599
628
|
* Returns null if analytics is disabled.
|
|
@@ -611,6 +640,7 @@ function resetAnalytics() {
|
|
|
611
640
|
isEnabled = true;
|
|
612
641
|
currentIdentity = null;
|
|
613
642
|
cachedApiKey = undefined;
|
|
643
|
+
spanAttributes = {};
|
|
614
644
|
logger_1.Logger.setSentrySink(null);
|
|
615
645
|
(0, sentry_runtime_1.resetSentryRuntime)();
|
|
616
646
|
// The error rate limiter is process-lifetime state; a reset analytics layer
|
|
@@ -624,7 +654,8 @@ function resetAnalytics() {
|
|
|
624
654
|
* surface. No-ops when analytics is disabled.
|
|
625
655
|
*
|
|
626
656
|
* @param error - Thrown value. Non-Error values are wrapped.
|
|
627
|
-
* @param options - `surface` ('cli' | 'sdk' | 'react' | string)
|
|
657
|
+
* @param options - `surface` ('cli' | 'mcp' | 'sdk' | 'react' | string)
|
|
658
|
+
* overriding the init-time `sdk.surface` tag for this event, extra `tags`,
|
|
628
659
|
* `extra` data, and a `flushTimeoutMs` to await before resolving (needed
|
|
629
660
|
* in Node when the process is about to exit).
|
|
630
661
|
*/
|
|
@@ -7,17 +7,24 @@ export interface IAnalyticsConfig {
|
|
|
7
7
|
/** Set to false to disable analytics. Default: true */
|
|
8
8
|
enabled?: boolean;
|
|
9
9
|
/**
|
|
10
|
-
* Sentry trace sample rate. Defaults to `1
|
|
11
|
-
*
|
|
10
|
+
* Sentry trace sample rate. Defaults to `0.1`; values outside `[0, 1]`
|
|
11
|
+
* are clamped.
|
|
12
12
|
*/
|
|
13
13
|
tracesSampleRate?: number;
|
|
14
|
+
/**
|
|
15
|
+
* Which August surface is emitting telemetry, recorded once at init as the
|
|
16
|
+
* sticky `sdk.surface` tag on every event and span. The CLI passes `'cli'`
|
|
17
|
+
* and the MCP server `'mcp'`; applications embedding the SDK directly can
|
|
18
|
+
* leave the default `'sdk'`.
|
|
19
|
+
*/
|
|
20
|
+
surface?: 'sdk' | 'cli' | 'mcp' | 'react' | string;
|
|
14
21
|
}
|
|
15
22
|
/**
|
|
16
23
|
* User identity for analytics tracking.
|
|
17
|
-
* Multiple identifiers are used with priority: apiKeyHash
|
|
24
|
+
* Multiple identifiers are used with priority: apiKeyHash \> wallet \> domain \> fingerprint \> session
|
|
18
25
|
*/
|
|
19
26
|
export interface IUserIdentity {
|
|
20
|
-
/** SHA-256 hash
|
|
27
|
+
/** Hex-encoded SHA-256 hash of the API key. Never stores the raw key. */
|
|
21
28
|
apiKeyHash?: string;
|
|
22
29
|
/** User's wallet address (lowercased) */
|
|
23
30
|
walletAddress?: string;
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import type { IEnv } from '../../types';
|
|
2
2
|
import type { IUserIdentity } from './types';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* Example: "abcdefghij12345" -> "**********12345"
|
|
4
|
+
* Hash an API key with SHA-256 for use as a Sentry-safe identity token.
|
|
6
5
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Only the hash is ever returned. The most recently hashed key and its hash
|
|
7
|
+
* are cached in memory, so a repeat call skips the digest and a different key
|
|
8
|
+
* replaces the cache instead of returning the previous key's hash.
|
|
9
|
+
*
|
|
10
|
+
* When the runtime has no usable `crypto.createHash` (e.g. a browser bundle
|
|
11
|
+
* without a `crypto` shim) this returns `''` rather than throwing, so the
|
|
12
|
+
* Sentry identity falls back to the next identifier instead of being dropped.
|
|
13
|
+
*
|
|
14
|
+
* @param apiKey - The raw API key to hash
|
|
15
|
+
* @returns Hex-encoded SHA-256 hash of `apiKey`, or `''` for an empty input or
|
|
16
|
+
* when hashing is unavailable
|
|
9
17
|
*/
|
|
10
18
|
export declare function hashApiKey(apiKey: string): string;
|
|
11
19
|
/**
|
|
@@ -33,7 +41,13 @@ export declare function generateFingerprint(): string | undefined;
|
|
|
33
41
|
export declare function createUserIdentity(apiKey?: string, walletAddress?: string, environment?: IEnv): IUserIdentity;
|
|
34
42
|
/**
|
|
35
43
|
* Generate a unique user ID for Sentry from identity components.
|
|
36
|
-
* Priority: apiKeyHash
|
|
44
|
+
* Priority: apiKeyHash \> wallet \> domain \> fingerprint \> session
|
|
45
|
+
*
|
|
46
|
+
* An API key identifies the integrator and a wallet identifies the end user,
|
|
47
|
+
* so both outrank the hosting domain — otherwise every visitor of one web app
|
|
48
|
+
* collapses into a single Sentry user. `domain` still ranks above the
|
|
49
|
+
* fingerprint, which nearly every runtime produces, so hostname attribution
|
|
50
|
+
* is not lost.
|
|
37
51
|
*
|
|
38
52
|
* @param identity - User identity object
|
|
39
53
|
* @returns Prefixed user ID string
|
|
@@ -9,31 +9,39 @@ const crypto_1 = require("crypto");
|
|
|
9
9
|
const uuid_1 = require("uuid");
|
|
10
10
|
/** Session ID persists for SDK instance lifetime */
|
|
11
11
|
let sessionId = null;
|
|
12
|
-
/**
|
|
13
|
-
let
|
|
12
|
+
/** Raw API key the cached hash below was computed from — lets a key change invalidate the cache. */
|
|
13
|
+
let cachedApiKey = null;
|
|
14
|
+
/** SHA-256 hash of {@link cachedApiKey}. */
|
|
15
|
+
let cachedApiKeyHash = null;
|
|
14
16
|
/**
|
|
15
|
-
*
|
|
16
|
-
* Example: "abcdefghij12345" -> "**********12345"
|
|
17
|
+
* Hash an API key with SHA-256 for use as a Sentry-safe identity token.
|
|
17
18
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
19
|
+
* Only the hash is ever returned. The most recently hashed key and its hash
|
|
20
|
+
* are cached in memory, so a repeat call skips the digest and a different key
|
|
21
|
+
* replaces the cache instead of returning the previous key's hash.
|
|
22
|
+
*
|
|
23
|
+
* When the runtime has no usable `crypto.createHash` (e.g. a browser bundle
|
|
24
|
+
* without a `crypto` shim) this returns `''` rather than throwing, so the
|
|
25
|
+
* Sentry identity falls back to the next identifier instead of being dropped.
|
|
26
|
+
*
|
|
27
|
+
* @param apiKey - The raw API key to hash
|
|
28
|
+
* @returns Hex-encoded SHA-256 hash of `apiKey`, or `''` for an empty input or
|
|
29
|
+
* when hashing is unavailable
|
|
20
30
|
*/
|
|
21
31
|
function hashApiKey(apiKey) {
|
|
22
32
|
if (!apiKey)
|
|
23
33
|
return '';
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return cachedMaskedApiKey;
|
|
27
|
-
const visibleChars = 5;
|
|
28
|
-
if (apiKey.length <= visibleChars) {
|
|
29
|
-
cachedMaskedApiKey = apiKey;
|
|
34
|
+
if (cachedApiKey === apiKey && cachedApiKeyHash) {
|
|
35
|
+
return cachedApiKeyHash;
|
|
30
36
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
try {
|
|
38
|
+
cachedApiKeyHash = (0, crypto_1.createHash)('sha256').update(apiKey).digest('hex');
|
|
39
|
+
cachedApiKey = apiKey;
|
|
40
|
+
return cachedApiKeyHash;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return '';
|
|
35
44
|
}
|
|
36
|
-
return cachedMaskedApiKey;
|
|
37
45
|
}
|
|
38
46
|
/**
|
|
39
47
|
* Generate a session ID that persists for the SDK instance lifetime.
|
|
@@ -118,21 +126,27 @@ function createUserIdentity(apiKey, walletAddress, environment = 'PROD') {
|
|
|
118
126
|
}
|
|
119
127
|
/**
|
|
120
128
|
* Generate a unique user ID for Sentry from identity components.
|
|
121
|
-
* Priority: apiKeyHash
|
|
129
|
+
* Priority: apiKeyHash \> wallet \> domain \> fingerprint \> session
|
|
130
|
+
*
|
|
131
|
+
* An API key identifies the integrator and a wallet identifies the end user,
|
|
132
|
+
* so both outrank the hosting domain — otherwise every visitor of one web app
|
|
133
|
+
* collapses into a single Sentry user. `domain` still ranks above the
|
|
134
|
+
* fingerprint, which nearly every runtime produces, so hostname attribution
|
|
135
|
+
* is not lost.
|
|
122
136
|
*
|
|
123
137
|
* @param identity - User identity object
|
|
124
138
|
* @returns Prefixed user ID string
|
|
125
139
|
*/
|
|
126
140
|
function getUserId(identity) {
|
|
127
|
-
if (identity.domain) {
|
|
128
|
-
return `domain:${identity.domain}`;
|
|
129
|
-
}
|
|
130
141
|
if (identity.apiKeyHash) {
|
|
131
142
|
return `apikey:${identity.apiKeyHash}`;
|
|
132
143
|
}
|
|
133
144
|
if (identity.walletAddress) {
|
|
134
145
|
return `wallet:${identity.walletAddress}`;
|
|
135
146
|
}
|
|
147
|
+
if (identity.domain) {
|
|
148
|
+
return `domain:${identity.domain}`;
|
|
149
|
+
}
|
|
136
150
|
if (identity.fingerprint) {
|
|
137
151
|
return `fp:${identity.fingerprint}`;
|
|
138
152
|
}
|
package/lib/core/auth/verify.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.verifyInfuraKey = verifyInfuraKey;
|
|
4
4
|
exports.verifyAugustKey = verifyAugustKey;
|
|
5
|
+
const analytics_1 = require("../analytics");
|
|
5
6
|
const core_1 = require("../constants/core");
|
|
6
7
|
const fetcher_1 = require("../fetcher");
|
|
7
8
|
async function verifyInfuraKey(key) {
|
|
@@ -14,17 +15,20 @@ async function verifyInfuraKey(key) {
|
|
|
14
15
|
}
|
|
15
16
|
async function verifyAugustKey(key) {
|
|
16
17
|
// Fast path: no key means no verification possible. Returning false here
|
|
17
|
-
// preserves the historical contract (`init()` throws a generic "API key is
|
|
18
|
-
// and
|
|
18
|
+
// preserves the historical contract (`init()` throws a generic "API key is
|
|
19
|
+
// invalid") and saves a request the backend would reject with a 401.
|
|
19
20
|
if (!key)
|
|
20
21
|
return false;
|
|
21
22
|
try {
|
|
22
23
|
const verify = await (0, fetcher_1.fetchAugustWithKey)(key, core_1.WEBSERVER_ENDPOINTS.auth.verify);
|
|
23
|
-
|
|
24
|
+
const success = verify.status === 200;
|
|
25
|
+
(0, analytics_1.trackKeyVerification)('august', success);
|
|
26
|
+
return success;
|
|
24
27
|
}
|
|
25
28
|
catch {
|
|
26
29
|
// Network errors, timeouts, and any future thrown auth errors all
|
|
27
30
|
// resolve to "key not verified" here. Callers handle this as a boolean.
|
|
31
|
+
(0, analytics_1.trackKeyVerification)('august', false);
|
|
28
32
|
return false;
|
|
29
33
|
}
|
|
30
34
|
}
|
package/lib/core/base.class.d.ts
CHANGED
|
@@ -63,7 +63,13 @@ export interface IAugustBase {
|
|
|
63
63
|
providers?: IProvidersConfig;
|
|
64
64
|
solana?: ISolanaConfig;
|
|
65
65
|
stellar?: IStellarConfig;
|
|
66
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Provider keys. Optional: vault reads and vault-linked sub-account reads
|
|
68
|
+
* work without an August key. Supply `august` for admin and curator methods,
|
|
69
|
+
* for authenticated-user reads such as `getDiscountFactors`, and for
|
|
70
|
+
* sub-account reads where the subaccount is not linked to a vault.
|
|
71
|
+
*/
|
|
72
|
+
keys?: IKeys;
|
|
67
73
|
monitoring?: IMonitoring;
|
|
68
74
|
/** Analytics configuration. Enabled by default (opt-out model). */
|
|
69
75
|
analytics?: IAnalyticsConfig;
|
|
@@ -149,6 +155,7 @@ export declare class AugustBase {
|
|
|
149
155
|
constructor({ appName, providers, keys, monitoring, analytics, versionCheck, timeoutMs, publicApiBaseUrl, attribution, }: IAugustBase);
|
|
150
156
|
/**
|
|
151
157
|
* Verify the configured August API key and mark this instance as authorized.
|
|
158
|
+
* Only for SDKs built with `keys.august`; a keyless SDK skips `init()`.
|
|
152
159
|
* @throws Error when `keys.august` is missing or rejected by the API.
|
|
153
160
|
*/
|
|
154
161
|
init(): Promise<void>;
|
package/lib/core/base.class.js
CHANGED
|
@@ -46,7 +46,9 @@ class AugustBase {
|
|
|
46
46
|
rpcUrl: Object.values(providers)[0],
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
// Default to an empty set so the api and sub-account modules can read
|
|
50
|
+
// `this.keys.august` (undefined) instead of throwing on a keyless SDK.
|
|
51
|
+
this.keys = keys ?? {};
|
|
50
52
|
// Set environment (defaults to PROD for safety)
|
|
51
53
|
const environment = monitoring?.env || monitoring?.['x-environment'] || 'PROD';
|
|
52
54
|
this.monitoring = {
|
|
@@ -71,6 +73,9 @@ class AugustBase {
|
|
|
71
73
|
// prior staging instance would leak into a later prod instance in the same
|
|
72
74
|
// process — the inverse of the isolation this option exists to provide.
|
|
73
75
|
(0, fetcher_1.setPublicApiBaseUrl)(publicApiBaseUrl ?? null);
|
|
76
|
+
// Every backend request from this process now identifies the app
|
|
77
|
+
// (`x-august-app`) — same last-instance-wins contract as the base URL.
|
|
78
|
+
(0, fetcher_1.setSdkAppName)(this.appName);
|
|
74
79
|
// ERC-8021 attribution follows the same reset-on-omit contract as
|
|
75
80
|
// `publicApiBaseUrl`: called unconditionally so a prior instance's
|
|
76
81
|
// builder codes never leak into a later instance in the same process.
|
|
@@ -88,6 +93,7 @@ class AugustBase {
|
|
|
88
93
|
}
|
|
89
94
|
/**
|
|
90
95
|
* Verify the configured August API key and mark this instance as authorized.
|
|
96
|
+
* Only for SDKs built with `keys.august`; a keyless SDK skips `init()`.
|
|
91
97
|
* @throws Error when `keys.august` is missing or rejected by the API.
|
|
92
98
|
*/
|
|
93
99
|
async init() {
|
|
@@ -33,6 +33,7 @@ export declare const WEBSERVER_URL: {
|
|
|
33
33
|
};
|
|
34
34
|
export declare const WEBSERVER_ENDPOINTS: {
|
|
35
35
|
default: {
|
|
36
|
+
/** @deprecated No backend route. Removed in the next major release. */
|
|
36
37
|
hello: string;
|
|
37
38
|
protected: string;
|
|
38
39
|
};
|
|
@@ -45,6 +46,7 @@ export declare const WEBSERVER_ENDPOINTS: {
|
|
|
45
46
|
};
|
|
46
47
|
subaccount: {
|
|
47
48
|
list: (offset?: number, limit?: number) => string;
|
|
49
|
+
/** @deprecated No backend route. Removed in the next major release. */
|
|
48
50
|
rewards: (subaccount: IAddress) => string;
|
|
49
51
|
tokens: (subaccount: IAddress) => string;
|
|
50
52
|
twap: {
|
|
@@ -55,6 +57,7 @@ export declare const WEBSERVER_ENDPOINTS: {
|
|
|
55
57
|
debank: (subaccount: IAddress) => string;
|
|
56
58
|
health_factor: (subaccount: IAddress) => string;
|
|
57
59
|
summary: (subaccount: IAddress) => string;
|
|
60
|
+
/** @deprecated No backend route. Removed in the next major release. */
|
|
58
61
|
batch: (subaccount: IAddress) => string;
|
|
59
62
|
loans: (subaccount: IAddress, side?: "BORROWER" | "LENDER" | "BOTH", active?: boolean) => string;
|
|
60
63
|
cefi: (subaccount: IAddress) => string;
|