@augustdigital/sdk 8.26.0 → 9.1.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/lib/adapters/stellar/actions.d.ts +13 -0
- package/lib/adapters/stellar/actions.js +51 -2
- package/lib/adapters/stellar/index.d.ts +12 -0
- package/lib/adapters/stellar/index.js +12 -0
- package/lib/adapters/stellar/invocation.d.ts +55 -0
- package/lib/adapters/stellar/invocation.js +92 -0
- package/lib/adapters/stellar/soroban.d.ts +8 -0
- package/lib/adapters/stellar/soroban.js +18 -4
- package/lib/adapters/stellar/submit.d.ts +8 -0
- package/lib/adapters/stellar/submit.js +46 -0
- package/lib/core/analytics/app-name.d.ts +27 -0
- package/lib/core/analytics/app-name.js +48 -0
- package/lib/core/analytics/env.d.ts +17 -0
- package/lib/core/analytics/env.js +88 -0
- package/lib/core/analytics/sentry.d.ts +16 -4
- package/lib/core/analytics/sentry.js +24 -29
- package/lib/core/analytics/version.d.ts +1 -1
- package/lib/core/analytics/version.js +1 -1
- package/lib/core/base.class.d.ts +26 -3
- package/lib/core/base.class.js +16 -31
- package/lib/core/logger/curator-alert.d.ts +217 -0
- package/lib/core/logger/curator-alert.js +276 -0
- package/lib/core/logger/index.d.ts +1 -0
- package/lib/core/logger/index.js +20 -1
- package/lib/sdk.d.ts +158 -7
- package/package.json +1 -1
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CURATOR_ALERTS_DISABLE_ENV_VAR = exports.DEFAULT_CURATOR_ALERT_ENDPOINT = exports.CURATOR_ALERT_PATH = void 0;
|
|
4
|
+
exports.configureCuratorAlerts = configureCuratorAlerts;
|
|
5
|
+
exports.resetCuratorAlertDedupe = resetCuratorAlertDedupe;
|
|
6
|
+
exports.areCuratorAlertsEnabled = areCuratorAlertsEnabled;
|
|
7
|
+
exports.reportRedeemFailure = reportRedeemFailure;
|
|
8
|
+
const lru_cache_1 = require("lru-cache");
|
|
9
|
+
const env_1 = require("../analytics/env");
|
|
10
|
+
const sanitize_1 = require("../analytics/sanitize");
|
|
11
|
+
const core_1 = require("../constants/core");
|
|
12
|
+
/**
|
|
13
|
+
* Path on the August public API that accepts a failed-redemption report. Chain
|
|
14
|
+
* lives in the payload, not the path — see {@link IRedeemFailureEvent.chain}.
|
|
15
|
+
*/
|
|
16
|
+
exports.CURATOR_ALERT_PATH = '/alerts/redeem-failure';
|
|
17
|
+
/**
|
|
18
|
+
* Where a redeem failure is reported: the August public API, which is already
|
|
19
|
+
* this SDK's read origin and already serves browsers.
|
|
20
|
+
*
|
|
21
|
+
* Browser delivery depends on CORS, and the API's allowlist is an enumerated
|
|
22
|
+
* list of partner origins (`ALLOWED_ORIGIN_REGEX` in the backend), not a
|
|
23
|
+
* wildcard. This POST sends `Content-Type: application/json`, so it is
|
|
24
|
+
* preflighted; an integration served from an origin that is not on that list
|
|
25
|
+
* loses every alert at the preflight. Onboarding a curator therefore has two
|
|
26
|
+
* halves — enabling the vault and allowlisting the origin their users load.
|
|
27
|
+
*
|
|
28
|
+
* That service is the trust boundary, not the destination: it validates the
|
|
29
|
+
* report, drops any vault it does not know or that has not opted in,
|
|
30
|
+
* rate-limits per wallet and per vault, and only then forwards to the Telegram
|
|
31
|
+
* bot that holds the token and the curator's channel. Nothing
|
|
32
|
+
* credential-shaped ships in this bundle, which is also why this endpoint
|
|
33
|
+
* takes no API key — a key in a browser bundle is a published key
|
|
34
|
+
* (CLAUDE.md §5). See {@link reportRedeemFailure} for the trust model.
|
|
35
|
+
*/
|
|
36
|
+
exports.DEFAULT_CURATOR_ALERT_ENDPOINT = `${core_1.WEBSERVER_URL.public}${exports.CURATOR_ALERT_PATH}`;
|
|
37
|
+
/** Env equivalent of `monitoring.curatorAlerts.enabled: false`. Node only. */
|
|
38
|
+
exports.CURATOR_ALERTS_DISABLE_ENV_VAR = 'AUGUST_SDK_DISABLE_CURATOR_ALERTS';
|
|
39
|
+
/** Suppression window per `{vault, wallet, phase, result code, error class}`. */
|
|
40
|
+
const ALERT_DEDUPE_TTL_MS = 10 * 60 * 1000;
|
|
41
|
+
/**
|
|
42
|
+
* Diagnostic tail kept on the relayed error. Bounds a field that is unbounded
|
|
43
|
+
* by nature (a Soroban diagnostic event log) before it leaves the process. The
|
|
44
|
+
* receiving service applies its own, smaller display cap for the Telegram
|
|
45
|
+
* message, so this is the transport ceiling, not the one a curator sees.
|
|
46
|
+
*/
|
|
47
|
+
const MAX_ERROR_CHARS = 1500;
|
|
48
|
+
const SEND_TIMEOUT_MS = 5000;
|
|
49
|
+
/**
|
|
50
|
+
* Dedupe keys only — deliberately NOT the shared `core/cache.ts` LRU. That one
|
|
51
|
+
* is a 1000-entry cache shared with RPC and metadata memoization, so ordinary
|
|
52
|
+
* traffic could evict a suppression key mid-window (re-opening the flood this
|
|
53
|
+
* exists to stop) and a vault-wide incident's keys could evict useful reads.
|
|
54
|
+
*/
|
|
55
|
+
const alertDedupe = new lru_cache_1.LRUCache({
|
|
56
|
+
max: 200,
|
|
57
|
+
ttl: ALERT_DEDUPE_TTL_MS,
|
|
58
|
+
});
|
|
59
|
+
let explicitEnabled;
|
|
60
|
+
let endpoint = exports.DEFAULT_CURATOR_ALERT_ENDPOINT;
|
|
61
|
+
let endpointOverridden = false;
|
|
62
|
+
let reporterAppName;
|
|
63
|
+
let reporterEnv;
|
|
64
|
+
let configSignature;
|
|
65
|
+
/**
|
|
66
|
+
* Apply constructor config. Called unconditionally by `AugustBase` so an
|
|
67
|
+
* instance that omits `curatorAlerts` RESETS to the defaults rather than
|
|
68
|
+
* inheriting a prior instance's settings — same contract as
|
|
69
|
+
* `setPublicApiBaseUrl` and `setAttribution`.
|
|
70
|
+
*
|
|
71
|
+
* Also the supported opt-out for code that calls the `Stellar` namespace
|
|
72
|
+
* functions directly without constructing an `AugustSDK` (the testnet flow in
|
|
73
|
+
* the docs), and the only one that works in a browser, where the env var is
|
|
74
|
+
* unreadable.
|
|
75
|
+
*
|
|
76
|
+
* @param config - `monitoring.curatorAlerts`, or `null` to restore defaults.
|
|
77
|
+
* @param context - Facts about the reporting instance; omitted entirely by a
|
|
78
|
+
* caller that only wants to disable reporting.
|
|
79
|
+
*/
|
|
80
|
+
function configureCuratorAlerts(config, context = {}) {
|
|
81
|
+
const override = config?.endpoint?.trim();
|
|
82
|
+
const nextEndpoint = override ||
|
|
83
|
+
(context.apiBaseUrl
|
|
84
|
+
? `${context.apiBaseUrl.replace(/\/+$/, '')}${exports.CURATOR_ALERT_PATH}`
|
|
85
|
+
: exports.DEFAULT_CURATOR_ALERT_ENDPOINT);
|
|
86
|
+
// Suppression state belongs to the configuration that produced it, so a
|
|
87
|
+
// redirected endpoint or a flipped switch starts with a clean window. But
|
|
88
|
+
// this runs on EVERY `AugustBase` construction, and an app that builds the
|
|
89
|
+
// SDK inside a render rather than a memo would otherwise reset flood control
|
|
90
|
+
// on every attempt — so an identical reconfiguration keeps the window.
|
|
91
|
+
const signature = `${nextEndpoint}|${config?.enabled}|${context.environment}`;
|
|
92
|
+
if (signature !== configSignature) {
|
|
93
|
+
alertDedupe.clear();
|
|
94
|
+
configSignature = signature;
|
|
95
|
+
}
|
|
96
|
+
explicitEnabled = config?.enabled;
|
|
97
|
+
endpointOverridden = Boolean(override);
|
|
98
|
+
endpoint = nextEndpoint;
|
|
99
|
+
reporterAppName = context.appName;
|
|
100
|
+
reporterEnv = context.environment;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Drop every suppression key. Test-only seam — reconfiguration no longer
|
|
104
|
+
* clears the window on its own when the configuration is unchanged, so a suite
|
|
105
|
+
* that reports the same failure across cases needs an explicit reset.
|
|
106
|
+
* @internal
|
|
107
|
+
*/
|
|
108
|
+
function resetCuratorAlertDedupe() {
|
|
109
|
+
alertDedupe.clear();
|
|
110
|
+
}
|
|
111
|
+
function isTruthyEnv(value) {
|
|
112
|
+
if (!value)
|
|
113
|
+
return false;
|
|
114
|
+
const v = value.toLowerCase();
|
|
115
|
+
return v === '1' || v === 'true' || v === 'yes' || v === 'on';
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Whether an alert would be sent right now.
|
|
119
|
+
*
|
|
120
|
+
* Quiet by default outside production, mirroring `analytics`: a partner's Jest
|
|
121
|
+
* suite or `next dev` session exercising a failing redeem must not page a real
|
|
122
|
+
* curator. Two gates are needed for that, because they cover different
|
|
123
|
+
* runtimes — `NODE_ENV` is the Node one, and bundlers strip or stub
|
|
124
|
+
* `process.env` in the browser, so a locally-served app is recognised by its
|
|
125
|
+
* hostname instead (CLAUDE.md §5). Without that gate, a browser app run
|
|
126
|
+
* against mainnet from any loopback or private origin — `localhost`, a
|
|
127
|
+
* container on `172.20.0.0/16`, `[::1]` — pages a real curator on every
|
|
128
|
+
* failed redeem. `isLocalhost` in `core/analytics/env` lists the ranges.
|
|
129
|
+
*
|
|
130
|
+
* `enabled: true` overrides both — it is the documented way to exercise the
|
|
131
|
+
* path deliberately, and the SDK's own suite relies on it.
|
|
132
|
+
*
|
|
133
|
+
* The env var is read per call (not once at module load) so a consumer that
|
|
134
|
+
* sets it after import is still honoured, and a test can set and unset it
|
|
135
|
+
* without re-importing. It deliberately outranks an explicit `enabled: true`:
|
|
136
|
+
* it is the kill switch, and an operator setting it should not have to find
|
|
137
|
+
* and edit the construction site to be obeyed.
|
|
138
|
+
*/
|
|
139
|
+
function areCuratorAlertsEnabled() {
|
|
140
|
+
if (explicitEnabled === false)
|
|
141
|
+
return false;
|
|
142
|
+
if (isTruthyEnv((0, env_1.readEnv)(exports.CURATOR_ALERTS_DISABLE_ENV_VAR)))
|
|
143
|
+
return false;
|
|
144
|
+
if (explicitEnabled === true)
|
|
145
|
+
return true;
|
|
146
|
+
if (reporterEnv && reporterEnv !== 'PROD')
|
|
147
|
+
return false;
|
|
148
|
+
return !(0, env_1.isNodeDevOrTestEnv)() && !(0, env_1.isLocalhost)();
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Collapse an error to the failure mode it represents, so one wallet retrying
|
|
152
|
+
* the same failing redeem produces one alert — but two *different* failures on
|
|
153
|
+
* that vault still produce two.
|
|
154
|
+
*
|
|
155
|
+
* Volatile or semantic is decided by shape:
|
|
156
|
+
* - long hex (XDR blobs, hashes) and 56-char Stellar strkeys → volatile;
|
|
157
|
+
* - runs of 4+ digits (amounts, balances, ledger sequences) → volatile;
|
|
158
|
+
* - a `#`-prefixed number → semantic, kept whatever its length. A Soroban
|
|
159
|
+
* contract code IS the failure's identity: merging `Error(Contract, #408)`
|
|
160
|
+
* (insufficient shares) with `#10` (balance out of range) — or two 4-digit
|
|
161
|
+
* codes with each other — would hide the second for the whole window.
|
|
162
|
+
*/
|
|
163
|
+
function errorSignature(error) {
|
|
164
|
+
return error
|
|
165
|
+
.replace(/0x[0-9a-fA-F]{8,}/g, '0x')
|
|
166
|
+
.replace(/\b[A-Z2-7]{56}\b/g, 'S')
|
|
167
|
+
.replace(/(?<![0-9a-fA-Fx#-])\d{4,}/g, 'N')
|
|
168
|
+
.replace(/\s+/g, ' ')
|
|
169
|
+
.trim()
|
|
170
|
+
.slice(0, 200);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Report a failed vault redemption for the curator of that vault.
|
|
174
|
+
*
|
|
175
|
+
* **Why this exists.** Stellar vaults are instant-redeem only — there is no
|
|
176
|
+
* request/queue path — so a curator whose users' redemptions are failing has
|
|
177
|
+
* no signal at all today: the failure surfaces to the user, and to August's
|
|
178
|
+
* internal Sentry, and stops there. Emitting from the SDK rather than from a
|
|
179
|
+
* single frontend means any integration can report one (AUGUST-7162) — subject
|
|
180
|
+
* to the CORS caveat on {@link DEFAULT_CURATOR_ALERT_ENDPOINT}.
|
|
181
|
+
*
|
|
182
|
+
* **Trust model.** The endpoint is public by construction — it ships in this
|
|
183
|
+
* bundle — so the relay treats every event as untrusted input, not as an
|
|
184
|
+
* attested fact. The SDK's job is to report accurately; the relay's job is to
|
|
185
|
+
* verify, rate-limit per `{vault, wallet}`, and drop events naming a vault
|
|
186
|
+
* outside its routing map. `'submission'` events carry a `txHash` the relay can
|
|
187
|
+
* confirm on chain, which makes them unforgeable; `'simulation'` events have no
|
|
188
|
+
* on-chain artifact and are treated as the weaker claim. Nothing
|
|
189
|
+
* credential-shaped is reachable from here: no bot token, no chat id, no
|
|
190
|
+
* curator identity.
|
|
191
|
+
*
|
|
192
|
+
* **Side effects.** At most one `POST` to the relay, fire-and-forget: this runs
|
|
193
|
+
* inside a `catch` on a money path, so it never awaits, never throws back into
|
|
194
|
+
* the caller, and never alters the error the caller sees. Suppressed to one
|
|
195
|
+
* send per `{contractId, eoa, phase, resultCode, error class}` per 10 minutes,
|
|
196
|
+
* so a wallet retrying a deterministic failure costs a single request. Note the
|
|
197
|
+
* receiving service applies its own, coarser window on top. A no-op when
|
|
198
|
+
* reporting is disabled (see {@link areCuratorAlertsEnabled}) and, unless a
|
|
199
|
+
* custom endpoint is configured, for any network other than mainnet — a
|
|
200
|
+
* testnet failure is not a curator's problem.
|
|
201
|
+
*
|
|
202
|
+
* @param event - The failed attempt. `error` is sanitized (secrets scrubbed via
|
|
203
|
+
* `sanitizeString`) and capped at 1500 characters before it leaves the
|
|
204
|
+
* process; `sharesRaw` is relayed unscaled, and the receiving service scales
|
|
205
|
+
* it for display with the decimals it holds for that vault — which for an
|
|
206
|
+
* offset vault are the asset's, not the share token's, so the figure a curator
|
|
207
|
+
* sees is a magnitude rather than an exact amount (see AUGUST-6381).
|
|
208
|
+
* @internal
|
|
209
|
+
*/
|
|
210
|
+
function reportRedeemFailure(event) {
|
|
211
|
+
if (!areCuratorAlertsEnabled())
|
|
212
|
+
return;
|
|
213
|
+
if (!event.contractId || !event.eoa || !event.error || !event.sharesRaw) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
// Production networks only. Every family names its production network
|
|
217
|
+
// `mainnet` except Solana (`mainnet-beta`), which is why this is a prefix
|
|
218
|
+
// test rather than an equality one — a testnet failure is not a curator's
|
|
219
|
+
// problem, and reporting it would spend a real vault's alert budget.
|
|
220
|
+
if (!event.network.startsWith('mainnet') && !endpointOverridden)
|
|
221
|
+
return;
|
|
222
|
+
const safeError = (0, sanitize_1.sanitizeString)(String(event.error)).slice(0, MAX_ERROR_CHARS);
|
|
223
|
+
// The two fields that exist only on the submission member, read once through
|
|
224
|
+
// the discriminant so everything below stays shape-agnostic.
|
|
225
|
+
const submission = event.phase === 'submission' ? event : undefined;
|
|
226
|
+
const key = [
|
|
227
|
+
event.contractId,
|
|
228
|
+
event.eoa,
|
|
229
|
+
event.phase,
|
|
230
|
+
submission?.resultCode ?? '',
|
|
231
|
+
errorSignature(safeError),
|
|
232
|
+
].join('|');
|
|
233
|
+
if (alertDedupe.has(key))
|
|
234
|
+
return;
|
|
235
|
+
alertDedupe.set(key, true);
|
|
236
|
+
// Coerced rather than trusted: this type is `@internal` but deep-importable,
|
|
237
|
+
// so an untyped consumer can reach it with a `bigint`, which `JSON.stringify`
|
|
238
|
+
// rejects. Emptiness is already handled by the guard above.
|
|
239
|
+
const body = JSON.stringify({
|
|
240
|
+
event: 'vault.redeem.failed',
|
|
241
|
+
phase: event.phase,
|
|
242
|
+
chain: event.chain,
|
|
243
|
+
network: event.network,
|
|
244
|
+
contractId: event.contractId,
|
|
245
|
+
eoa: event.eoa,
|
|
246
|
+
sharesRaw: String(event.sharesRaw),
|
|
247
|
+
txHash: submission?.txHash,
|
|
248
|
+
resultCode: submission?.resultCode,
|
|
249
|
+
error: safeError,
|
|
250
|
+
timestamp: new Date().toISOString(),
|
|
251
|
+
appName: reporterAppName,
|
|
252
|
+
});
|
|
253
|
+
(async () => {
|
|
254
|
+
const res = await fetch(endpoint, {
|
|
255
|
+
method: 'POST',
|
|
256
|
+
headers: { 'Content-Type': 'application/json' },
|
|
257
|
+
body,
|
|
258
|
+
signal: AbortSignal.timeout(SEND_TIMEOUT_MS),
|
|
259
|
+
});
|
|
260
|
+
const status = res?.status ?? 0;
|
|
261
|
+
if (status >= 200 && status < 300)
|
|
262
|
+
return;
|
|
263
|
+
// A 4xx is the endpoint answering: the report was rejected (422), or we are
|
|
264
|
+
// being throttled (429). Keep the suppression key — retrying a rejected
|
|
265
|
+
// report cannot make it acceptable, and answering a rate limit by removing
|
|
266
|
+
// our own backpressure is the wrong direction (CLAUDE.md §4.2). A 5xx or a
|
|
267
|
+
// transport failure means the report never landed, so release it.
|
|
268
|
+
if (status < 400 || status >= 500)
|
|
269
|
+
alertDedupe.delete(key);
|
|
270
|
+
console.warn('#CuratorAlert.stellarRedeemFailure:', status, res?.statusText);
|
|
271
|
+
})().catch((e) => {
|
|
272
|
+
alertDedupe.delete(key);
|
|
273
|
+
console.warn('#CuratorAlert.redeemFailure.unreachable:', (0, sanitize_1.sanitizeString)(String(e?.message ?? e)));
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
//# sourceMappingURL=curator-alert.js.map
|
|
@@ -96,3 +96,4 @@ declare const Logger: {
|
|
|
96
96
|
};
|
|
97
97
|
import * as slack from './slack';
|
|
98
98
|
export { slack as Slack, Logger };
|
|
99
|
+
export { configureCuratorAlerts, areCuratorAlertsEnabled, CURATOR_ALERTS_DISABLE_ENV_VAR, type ICuratorAlertsConfig, type ICuratorAlertsContext, } from './curator-alert';
|
package/lib/core/logger/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.Logger = exports.Slack = void 0;
|
|
36
|
+
exports.CURATOR_ALERTS_DISABLE_ENV_VAR = exports.areCuratorAlertsEnabled = exports.configureCuratorAlerts = exports.Logger = exports.Slack = void 0;
|
|
37
37
|
const sanitize_1 = require("../analytics/sanitize");
|
|
38
38
|
let logger = null;
|
|
39
39
|
let structuredLogger = null;
|
|
@@ -141,4 +141,23 @@ const Logger = {
|
|
|
141
141
|
exports.Logger = Logger;
|
|
142
142
|
const slack = __importStar(require("./slack"));
|
|
143
143
|
exports.Slack = slack;
|
|
144
|
+
// Only the opt-out is public: code that drives the `Stellar` namespace directly
|
|
145
|
+
// never constructs an `AugustSDK`, so `configureCuratorAlerts` is its sole way
|
|
146
|
+
// to turn curator alerts off (and the only one that works in a browser, where
|
|
147
|
+
// the env var is unreadable). The emitter itself stays deep-import only — a
|
|
148
|
+
// partner has no reason to inject events into the relay.
|
|
149
|
+
//
|
|
150
|
+
// Safe to re-export from this barrel at all because `curator-alert` imports only
|
|
151
|
+
// `types/`, `constants/` and leaf helpers under `core/analytics/` — never this
|
|
152
|
+
// file — so there is no cycle back through the logger. `madge --circular` in CI
|
|
153
|
+
// is the enforcement; this note is why it passes (CLAUDE.md §9).
|
|
154
|
+
//
|
|
155
|
+
// Both parameter types travel with the function: `ICuratorAlertsContext` is the
|
|
156
|
+
// second argument's type, so without it a consumer cannot type a wrapper around
|
|
157
|
+
// `configureCuratorAlerts` — and API Extractor flags it as a forgotten export
|
|
158
|
+
// (CLAUDE.md §6).
|
|
159
|
+
var curator_alert_1 = require("./curator-alert");
|
|
160
|
+
Object.defineProperty(exports, "configureCuratorAlerts", { enumerable: true, get: function () { return curator_alert_1.configureCuratorAlerts; } });
|
|
161
|
+
Object.defineProperty(exports, "areCuratorAlertsEnabled", { enumerable: true, get: function () { return curator_alert_1.areCuratorAlertsEnabled; } });
|
|
162
|
+
Object.defineProperty(exports, "CURATOR_ALERTS_DISABLE_ENV_VAR", { enumerable: true, get: function () { return curator_alert_1.CURATOR_ALERTS_DISABLE_ENV_VAR; } });
|
|
144
163
|
//# sourceMappingURL=index.js.map
|
package/lib/sdk.d.ts
CHANGED
|
@@ -15112,6 +15112,30 @@ export declare type ApproveResult =
|
|
|
15112
15112
|
kind: 'native';
|
|
15113
15113
|
};
|
|
15114
15114
|
|
|
15115
|
+
/**
|
|
15116
|
+
* Whether an alert would be sent right now.
|
|
15117
|
+
*
|
|
15118
|
+
* Quiet by default outside production, mirroring `analytics`: a partner's Jest
|
|
15119
|
+
* suite or `next dev` session exercising a failing redeem must not page a real
|
|
15120
|
+
* curator. Two gates are needed for that, because they cover different
|
|
15121
|
+
* runtimes — `NODE_ENV` is the Node one, and bundlers strip or stub
|
|
15122
|
+
* `process.env` in the browser, so a locally-served app is recognised by its
|
|
15123
|
+
* hostname instead (CLAUDE.md §5). Without that gate, a browser app run
|
|
15124
|
+
* against mainnet from any loopback or private origin — `localhost`, a
|
|
15125
|
+
* container on `172.20.0.0/16`, `[::1]` — pages a real curator on every
|
|
15126
|
+
* failed redeem. `isLocalhost` in `core/analytics/env` lists the ranges.
|
|
15127
|
+
*
|
|
15128
|
+
* `enabled: true` overrides both — it is the documented way to exercise the
|
|
15129
|
+
* path deliberately, and the SDK's own suite relies on it.
|
|
15130
|
+
*
|
|
15131
|
+
* The env var is read per call (not once at module load) so a consumer that
|
|
15132
|
+
* sets it after import is still honoured, and a test can set and unset it
|
|
15133
|
+
* without re-importing. It deliberately outranks an explicit `enabled: true`:
|
|
15134
|
+
* it is the kill switch, and an operator setting it should not have to find
|
|
15135
|
+
* and edit the construction site to be obeyed.
|
|
15136
|
+
*/
|
|
15137
|
+
export declare function areCuratorAlertsEnabled(): boolean;
|
|
15138
|
+
|
|
15115
15139
|
declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
15116
15140
|
|
|
15117
15141
|
/**
|
|
@@ -15822,8 +15846,8 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
15822
15846
|
* Initialize base SDK with provider configuration and API keys.
|
|
15823
15847
|
* Sets up the first provider as the active network by default.
|
|
15824
15848
|
*
|
|
15825
|
-
* @throws
|
|
15826
|
-
* length range — see {@link IAugustBase.appName}.
|
|
15849
|
+
* @throws AugustValidationError if `appName` is missing, malformed, or
|
|
15850
|
+
* out of the allowed length range — see {@link IAugustBase.appName}.
|
|
15827
15851
|
*/
|
|
15828
15852
|
constructor({ appName, providers, keys, monitoring, analytics, versionCheck, timeoutMs, publicApiBaseUrl, attribution, }: IAugustBase);
|
|
15829
15853
|
/**
|
|
@@ -17530,6 +17554,23 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
17530
17554
|
*/
|
|
17531
17555
|
export declare function computeArgShape(args: unknown[]): string[];
|
|
17532
17556
|
|
|
17557
|
+
/**
|
|
17558
|
+
* Apply constructor config. Called unconditionally by `AugustBase` so an
|
|
17559
|
+
* instance that omits `curatorAlerts` RESETS to the defaults rather than
|
|
17560
|
+
* inheriting a prior instance's settings — same contract as
|
|
17561
|
+
* `setPublicApiBaseUrl` and `setAttribution`.
|
|
17562
|
+
*
|
|
17563
|
+
* Also the supported opt-out for code that calls the `Stellar` namespace
|
|
17564
|
+
* functions directly without constructing an `AugustSDK` (the testnet flow in
|
|
17565
|
+
* the docs), and the only one that works in a browser, where the env var is
|
|
17566
|
+
* unreadable.
|
|
17567
|
+
*
|
|
17568
|
+
* @param config - `monitoring.curatorAlerts`, or `null` to restore defaults.
|
|
17569
|
+
* @param context - Facts about the reporting instance; omitted entirely by a
|
|
17570
|
+
* caller that only wants to disable reporting.
|
|
17571
|
+
*/
|
|
17572
|
+
export declare function configureCuratorAlerts(config: ICuratorAlertsConfig | null, context?: ICuratorAlertsContext): void;
|
|
17573
|
+
|
|
17533
17574
|
/**
|
|
17534
17575
|
* Query the vault's `convert_to_shares` to preview how many shares a deposit
|
|
17535
17576
|
* amount would yield. Returns the raw share amount as a string, or null on
|
|
@@ -17627,6 +17668,9 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
17627
17668
|
*/
|
|
17628
17669
|
export declare function crossChainVaultRedeem(props: ICrossChainRedeemRequest): Promise<ICrossChainRedeemResult>;
|
|
17629
17670
|
|
|
17671
|
+
/** Env equivalent of `monitoring.curatorAlerts.enabled: false`. Node only. */
|
|
17672
|
+
export declare const CURATOR_ALERTS_DISABLE_ENV_VAR = "AUGUST_SDK_DISABLE_CURATOR_ALERTS";
|
|
17673
|
+
|
|
17630
17674
|
/**
|
|
17631
17675
|
* Datetime
|
|
17632
17676
|
*/
|
|
@@ -19810,6 +19854,19 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
19810
19854
|
* `redeem(shares: i128, receiver, owner, operator) -> i128`; divergence
|
|
19811
19855
|
* surfaces as a generic Soroban simulation error.
|
|
19812
19856
|
*
|
|
19857
|
+
* Side effect on failure: when the *vault* cannot serve the redemption — it
|
|
19858
|
+
* rejected the call, or its ledger state needs restoring — the failure is
|
|
19859
|
+
* reported to that vault's curator. Stellar vaults are instant-redeem only, so
|
|
19860
|
+
* this is the curator's only signal that their depositors cannot get out
|
|
19861
|
+
* (AUGUST-7162). Fire-and-forget and deduped; see
|
|
19862
|
+
* {@link reportRedeemFailure} and {@link REPORTED_BUILD_STAGES}.
|
|
19863
|
+
*
|
|
19864
|
+
* Note this includes a caller-caused rejection such as redeeming more shares
|
|
19865
|
+
* than the wallet holds: the contract trapping is what we can observe, and
|
|
19866
|
+
* telling that apart from a vault-side problem needs the vault's error
|
|
19867
|
+
* taxonomy. A bad address, an unfunded account, and an exhausted RPC failover
|
|
19868
|
+
* are excluded — none of those reached the vault.
|
|
19869
|
+
*
|
|
19813
19870
|
* @returns Base64-encoded XDR ready for wallet signing; pass the signed
|
|
19814
19871
|
* XDR to {@link submitStellarTransaction}.
|
|
19815
19872
|
*/
|
|
@@ -19960,7 +20017,8 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
19960
20017
|
* 3–64 characters, `[a-zA-Z0-9._-]` only. Use a slug ("acme-trader"),
|
|
19961
20018
|
* not a display name ("Acme Trader").
|
|
19962
20019
|
*
|
|
19963
|
-
* @throws
|
|
20020
|
+
* @throws AugustValidationError synchronously from the constructor if
|
|
20021
|
+
* missing, empty, or malformed.
|
|
19964
20022
|
*
|
|
19965
20023
|
* @example
|
|
19966
20024
|
* ```typescript
|
|
@@ -20408,6 +20466,46 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
20408
20466
|
hubOnlyReceipt?: boolean;
|
|
20409
20467
|
}
|
|
20410
20468
|
|
|
20469
|
+
/** Curator-alert reporting. Enabled by default; this is the opt-out. */
|
|
20470
|
+
export declare interface ICuratorAlertsConfig {
|
|
20471
|
+
/**
|
|
20472
|
+
* `false` stops emitting entirely. `true` forces emitting even in an
|
|
20473
|
+
* environment the SDK would otherwise stay quiet in — it bypasses **every**
|
|
20474
|
+
* environment gate: `NODE_ENV` of `development`/`test`, a browser served
|
|
20475
|
+
* from a loopback or private host, and `monitoring.env` other than `PROD`.
|
|
20476
|
+
* It does NOT lift the mainnet-only restriction; only `endpoint` does. A
|
|
20477
|
+
* `DEV` or test
|
|
20478
|
+
* integration that sets it and then fails a mainnet redeem pages a real
|
|
20479
|
+
* curator, so use it only when deliberately exercising the path (pair it
|
|
20480
|
+
* with `endpoint` to aim at a test relay). The only thing that still wins is
|
|
20481
|
+
* the {@link CURATOR_ALERTS_DISABLE_ENV_VAR} kill switch.
|
|
20482
|
+
*/
|
|
20483
|
+
enabled?: boolean;
|
|
20484
|
+
/**
|
|
20485
|
+
* Override the relay endpoint. Defaults to
|
|
20486
|
+
* {@link DEFAULT_CURATOR_ALERT_ENDPOINT}. Setting it also lifts the
|
|
20487
|
+
* mainnet-only restriction, so a staging relay can receive testnet failures.
|
|
20488
|
+
*/
|
|
20489
|
+
endpoint?: string;
|
|
20490
|
+
}
|
|
20491
|
+
|
|
20492
|
+
/** Ambient facts about the reporting SDK instance, supplied by `AugustBase`. */
|
|
20493
|
+
export declare interface ICuratorAlertsContext {
|
|
20494
|
+
/** Carried on the payload so August can tell partner traffic apart. */
|
|
20495
|
+
appName?: string;
|
|
20496
|
+
/**
|
|
20497
|
+
* `monitoring.env`. Anything other than `'PROD'` keeps the SDK quiet unless
|
|
20498
|
+
* `config.enabled` is explicitly `true`.
|
|
20499
|
+
*/
|
|
20500
|
+
environment?: IEnv;
|
|
20501
|
+
/**
|
|
20502
|
+
* Effective base URL of the August public API. Reports follow the API this
|
|
20503
|
+
* instance reads from, so a deployment pointed at a staging backend alerts
|
|
20504
|
+
* staging rather than production.
|
|
20505
|
+
*/
|
|
20506
|
+
apiBaseUrl?: string;
|
|
20507
|
+
}
|
|
20508
|
+
|
|
20411
20509
|
/**
|
|
20412
20510
|
* On-chain whitelist status of one subaccount linked to a vault, from
|
|
20413
20511
|
* `GET /curator/vaults/{vault_address}/whitelist` (backend
|
|
@@ -20953,6 +21051,27 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
20953
21051
|
declare interface IMonitoring extends IWSMonitorHeaders {
|
|
20954
21052
|
slackWebhookUrl?: string;
|
|
20955
21053
|
env?: IEnv;
|
|
21054
|
+
/**
|
|
21055
|
+
* Curator notifications for failed vault redemptions. Enabled by default
|
|
21056
|
+
* (opt-out model, like `analytics`).
|
|
21057
|
+
*
|
|
21058
|
+
* Stellar vaults are instant-redeem only, so when a redemption fails the
|
|
21059
|
+
* vault's curator has no other way to learn about it. The SDK relays the
|
|
21060
|
+
* failure to August's notification service, which routes it to that curator's
|
|
21061
|
+
* own channel — no credentials or curator identities are held here.
|
|
21062
|
+
*
|
|
21063
|
+
* Set `enabled: false` (or, in Node, the
|
|
21064
|
+
* `AUGUST_SDK_DISABLE_CURATOR_ALERTS` env var) to stop emitting; set
|
|
21065
|
+
* `endpoint` only to point a non-prod deployment at a test relay. Nothing is
|
|
21066
|
+
* emitted unless `monitoring.env` is `PROD`, `NODE_ENV` is neither
|
|
21067
|
+
* `development` nor `test`, and — in a browser, where `NODE_ENV` is not
|
|
21068
|
+
* readable — the page is not served from localhost.
|
|
21069
|
+
*
|
|
21070
|
+
* `enabled: true` is the one exception: it bypasses all three gates, so a
|
|
21071
|
+
* `DEV` or test integration that sets it can page a real curator. See
|
|
21072
|
+
* {@link ICuratorAlertsConfig}.
|
|
21073
|
+
*/
|
|
21074
|
+
curatorAlerts?: ICuratorAlertsConfig;
|
|
20956
21075
|
}
|
|
20957
21076
|
|
|
20958
21077
|
/* Excluded from this release type: IMulticall3Request */
|
|
@@ -20983,16 +21102,28 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
20983
21102
|
* Initialize Sentry with SDK-specific configuration. Idempotent: re-calls
|
|
20984
21103
|
* only refresh user identity and the cached API-key hash.
|
|
20985
21104
|
*
|
|
21105
|
+
* Breaking change in v9: `appName` moved from the optional fifth parameter
|
|
21106
|
+
* to the required third parameter, so every telemetry stream carries an
|
|
21107
|
+
* application identity (the `AugustSDK` constructor has required it since
|
|
21108
|
+
* v5). Callers on the old positional order get a synchronous validation
|
|
21109
|
+
* error rather than silently anonymous events.
|
|
21110
|
+
*
|
|
20986
21111
|
* @param config - Analytics configuration. Pass `tracesSampleRate` to
|
|
20987
21112
|
* override the default of `0.1`.
|
|
20988
21113
|
* @param environment - Current environment (DEV or PROD).
|
|
21114
|
+
* @param appName - App-name slug, required. Set as the global `app.name`
|
|
21115
|
+
* tag on every event and used to derive `partner.id`. Identifier-shaped:
|
|
21116
|
+
* 3–64 chars, `[a-zA-Z0-9._-]` only, and not an EVM address — the same
|
|
21117
|
+
* rules the `AugustSDK` constructor enforces.
|
|
20989
21118
|
* @param walletAddress - Optional wallet address for user identification.
|
|
20990
21119
|
* @param apiKey - Optional API key (hashed for identification).
|
|
20991
|
-
* @
|
|
20992
|
-
*
|
|
20993
|
-
*
|
|
21120
|
+
* @throws AugustValidationError (code `INVALID_INPUT`) when `appName` is
|
|
21121
|
+
* missing, empty, mis-typed, out of the allowed length range, contains
|
|
21122
|
+
* disallowed characters, or is shaped like an EVM address. Thrown before
|
|
21123
|
+
* any analytics state mutates, even when analytics would be disabled by
|
|
21124
|
+
* config or environment gates.
|
|
20994
21125
|
*/
|
|
20995
|
-
export declare function initializeSentry(config: IAnalyticsConfig, environment: IEnv,
|
|
21126
|
+
export declare function initializeSentry(config: IAnalyticsConfig, environment: IEnv, appName: string, walletAddress?: string, apiKey?: string): void;
|
|
20996
21127
|
|
|
20997
21128
|
export declare type INormalizedNumber = {
|
|
20998
21129
|
normalized: string;
|
|
@@ -26099,10 +26230,22 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
26099
26230
|
vaultDeposit(params: Omit<IStellarDepositParams, 'network'>): Promise<string>;
|
|
26100
26231
|
/**
|
|
26101
26232
|
* Build an unsigned redeem transaction for a Stellar vault.
|
|
26233
|
+
*
|
|
26234
|
+
* Side effect on failure: a redemption the vault cannot serve is reported to
|
|
26235
|
+
* that vault's curator, since Stellar vaults are instant-redeem only and this
|
|
26236
|
+
* is the curator's only signal. Fire-and-forget — it never delays or alters
|
|
26237
|
+
* the error you receive. On by default in production; see
|
|
26238
|
+
* `monitoring.curatorAlerts` and the Curator Notifications section of the
|
|
26239
|
+
* Stellar Actions guide for exactly what is sent and how to opt out.
|
|
26240
|
+
*
|
|
26102
26241
|
* @returns Base64-encoded XDR of the unsigned transaction.
|
|
26103
26242
|
*/
|
|
26104
26243
|
vaultRedeem(params: Omit<IStellarRedeemParams, 'network'>): Promise<string>;
|
|
26105
26244
|
/**
|
|
26245
|
+
* Side effect: a submitted transaction that the network reports as a failed
|
|
26246
|
+
* `redeem` operation is reported to that vault's curator, on the same
|
|
26247
|
+
* fire-and-forget terms as {@link StellarAdapter.vaultRedeem}.
|
|
26248
|
+
*
|
|
26106
26249
|
* Submit a signed Soroban transaction and poll until the network confirms it.
|
|
26107
26250
|
*
|
|
26108
26251
|
* Submits on the network this adapter was constructed with, so `signedXdr`
|
|
@@ -26214,6 +26357,14 @@ declare type AsArray<T> = T extends readonly unknown[] ? T : never;
|
|
|
26214
26357
|
* plus, when the result XDR decodes, a `resultCode` string holding the
|
|
26215
26358
|
* transaction-level reason (e.g. `"txBadSeq"`, `"txTooLate"`); `resultCode`
|
|
26216
26359
|
* is `undefined` when the code cannot be decoded.
|
|
26360
|
+
*
|
|
26361
|
+
* Side effect: a transaction whose `resultCode` is `txFailed` — the operation
|
|
26362
|
+
* itself ran and failed — and whose envelope shows a vault `redeem` is relayed
|
|
26363
|
+
* to that vault's curator (fire-and-forget, deduped — see
|
|
26364
|
+
* {@link reportRedeemFailure}). Nothing else alerts: an RPC-rejected
|
|
26365
|
+
* broadcast is a retryable race, a poll timeout is indeterminate (the
|
|
26366
|
+
* transaction may yet succeed), and any other result code means the redeem
|
|
26367
|
+
* never executed.
|
|
26217
26368
|
* @example
|
|
26218
26369
|
* ```ts
|
|
26219
26370
|
* try {
|