@augustdigital/sdk 9.6.0 → 9.7.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 +1 -1
- 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/sanitize.d.ts +13 -0
- package/lib/core/analytics/sanitize.js +24 -12
- package/lib/core/analytics/version.d.ts +1 -1
- package/lib/core/analytics/version.js +1 -1
- package/lib/core/auth/verify.js +2 -2
- package/lib/core/base.class.d.ts +8 -1
- package/lib/core/base.class.js +4 -1
- package/lib/core/fetcher.d.ts +11 -5
- package/lib/core/fetcher.js +10 -7
- package/lib/main.d.ts +2 -1
- package/lib/main.js +2 -1
- 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 +97 -11
- package/lib/modules/vaults/getters.js +169 -17
- package/lib/modules/vaults/main.d.ts +2 -1
- package/lib/modules/vaults/main.js +2 -1
- package/lib/sdk.d.ts +1202 -1072
- 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 +1 -1
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ const sdk = new AugustSDK({
|
|
|
36
36
|
-1: 'https://api.mainnet-beta.solana.com', // Solana
|
|
37
37
|
},
|
|
38
38
|
keys: {
|
|
39
|
-
august: 'YOUR_API_KEY', // Optional:
|
|
39
|
+
august: 'YOUR_API_KEY', // Optional: vault reads, allocations and vault-linked sub-account reads work without it
|
|
40
40
|
},
|
|
41
41
|
monitoring: {
|
|
42
42
|
env: 'DEV', // Optional: 'DEV' enables console logging (defaults to 'PROD')
|
|
@@ -85,6 +85,10 @@ export interface ISolanaDepositOptions {
|
|
|
85
85
|
* Skips the quote and the single snapshot read it needs. `0n` restores the
|
|
86
86
|
* unguarded behaviour of the plain `deposit` instruction.
|
|
87
87
|
*
|
|
88
|
+
* When the handler's `idl` predates `deposit_checked`, a non-zero floor or
|
|
89
|
+
* any `slippageBps` throws {@link AugustValidationError} instead of being
|
|
90
|
+
* silently dropped; with neither, the plain `deposit` is sent.
|
|
91
|
+
*
|
|
88
92
|
* Must be a `bigint` in `0 .. 2^64-1`; anything else throws
|
|
89
93
|
* {@link AugustValidationError} before the transaction is built.
|
|
90
94
|
*/
|
|
@@ -107,6 +111,10 @@ export interface ISolanaRedeemOptions {
|
|
|
107
111
|
* Explicit floor in raw deposit-mint units, net of the withdrawal fee,
|
|
108
112
|
* passed to `redeem_checked` as is. Skips the quote. `0n` restores the
|
|
109
113
|
* unguarded behaviour of the plain `redeem` instruction.
|
|
114
|
+
*
|
|
115
|
+
* When the handler's `idl` predates `redeem_checked`, a non-zero floor or
|
|
116
|
+
* any `slippageBps` throws {@link AugustValidationError} instead of being
|
|
117
|
+
* silently dropped; with neither, the plain `redeem` is sent.
|
|
110
118
|
*/
|
|
111
119
|
minAssetsOut?: bigint;
|
|
112
120
|
}
|
|
@@ -55,7 +55,9 @@ export declare function slippageHint(e: unknown): string;
|
|
|
55
55
|
* is given, the vault state and share mint are read to quote the shares this
|
|
56
56
|
* deposit should mint, and that quote lowered by `options.slippageBps`
|
|
57
57
|
* (default {@link DEFAULT_SLIPPAGE_BPS}) is passed as the floor; the program
|
|
58
|
-
* reverts with `SlippageExceeded` if execution would mint fewer.
|
|
58
|
+
* reverts with `SlippageExceeded` if execution would mint fewer. An `idl`
|
|
59
|
+
* that predates `deposit_checked` gets the plain `deposit` with no floor,
|
|
60
|
+
* unless `options` asks for one — then it throws {@link AugustValidationError}.
|
|
59
61
|
*/
|
|
60
62
|
export declare function handleSolanaDeposit({ provider, connection, network, vaultProgramId, vaultAddress, depositAmount, publicKey, idl, options, }: {
|
|
61
63
|
vaultProgramId: PublicKey | string;
|
|
@@ -83,6 +85,9 @@ export declare function handleSolanaDeposit({ provider, connection, network, vau
|
|
|
83
85
|
* handler already reads, **net of the withdrawal fee**, and that quote
|
|
84
86
|
* lowered by `options.slippageBps` (default {@link DEFAULT_SLIPPAGE_BPS}) is
|
|
85
87
|
* passed as the floor; the program reverts with `SlippageExceeded` below it.
|
|
88
|
+
* An `idl` that predates `redeem_checked` gets the plain `redeem` with no
|
|
89
|
+
* floor, unless `options` asks for one — then it throws
|
|
90
|
+
* {@link AugustValidationError}.
|
|
86
91
|
* @throws AugustValidationError on missing wallet/programId or invalid amount,
|
|
87
92
|
* or when the wallet holds fewer shares than `redeemShares`.
|
|
88
93
|
* @throws AugustSDKError when a candidate token account's balance cannot be
|
|
@@ -99,6 +99,52 @@ function validateExplicitFloor(value, label) {
|
|
|
99
99
|
}
|
|
100
100
|
return value;
|
|
101
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Decide whether a handler can send the slippage-checked instruction, or must
|
|
104
|
+
* fall back to the plain one.
|
|
105
|
+
*
|
|
106
|
+
* `idl` is caller-supplied, and an IDL generated before the program shipped
|
|
107
|
+
* `deposit_checked` / `redeem_checked` produces a `Program` with no such
|
|
108
|
+
* method. Until 9.4.0 the handlers sent the plain instructions, so those same
|
|
109
|
+
* inputs used to work; calling the checked method on them throws a TypeError
|
|
110
|
+
* before anything is sent (AUGUST-8023). The program still accepts the plain
|
|
111
|
+
* instructions, with the behaviour a floor of `0` gives the checked ones, so
|
|
112
|
+
* falling back preserves what those callers had.
|
|
113
|
+
*
|
|
114
|
+
* The fallback is refused when the caller asked for protection — a non-zero
|
|
115
|
+
* explicit floor, or any `slippageBps` — since the plain instruction would
|
|
116
|
+
* silently drop it. An explicit floor of `0n` is the documented "no floor" and
|
|
117
|
+
* falls back.
|
|
118
|
+
*
|
|
119
|
+
* Probes `program.methods` rather than `idl.instructions`: that is the object
|
|
120
|
+
* the handler calls, and it already reflects Anchor's camelCase conversion.
|
|
121
|
+
*
|
|
122
|
+
* @param program - Anchor program built from the caller's IDL.
|
|
123
|
+
* @param checkedMethod - `'depositChecked'` or `'redeemChecked'`.
|
|
124
|
+
* @param floor - The caller's explicit `minSharesOut` / `minAssetsOut`, if any.
|
|
125
|
+
* @param slippageBps - The caller's tolerance, if any.
|
|
126
|
+
* @param handler - Handler name, for the log line and the error.
|
|
127
|
+
* @returns `true` to send the checked instruction, `false` for the plain one.
|
|
128
|
+
* @throws {@link AugustValidationError} when the IDL lacks the checked
|
|
129
|
+
* instruction and the caller asked for a floor.
|
|
130
|
+
*/
|
|
131
|
+
function sendsCheckedInstruction({ program, checkedMethod, floor, slippageBps, handler, }) {
|
|
132
|
+
const methods = program.methods;
|
|
133
|
+
if (typeof methods[checkedMethod] === 'function')
|
|
134
|
+
return true;
|
|
135
|
+
const instruction = checkedMethod === 'depositChecked' ? 'deposit_checked' : 'redeem_checked';
|
|
136
|
+
const floorOption = checkedMethod === 'depositChecked' ? 'minSharesOut' : 'minAssetsOut';
|
|
137
|
+
if ((floor !== undefined && floor !== 0n) || slippageBps !== undefined) {
|
|
138
|
+
throw new core_1.AugustValidationError('INVALID_INPUT', `${handler}: the supplied IDL does not declare \`${instruction}\`, so ` +
|
|
139
|
+
`the requested ${floorOption} / slippageBps cannot be enforced. Pass ` +
|
|
140
|
+
"the SDK's bundled IDL (`Solana.constants.vaultIdl`), or omit both " +
|
|
141
|
+
'options to send the unguarded instruction.');
|
|
142
|
+
}
|
|
143
|
+
core_1.Logger.log.warn(handler, `Supplied IDL does not declare \`${instruction}\`; sending the plain ` +
|
|
144
|
+
"instruction without a slippage floor. Pass the SDK's bundled IDL to " +
|
|
145
|
+
'enable slippage protection.');
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
102
148
|
/**
|
|
103
149
|
* The vault state and share-mint supply as of a **single slot**.
|
|
104
150
|
*
|
|
@@ -265,7 +311,9 @@ async function resolveUserTokenAccountPair({ connection, owner, mints, }) {
|
|
|
265
311
|
* is given, the vault state and share mint are read to quote the shares this
|
|
266
312
|
* deposit should mint, and that quote lowered by `options.slippageBps`
|
|
267
313
|
* (default {@link DEFAULT_SLIPPAGE_BPS}) is passed as the floor; the program
|
|
268
|
-
* reverts with `SlippageExceeded` if execution would mint fewer.
|
|
314
|
+
* reverts with `SlippageExceeded` if execution would mint fewer. An `idl`
|
|
315
|
+
* that predates `deposit_checked` gets the plain `deposit` with no floor,
|
|
316
|
+
* unless `options` asks for one — then it throws {@link AugustValidationError}.
|
|
269
317
|
*/
|
|
270
318
|
async function handleSolanaDeposit({ provider, connection, network = constants_1.fallbackNetwork, vaultProgramId, vaultAddress, depositAmount, publicKey, idl, options = {}, }) {
|
|
271
319
|
try {
|
|
@@ -281,6 +329,21 @@ async function handleSolanaDeposit({ provider, connection, network = constants_1
|
|
|
281
329
|
// Before any RPC: an unusable floor should cost the caller nothing.
|
|
282
330
|
if (options.minSharesOut !== undefined)
|
|
283
331
|
validateExplicitFloor(options.minSharesOut, 'minSharesOut');
|
|
332
|
+
const _vaultProgramId = new web3_js_1.PublicKey(vaultProgramId);
|
|
333
|
+
const program = utils_1.SolanaUtils.getProgram({
|
|
334
|
+
provider,
|
|
335
|
+
idl,
|
|
336
|
+
programId: _vaultProgramId.toBase58(),
|
|
337
|
+
});
|
|
338
|
+
// Also before any RPC: a floor the caller's IDL cannot enforce is refused
|
|
339
|
+
// on the spot rather than after the mint and token-account reads.
|
|
340
|
+
const checked = sendsCheckedInstruction({
|
|
341
|
+
program,
|
|
342
|
+
checkedMethod: 'depositChecked',
|
|
343
|
+
floor: options.minSharesOut,
|
|
344
|
+
slippageBps: options.slippageBps,
|
|
345
|
+
handler: 'handleSolanaDeposit',
|
|
346
|
+
});
|
|
284
347
|
const { depositMint, shareMint, vaultVersion } = await utils_1.SolanaUtils.getVaultMints({
|
|
285
348
|
network,
|
|
286
349
|
connection,
|
|
@@ -291,14 +354,8 @@ async function handleSolanaDeposit({ provider, connection, network = constants_1
|
|
|
291
354
|
if (!depositMint || !shareMint) {
|
|
292
355
|
throw new Error('Failed to read vault mints from on-chain state');
|
|
293
356
|
}
|
|
294
|
-
const _vaultProgramId = new web3_js_1.PublicKey(vaultProgramId);
|
|
295
357
|
const _publicKey = new web3_js_1.PublicKey(publicKey);
|
|
296
358
|
const _depositMint = new web3_js_1.PublicKey(depositMint);
|
|
297
|
-
const program = utils_1.SolanaUtils.getProgram({
|
|
298
|
-
provider,
|
|
299
|
-
idl,
|
|
300
|
-
programId: _vaultProgramId.toBase58(),
|
|
301
|
-
});
|
|
302
359
|
core_1.Logger.log.info('handleSolanaDeposit', 'Program', program);
|
|
303
360
|
const vaultStatePda = vaultAddress
|
|
304
361
|
? new web3_js_1.PublicKey(vaultAddress)
|
|
@@ -394,7 +451,10 @@ async function handleSolanaDeposit({ provider, connection, network = constants_1
|
|
|
394
451
|
core_1.Logger.log.info('handleSolanaDeposit', 'Deposit mint', _depositMint?.toBase58());
|
|
395
452
|
core_1.Logger.log.info('handleSolanaDeposit', 'Signer', _publicKey.toBase58());
|
|
396
453
|
let minSharesOut;
|
|
397
|
-
if (
|
|
454
|
+
if (!checked) {
|
|
455
|
+
// The plain instruction takes no floor, so there is nothing to quote.
|
|
456
|
+
}
|
|
457
|
+
else if (options.minSharesOut !== undefined) {
|
|
398
458
|
minSharesOut = options.minSharesOut;
|
|
399
459
|
}
|
|
400
460
|
else {
|
|
@@ -417,9 +477,11 @@ async function handleSolanaDeposit({ provider, connection, network = constants_1
|
|
|
417
477
|
slippageBps: options.slippageBps ?? pricing_1.DEFAULT_SLIPPAGE_BPS,
|
|
418
478
|
});
|
|
419
479
|
}
|
|
420
|
-
core_1.Logger.log.info('handleSolanaDeposit', 'Min shares out (raw)', minSharesOut
|
|
421
|
-
const
|
|
422
|
-
|
|
480
|
+
core_1.Logger.log.info('handleSolanaDeposit', 'Min shares out (raw)', minSharesOut?.toString() ?? 'none (plain deposit)');
|
|
481
|
+
const methods = program.methods;
|
|
482
|
+
const tx = await (minSharesOut === undefined
|
|
483
|
+
? methods.deposit(depositAmountRaw)
|
|
484
|
+
: methods.depositChecked(depositAmountRaw, new anchor_1.BN(minSharesOut.toString())))
|
|
423
485
|
.accounts({
|
|
424
486
|
vaultState: vaultStatePda,
|
|
425
487
|
vaultTokenAta: vaultTokenAtaPda,
|
|
@@ -478,6 +540,9 @@ async function handleSolanaDeposit({ provider, connection, network = constants_1
|
|
|
478
540
|
* handler already reads, **net of the withdrawal fee**, and that quote
|
|
479
541
|
* lowered by `options.slippageBps` (default {@link DEFAULT_SLIPPAGE_BPS}) is
|
|
480
542
|
* passed as the floor; the program reverts with `SlippageExceeded` below it.
|
|
543
|
+
* An `idl` that predates `redeem_checked` gets the plain `redeem` with no
|
|
544
|
+
* floor, unless `options` asks for one — then it throws
|
|
545
|
+
* {@link AugustValidationError}.
|
|
481
546
|
* @throws AugustValidationError on missing wallet/programId or invalid amount,
|
|
482
547
|
* or when the wallet holds fewer shares than `redeemShares`.
|
|
483
548
|
* @throws AugustSDKError when a candidate token account's balance cannot be
|
|
@@ -503,6 +568,20 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
|
|
|
503
568
|
// Before any RPC: an unusable floor should cost the caller nothing.
|
|
504
569
|
if (options.minAssetsOut !== undefined)
|
|
505
570
|
validateExplicitFloor(options.minAssetsOut, 'minAssetsOut');
|
|
571
|
+
const _vaultProgramId = new web3_js_1.PublicKey(vaultProgramId);
|
|
572
|
+
const program = utils_1.SolanaUtils.getProgram({
|
|
573
|
+
provider,
|
|
574
|
+
idl,
|
|
575
|
+
programId: _vaultProgramId.toBase58(),
|
|
576
|
+
});
|
|
577
|
+
// See `handleSolanaDeposit`: refused before any RPC.
|
|
578
|
+
const checked = sendsCheckedInstruction({
|
|
579
|
+
program,
|
|
580
|
+
checkedMethod: 'redeemChecked',
|
|
581
|
+
floor: options.minAssetsOut,
|
|
582
|
+
slippageBps: options.slippageBps,
|
|
583
|
+
handler: 'handleSolanaRedeem',
|
|
584
|
+
});
|
|
506
585
|
const { depositMint, shareMint, vaultVersion } = await utils_1.SolanaUtils.getVaultMints({
|
|
507
586
|
network: provider.connection.rpcEndpoint.includes('devnet')
|
|
508
587
|
? 'devnet'
|
|
@@ -515,14 +594,8 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
|
|
|
515
594
|
if (!depositMint || !shareMint) {
|
|
516
595
|
throw new Error('Failed to read vault mints from on-chain state');
|
|
517
596
|
}
|
|
518
|
-
const _vaultProgramId = new web3_js_1.PublicKey(vaultProgramId);
|
|
519
597
|
const _depositMint = new web3_js_1.PublicKey(depositMint);
|
|
520
598
|
const _publicKey = new web3_js_1.PublicKey(publicKey);
|
|
521
|
-
const program = utils_1.SolanaUtils.getProgram({
|
|
522
|
-
provider,
|
|
523
|
-
idl,
|
|
524
|
-
programId: _vaultProgramId.toBase58(),
|
|
525
|
-
});
|
|
526
599
|
const vaultStatePda = vaultAddress
|
|
527
600
|
? new web3_js_1.PublicKey(vaultAddress)
|
|
528
601
|
: utils_1.SolanaUtils.deriveVaultStatePda(_vaultProgramId);
|
|
@@ -598,7 +671,10 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
|
|
|
598
671
|
// No extra reads here: the share mint (supply) and vault state (assets,
|
|
599
672
|
// offset, fee, fee recipient) came from the snapshot above.
|
|
600
673
|
let minAssetsOut;
|
|
601
|
-
if (
|
|
674
|
+
if (!checked) {
|
|
675
|
+
// The plain instruction takes no floor, so there is nothing to quote.
|
|
676
|
+
}
|
|
677
|
+
else if (options.minAssetsOut !== undefined) {
|
|
602
678
|
minAssetsOut = options.minAssetsOut;
|
|
603
679
|
}
|
|
604
680
|
else {
|
|
@@ -639,9 +715,11 @@ async function handleSolanaRedeem({ provider, connection, vaultProgramId, vaultA
|
|
|
639
715
|
core_1.Logger.log.info('handleSolanaRedeem', 'Share mint:', shareMintAddr.toBase58());
|
|
640
716
|
core_1.Logger.log.info('handleSolanaRedeem', 'Deposit mint:', _depositMint?.toBase58());
|
|
641
717
|
core_1.Logger.log.info('handleSolanaRedeem', 'Signer:', _publicKey.toBase58());
|
|
642
|
-
core_1.Logger.log.info('handleSolanaRedeem', 'Min assets out, net of fee (raw):', minAssetsOut
|
|
643
|
-
const
|
|
644
|
-
|
|
718
|
+
core_1.Logger.log.info('handleSolanaRedeem', 'Min assets out, net of fee (raw):', minAssetsOut?.toString() ?? 'none (plain redeem)');
|
|
719
|
+
const methods = program.methods;
|
|
720
|
+
const tx = await (minAssetsOut === undefined
|
|
721
|
+
? methods.redeem(redeemSharesRaw)
|
|
722
|
+
: methods.redeemChecked(redeemSharesRaw, new anchor_1.BN(minAssetsOut.toString())))
|
|
645
723
|
.accounts({
|
|
646
724
|
vaultState: vaultStatePda,
|
|
647
725
|
vaultDepositAta: vaultTokenAtaPda,
|
|
@@ -12,6 +12,19 @@ export declare function sanitizeString(input: string): string;
|
|
|
12
12
|
* …), and `cause`. Subclass constructors are NOT invoked — they may have
|
|
13
13
|
* positional signatures (`new AugustAuthError(code, message, opts)`) that would
|
|
14
14
|
* misalign if we naively passed the sanitized message as the first arg.
|
|
15
|
+
*
|
|
16
|
+
* Every write onto the clone goes through `Object.defineProperty` rather than
|
|
17
|
+
* assignment: the clone inherits `err`'s prototype, and some libraries make
|
|
18
|
+
* properties read-only there — `@solana/web3.js` defines `name` as non-writable
|
|
19
|
+
* on its error classes (`TransactionExpiredTimeoutError`, …). Assigning to an
|
|
20
|
+
* inherited non-writable property throws a `TypeError` in strict mode, which
|
|
21
|
+
* would escape from inside a caller's `catch` (e.g. `Logger.log.error`) and
|
|
22
|
+
* replace the error being reported. Defining an own property shadows the
|
|
23
|
+
* prototype's instead; each one is writable, configurable and enumerable,
|
|
24
|
+
* exactly as the plain assignment used to create it.
|
|
25
|
+
*
|
|
26
|
+
* @param err - Any caught value; non-`Error` values are returned unchanged.
|
|
27
|
+
* @returns A redacted clone for `Error` instances, otherwise `err` itself.
|
|
15
28
|
*/
|
|
16
29
|
export declare function sanitizeError(err: unknown): unknown;
|
|
17
30
|
/** Sanitize arbitrary log input (strings, errors, objects, arrays, primitives). */
|
|
@@ -72,30 +72,42 @@ function sanitizeString(input) {
|
|
|
72
72
|
* …), and `cause`. Subclass constructors are NOT invoked — they may have
|
|
73
73
|
* positional signatures (`new AugustAuthError(code, message, opts)`) that would
|
|
74
74
|
* misalign if we naively passed the sanitized message as the first arg.
|
|
75
|
+
*
|
|
76
|
+
* Every write onto the clone goes through `Object.defineProperty` rather than
|
|
77
|
+
* assignment: the clone inherits `err`'s prototype, and some libraries make
|
|
78
|
+
* properties read-only there — `@solana/web3.js` defines `name` as non-writable
|
|
79
|
+
* on its error classes (`TransactionExpiredTimeoutError`, …). Assigning to an
|
|
80
|
+
* inherited non-writable property throws a `TypeError` in strict mode, which
|
|
81
|
+
* would escape from inside a caller's `catch` (e.g. `Logger.log.error`) and
|
|
82
|
+
* replace the error being reported. Defining an own property shadows the
|
|
83
|
+
* prototype's instead; each one is writable, configurable and enumerable,
|
|
84
|
+
* exactly as the plain assignment used to create it.
|
|
85
|
+
*
|
|
86
|
+
* @param err - Any caught value; non-`Error` values are returned unchanged.
|
|
87
|
+
* @returns A redacted clone for `Error` instances, otherwise `err` itself.
|
|
75
88
|
*/
|
|
76
89
|
function sanitizeError(err) {
|
|
77
90
|
if (!(err instanceof Error))
|
|
78
91
|
return err;
|
|
79
92
|
const safe = Object.create(Object.getPrototypeOf(err));
|
|
93
|
+
const define = (key, value) => Object.defineProperty(safe, key, {
|
|
94
|
+
value,
|
|
95
|
+
writable: true,
|
|
96
|
+
configurable: true,
|
|
97
|
+
enumerable: true,
|
|
98
|
+
});
|
|
80
99
|
for (const key of Object.getOwnPropertyNames(err)) {
|
|
81
100
|
const value = err[key];
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
else if (key === 'stack' && typeof value === 'string') {
|
|
86
|
-
safe[key] = sanitizeString(value);
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
safe[key] = value;
|
|
90
|
-
}
|
|
101
|
+
const redact = (key === 'message' || key === 'stack') && typeof value === 'string';
|
|
102
|
+
define(key, redact ? sanitizeString(value) : value);
|
|
91
103
|
}
|
|
92
104
|
if (!safe.message && typeof err.message === 'string') {
|
|
93
|
-
|
|
105
|
+
define('message', sanitizeString(err.message));
|
|
94
106
|
}
|
|
95
107
|
if (!safe.stack && typeof err.stack === 'string') {
|
|
96
|
-
|
|
108
|
+
define('stack', sanitizeString(err.stack));
|
|
97
109
|
}
|
|
98
|
-
|
|
110
|
+
define('name', err.name);
|
|
99
111
|
return safe;
|
|
100
112
|
}
|
|
101
113
|
/** Sanitize arbitrary log input (strings, errors, objects, arrays, primitives). */
|
package/lib/core/auth/verify.js
CHANGED
|
@@ -15,8 +15,8 @@ async function verifyInfuraKey(key) {
|
|
|
15
15
|
}
|
|
16
16
|
async function verifyAugustKey(key) {
|
|
17
17
|
// Fast path: no key means no verification possible. Returning false here
|
|
18
|
-
// preserves the historical contract (`init()` throws a generic "API key is
|
|
19
|
-
// 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.
|
|
20
20
|
if (!key)
|
|
21
21
|
return false;
|
|
22
22
|
try {
|
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 = {
|
|
@@ -91,6 +93,7 @@ class AugustBase {
|
|
|
91
93
|
}
|
|
92
94
|
/**
|
|
93
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()`.
|
|
94
97
|
* @throws Error when `keys.august` is missing or rejected by the API.
|
|
95
98
|
*/
|
|
96
99
|
async init() {
|
package/lib/core/fetcher.d.ts
CHANGED
|
@@ -21,8 +21,8 @@ export type IFetchAugustOptions = {
|
|
|
21
21
|
/** Per-request timeout in ms. Defaults to `REQUEST_TIMEOUT_MS`. */
|
|
22
22
|
timeoutMs?: number;
|
|
23
23
|
/**
|
|
24
|
-
* @deprecated
|
|
25
|
-
* Will be removed in a future major version;
|
|
24
|
+
* @deprecated No longer has any effect: an absent `apiKey` already sends an
|
|
25
|
+
* anonymous request. Will be removed in a future major version; drop it.
|
|
26
26
|
*/
|
|
27
27
|
override?: boolean;
|
|
28
28
|
};
|
|
@@ -92,15 +92,21 @@ export declare function getPublicApiBaseUrl(): string;
|
|
|
92
92
|
import { CACHE, getSafeCache, setSafeCache } from './cache';
|
|
93
93
|
export { CACHE, getSafeCache, setSafeCache };
|
|
94
94
|
/**
|
|
95
|
-
* Make
|
|
95
|
+
* Make requests to August backend services, sending an API key when one is
|
|
96
|
+
* configured. Many backend routes — vault-linked sub-account reads, the two
|
|
97
|
+
* collateral risk routes, timelock requests — answer anonymous callers, so a
|
|
98
|
+
* missing key is not an error here: the request goes out without the
|
|
99
|
+
* `x-api-key` header and the backend decides. Routes that do require a key
|
|
100
|
+
* answer `401`, which surfaces as an `AugustAuthError` with code
|
|
101
|
+
* `AUTH_UNAUTHORIZED`.
|
|
96
102
|
* Automatically logs errors with correlation IDs for debugging.
|
|
97
|
-
* @param apiKey - August API key for
|
|
103
|
+
* @param apiKey - August API key, or `undefined` for an anonymous request
|
|
98
104
|
* @param relativeUrl - Endpoint path relative to base URL
|
|
99
105
|
* @param options - Request configuration including method and headers
|
|
100
106
|
* @returns Response object if successful
|
|
101
107
|
* @throws Error with correlation ID if request fails
|
|
102
108
|
*/
|
|
103
|
-
export declare function fetchAugustWithKey(apiKey: string, relativeUrl: string, options?: IFetchAugustOptions): Promise<Response>;
|
|
109
|
+
export declare function fetchAugustWithKey(apiKey: string | undefined, relativeUrl: string, options?: IFetchAugustOptions): Promise<Response>;
|
|
104
110
|
/**
|
|
105
111
|
* Make unauthenticated requests to August public API endpoints.
|
|
106
112
|
* Used for fetching vault metadata and public market data.
|
package/lib/core/fetcher.js
CHANGED
|
@@ -258,7 +258,7 @@ function warnOverrideDeprecation(callerTag) {
|
|
|
258
258
|
// notice must surface in the integrator's console in every environment.
|
|
259
259
|
// Logger.log.warn would downgrade it to a prod-silent Sentry breadcrumb.
|
|
260
260
|
// biome-ignore lint/suspicious/noConsole: integrator-facing deprecation notice must surface in every environment; Logger.log.warn would downgrade it to a prod-silent Sentry breadcrumb.
|
|
261
|
-
console.warn(`[@augustdigital/sdk] ${callerTag}: option "override" is deprecated and will be removed in a future major version
|
|
261
|
+
console.warn(`[@augustdigital/sdk] ${callerTag}: option "override" is deprecated and has no effect — an absent apiKey already sends an anonymous request. It will be removed in a future major version; drop it.`);
|
|
262
262
|
}
|
|
263
263
|
/**
|
|
264
264
|
* LRU cache for API responses and frequently accessed data.
|
|
@@ -384,9 +384,15 @@ function buildAugustUrl(server, relativeUrl) {
|
|
|
384
384
|
return url.toString();
|
|
385
385
|
}
|
|
386
386
|
/**
|
|
387
|
-
* Make
|
|
387
|
+
* Make requests to August backend services, sending an API key when one is
|
|
388
|
+
* configured. Many backend routes — vault-linked sub-account reads, the two
|
|
389
|
+
* collateral risk routes, timelock requests — answer anonymous callers, so a
|
|
390
|
+
* missing key is not an error here: the request goes out without the
|
|
391
|
+
* `x-api-key` header and the backend decides. Routes that do require a key
|
|
392
|
+
* answer `401`, which surfaces as an `AugustAuthError` with code
|
|
393
|
+
* `AUTH_UNAUTHORIZED`.
|
|
388
394
|
* Automatically logs errors with correlation IDs for debugging.
|
|
389
|
-
* @param apiKey - August API key for
|
|
395
|
+
* @param apiKey - August API key, or `undefined` for an anonymous request
|
|
390
396
|
* @param relativeUrl - Endpoint path relative to base URL
|
|
391
397
|
* @param options - Request configuration including method and headers
|
|
392
398
|
* @returns Response object if successful
|
|
@@ -396,12 +402,9 @@ async function fetchAugustWithKey(apiKey, relativeUrl, options) {
|
|
|
396
402
|
if (options?.override) {
|
|
397
403
|
warnOverrideDeprecation('fetchAugustWithKey');
|
|
398
404
|
}
|
|
399
|
-
if (!apiKey && !options?.override) {
|
|
400
|
-
throw new errors_1.AugustAuthError('AUTH_MISSING_KEY', 'fetchAugustWithKey: apiKey is required (set keys.august on the SDK constructor, or pass an explicit apiKey).');
|
|
401
|
-
}
|
|
402
405
|
const defaultHeaders = {
|
|
403
406
|
...sdkClientHeaders(),
|
|
404
|
-
'x-api-key': apiKey,
|
|
407
|
+
...(apiKey ? { 'x-api-key': apiKey } : {}),
|
|
405
408
|
'content-type': 'application/json',
|
|
406
409
|
accept: 'application/json',
|
|
407
410
|
};
|
package/lib/main.d.ts
CHANGED
|
@@ -356,7 +356,8 @@ export declare class AugustSDK extends AugustBase {
|
|
|
356
356
|
* @param props - Vault address, wallet address, and optional chain ID
|
|
357
357
|
* @returns Lifetime PnL data including realized and unrealized PnL in both native token and USD
|
|
358
358
|
* @throws {@link AugustHistoryUnavailableError} (`HISTORY_UNAVAILABLE`) when a
|
|
359
|
-
* live position has no indexed deposits or
|
|
359
|
+
* live position has no indexed deposits, withdrawals or priceable share
|
|
360
|
+
* transfers.
|
|
360
361
|
* @throws {@link AugustPriceUnavailableError} (`PRICE_UNAVAILABLE`) when the
|
|
361
362
|
* vault's underlying asset has no USD price — the USD fields are never
|
|
362
363
|
* computed from a stand-in price.
|
package/lib/main.js
CHANGED
|
@@ -431,7 +431,8 @@ class AugustSDK extends core_1.AugustBase {
|
|
|
431
431
|
* @param props - Vault address, wallet address, and optional chain ID
|
|
432
432
|
* @returns Lifetime PnL data including realized and unrealized PnL in both native token and USD
|
|
433
433
|
* @throws {@link AugustHistoryUnavailableError} (`HISTORY_UNAVAILABLE`) when a
|
|
434
|
-
* live position has no indexed deposits or
|
|
434
|
+
* live position has no indexed deposits, withdrawals or priceable share
|
|
435
|
+
* transfers.
|
|
435
436
|
* @throws {@link AugustPriceUnavailableError} (`PRICE_UNAVAILABLE`) when the
|
|
436
437
|
* vault's underlying asset has no USD price — the USD fields are never
|
|
437
438
|
* computed from a stand-in price.
|
|
@@ -54,9 +54,10 @@ export declare class AugustApi extends AugustBase {
|
|
|
54
54
|
* token.
|
|
55
55
|
*
|
|
56
56
|
* Backed by `GET /risk/collateral_excess_or_deficit` (60-second server-side
|
|
57
|
-
* cache), which resolves the subaccount and reads its current health factor
|
|
58
|
-
*
|
|
59
|
-
*
|
|
57
|
+
* cache), which resolves the subaccount and reads its current health factor.
|
|
58
|
+
* The backend serves this route to anonymous callers today, so no August API
|
|
59
|
+
* key is needed; pass one if you get `AUTH_UNAUTHORIZED`. Makes exactly one
|
|
60
|
+
* HTTP request and no RPC calls.
|
|
60
61
|
*
|
|
61
62
|
* @param params.subaccount Subaccount (smart-contract wallet) address.
|
|
62
63
|
* @param params.tokenAddress Collateral token address to evaluate.
|
|
@@ -86,9 +87,8 @@ export declare class AugustApi extends AugustBase {
|
|
|
86
87
|
* This is a pure, read-only simulation: the backend `POST
|
|
87
88
|
* /risk/collateral_simulation` endpoint (60-second server-side cache)
|
|
88
89
|
* computes required collateral and effective discount factors and changes
|
|
89
|
-
* no state.
|
|
90
|
-
*
|
|
91
|
-
* and no RPC calls.
|
|
90
|
+
* no state. The route is public, so no August API key is needed. Makes
|
|
91
|
+
* exactly one HTTP request and no RPC calls.
|
|
92
92
|
*
|
|
93
93
|
* @param input Simulation parameters — see {@link ICollateralSimulationInput}. `collateral_tokens` and `collateral_token_allocation` must be non-empty and equal length; when `on_platform` is `true`, both `loan_redeployed_token_*` fields are required.
|
|
94
94
|
* @returns The simulated {@link ICollateralSimulationResults}: total debt, required collateral, resulting health factor, and a per-token breakdown.
|
package/lib/modules/api/main.js
CHANGED
|
@@ -204,9 +204,10 @@ class AugustApi extends base_class_1.AugustBase {
|
|
|
204
204
|
* token.
|
|
205
205
|
*
|
|
206
206
|
* Backed by `GET /risk/collateral_excess_or_deficit` (60-second server-side
|
|
207
|
-
* cache), which resolves the subaccount and reads its current health factor
|
|
208
|
-
*
|
|
209
|
-
*
|
|
207
|
+
* cache), which resolves the subaccount and reads its current health factor.
|
|
208
|
+
* The backend serves this route to anonymous callers today, so no August API
|
|
209
|
+
* key is needed; pass one if you get `AUTH_UNAUTHORIZED`. Makes exactly one
|
|
210
|
+
* HTTP request and no RPC calls.
|
|
210
211
|
*
|
|
211
212
|
* @param params.subaccount Subaccount (smart-contract wallet) address.
|
|
212
213
|
* @param params.tokenAddress Collateral token address to evaluate.
|
|
@@ -244,9 +245,8 @@ class AugustApi extends base_class_1.AugustBase {
|
|
|
244
245
|
* This is a pure, read-only simulation: the backend `POST
|
|
245
246
|
* /risk/collateral_simulation` endpoint (60-second server-side cache)
|
|
246
247
|
* computes required collateral and effective discount factors and changes
|
|
247
|
-
* no state.
|
|
248
|
-
*
|
|
249
|
-
* and no RPC calls.
|
|
248
|
+
* no state. The route is public, so no August API key is needed. Makes
|
|
249
|
+
* exactly one HTTP request and no RPC calls.
|
|
250
250
|
*
|
|
251
251
|
* @param input Simulation parameters — see {@link ICollateralSimulationInput}. `collateral_tokens` and `collateral_token_allocation` must be non-empty and equal length; when `on_platform` is `true`, both `loan_redeployed_token_*` fields are required.
|
|
252
252
|
* @returns The simulated {@link ICollateralSimulationResults}: total debt, required collateral, resulting health factor, and a per-token breakdown.
|
|
@@ -4,7 +4,13 @@ import type { IAddress, ILoanBookInfo, ISubaccountDebank, ISubaccountTransaction
|
|
|
4
4
|
* Subaccount operation class interacting with August Subaccounts
|
|
5
5
|
* Subaccount is a smart contract wallet that serves as the fundamental infrastructure for August's platform.
|
|
6
6
|
* It functions as a cross-margin account designed for optimal capital efficiency.
|
|
7
|
-
*
|
|
7
|
+
*
|
|
8
|
+
* `getSubaccountSummary`, `getSubaccountHealthFactor`, `getSubaccountLoans`,
|
|
9
|
+
* `getSubaccountCefiPositions` and `getSubaccountOtcPositions` work without an
|
|
10
|
+
* August API key for subaccounts linked to a vault; `getSubaccountDebank` is
|
|
11
|
+
* public. `getSubaccountTransactions` needs a key authorized for the
|
|
12
|
+
* subaccount, and `getAllSubaccounts` and `getSubaccountLoanByAddress` need an
|
|
13
|
+
* admin key.
|
|
8
14
|
*/
|
|
9
15
|
export declare class AugustSubAccounts extends AugustBase {
|
|
10
16
|
private headers;
|
|
@@ -25,7 +25,13 @@ function assertSubaccountAddress(address, method) {
|
|
|
25
25
|
* Subaccount operation class interacting with August Subaccounts
|
|
26
26
|
* Subaccount is a smart contract wallet that serves as the fundamental infrastructure for August's platform.
|
|
27
27
|
* It functions as a cross-margin account designed for optimal capital efficiency.
|
|
28
|
-
*
|
|
28
|
+
*
|
|
29
|
+
* `getSubaccountSummary`, `getSubaccountHealthFactor`, `getSubaccountLoans`,
|
|
30
|
+
* `getSubaccountCefiPositions` and `getSubaccountOtcPositions` work without an
|
|
31
|
+
* August API key for subaccounts linked to a vault; `getSubaccountDebank` is
|
|
32
|
+
* public. `getSubaccountTransactions` needs a key authorized for the
|
|
33
|
+
* subaccount, and `getAllSubaccounts` and `getSubaccountLoanByAddress` need an
|
|
34
|
+
* admin key.
|
|
29
35
|
*/
|
|
30
36
|
class AugustSubAccounts extends core_1.AugustBase {
|
|
31
37
|
headers = null;
|