@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.
Files changed (51) hide show
  1. package/README.md +1 -1
  2. package/lib/adapters/evm/index.d.ts +1 -1
  3. package/lib/adapters/evm/index.js +29 -29
  4. package/lib/adapters/solana/types.d.ts +8 -0
  5. package/lib/adapters/solana/vault.actions.d.ts +6 -1
  6. package/lib/adapters/solana/vault.actions.js +99 -21
  7. package/lib/core/analytics/app-name.js +1 -1
  8. package/lib/core/analytics/constants.d.ts +10 -0
  9. package/lib/core/analytics/constants.js +17 -1
  10. package/lib/core/analytics/index.d.ts +7 -4
  11. package/lib/core/analytics/index.js +8 -4
  12. package/lib/core/analytics/instrumentation.js +8 -4
  13. package/lib/core/analytics/method-taxonomy.js +13 -0
  14. package/lib/core/analytics/metrics.d.ts +25 -10
  15. package/lib/core/analytics/metrics.js +41 -15
  16. package/lib/core/analytics/sentry.d.ts +24 -3
  17. package/lib/core/analytics/sentry.js +49 -18
  18. package/lib/core/analytics/types.d.ts +11 -4
  19. package/lib/core/analytics/user-identity.d.ts +19 -5
  20. package/lib/core/analytics/user-identity.js +35 -21
  21. package/lib/core/analytics/version.d.ts +1 -1
  22. package/lib/core/analytics/version.js +1 -1
  23. package/lib/core/auth/verify.js +7 -3
  24. package/lib/core/base.class.d.ts +8 -1
  25. package/lib/core/base.class.js +7 -1
  26. package/lib/core/constants/core.d.ts +3 -0
  27. package/lib/core/constants/core.js +3 -0
  28. package/lib/core/constants/swap-router.d.ts +16 -0
  29. package/lib/core/constants/swap-router.js +16 -0
  30. package/lib/core/errors/index.d.ts +36 -1
  31. package/lib/core/errors/index.js +40 -1
  32. package/lib/core/fetcher.d.ts +24 -5
  33. package/lib/core/fetcher.js +43 -7
  34. package/lib/main.d.ts +6 -0
  35. package/lib/main.js +6 -0
  36. package/lib/modules/api/main.d.ts +6 -6
  37. package/lib/modules/api/main.js +6 -6
  38. package/lib/modules/sub-accounts/main.d.ts +7 -1
  39. package/lib/modules/sub-accounts/main.js +7 -1
  40. package/lib/modules/vaults/getters.d.ts +151 -10
  41. package/lib/modules/vaults/getters.js +226 -30
  42. package/lib/modules/vaults/main.d.ts +5 -0
  43. package/lib/modules/vaults/main.js +5 -0
  44. package/lib/modules/vaults/write.actions.d.ts +57 -1
  45. package/lib/modules/vaults/write.actions.js +86 -2
  46. package/lib/sdk.d.ts +13171 -12810
  47. package/lib/services/debank/fetcher.js +1 -1
  48. package/lib/services/subgraph/vaults.d.ts +18 -1
  49. package/lib/services/subgraph/vaults.js +19 -3
  50. package/lib/types/vaults.d.ts +5 -0
  51. package/package.json +2 -2
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: required for allocations, health factors, and sub-account operations
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')
@@ -28,7 +28,7 @@ declare class EVMAdapter {
28
28
  * Get the normalized ethers-compatible signer
29
29
  * Converts viem WalletClient to ethers Signer if needed
30
30
  */
31
- private getSigner;
31
+ private _getSigner;
32
32
  vaultApprove(options: IContractWriteOptions): Promise<string>;
33
33
  /**
34
34
  * Approve a vault to spend a deposit token, returning a discriminated
@@ -49,7 +49,7 @@ class EVMAdapter {
49
49
  * Get the normalized ethers-compatible signer
50
50
  * Converts viem WalletClient to ethers Signer if needed
51
51
  */
52
- async getSigner() {
52
+ async _getSigner() {
53
53
  if (!this.rawSigner) {
54
54
  throw new Error('No signer provided');
55
55
  }
@@ -65,7 +65,7 @@ class EVMAdapter {
65
65
  }
66
66
  // Core EVM operations
67
67
  async vaultApprove(options) {
68
- const signer = await this.getSigner();
68
+ const signer = await this._getSigner();
69
69
  return (0, write_actions_1.vaultApprove)(signer, options);
70
70
  }
71
71
  /**
@@ -86,7 +86,7 @@ class EVMAdapter {
86
86
  * ```
87
87
  */
88
88
  async approve(options) {
89
- const signer = await this.getSigner();
89
+ const signer = await this._getSigner();
90
90
  return (0, write_actions_1.approve)(signer, options);
91
91
  }
92
92
  /**
@@ -112,7 +112,7 @@ class EVMAdapter {
112
112
  * ```
113
113
  */
114
114
  async vaultAllowance(options) {
115
- const signer = await this.getSigner();
115
+ const signer = await this._getSigner();
116
116
  return (0, read_actions_1.vaultAllowance)(signer, options);
117
117
  }
118
118
  // Vault operations (delegate to modules)
@@ -143,7 +143,7 @@ class EVMAdapter {
143
143
  * ```
144
144
  */
145
145
  async vaultDeposit(options) {
146
- const signer = await this.getSigner();
146
+ const signer = await this._getSigner();
147
147
  return (0, write_actions_1.vaultDeposit)(signer, options);
148
148
  }
149
149
  /**
@@ -171,7 +171,7 @@ class EVMAdapter {
171
171
  * ```
172
172
  */
173
173
  async vaultRequestRedeem(options) {
174
- const signer = await this.getSigner();
174
+ const signer = await this._getSigner();
175
175
  return (0, write_actions_1.vaultRequestRedeem)(signer, options);
176
176
  }
177
177
  /**
@@ -197,7 +197,7 @@ class EVMAdapter {
197
197
  * ```
198
198
  */
199
199
  async depositNative(options) {
200
- const signer = await this.getSigner();
200
+ const signer = await this._getSigner();
201
201
  return (0, write_actions_1.depositNative)(signer, options);
202
202
  }
203
203
  /**
@@ -227,7 +227,7 @@ class EVMAdapter {
227
227
  * ```
228
228
  */
229
229
  async swapAndDeposit(options) {
230
- const signer = await this.getSigner();
230
+ const signer = await this._getSigner();
231
231
  return (0, write_actions_1.swapAndDeposit)(signer, options);
232
232
  }
233
233
  /**
@@ -239,7 +239,7 @@ class EVMAdapter {
239
239
  * @returns The transaction hash of the `deposit` call.
240
240
  */
241
241
  async depositViaSwapRouter(options) {
242
- const signer = await this.getSigner();
242
+ const signer = await this._getSigner();
243
243
  return (0, write_actions_1.depositViaSwapRouter)(signer, options);
244
244
  }
245
245
  /**
@@ -251,7 +251,7 @@ class EVMAdapter {
251
251
  * @returns The transaction hash of the `depositNativeToken` call.
252
252
  */
253
253
  async depositNativeViaSwapRouter(options) {
254
- const signer = await this.getSigner();
254
+ const signer = await this._getSigner();
255
255
  return (0, write_actions_1.depositNativeViaSwapRouter)(signer, options);
256
256
  }
257
257
  /**
@@ -277,7 +277,7 @@ class EVMAdapter {
277
277
  * ```
278
278
  */
279
279
  async swapRouterDeposit(options) {
280
- const signer = await this.getSigner();
280
+ const signer = await this._getSigner();
281
281
  return (0, write_actions_1.swapRouterDeposit)(signer, options);
282
282
  }
283
283
  /**
@@ -296,7 +296,7 @@ class EVMAdapter {
296
296
  * ```
297
297
  */
298
298
  async getSwapRouterDepositResult(options) {
299
- const signer = await this.getSigner();
299
+ const signer = await this._getSigner();
300
300
  return (0, swap_router_1.getSwapRouterDepositResult)(signer, options);
301
301
  }
302
302
  /**
@@ -329,7 +329,7 @@ class EVMAdapter {
329
329
  * ```
330
330
  */
331
331
  async vaultRedeem(options) {
332
- const signer = await this.getSigner();
332
+ const signer = await this._getSigner();
333
333
  return (0, write_actions_1.vaultRedeem)(signer, options);
334
334
  }
335
335
  /**
@@ -362,23 +362,23 @@ class EVMAdapter {
362
362
  * ```
363
363
  */
364
364
  async claimWithdrawal(options) {
365
- const signer = await this.getSigner();
365
+ const signer = await this._getSigner();
366
366
  return (0, write_actions_1.claimWithdrawal)(signer, options);
367
367
  }
368
368
  async sendersWhitelistAddress(options) {
369
- const signer = await this.getSigner();
369
+ const signer = await this._getSigner();
370
370
  return (0, read_actions_1.sendersWhitelistAddress)(signer, options);
371
371
  }
372
372
  async isWhitelisted(options) {
373
- const signer = await this.getSigner();
373
+ const signer = await this._getSigner();
374
374
  return (0, read_actions_1.isWhitelisted)(signer, options);
375
375
  }
376
376
  async getDeposited(options) {
377
- const signer = await this.getSigner();
377
+ const signer = await this._getSigner();
378
378
  return (0, read_actions_1.getDeposited)(signer, options);
379
379
  }
380
380
  async getRemainingAllocations(options) {
381
- const signer = await this.getSigner();
381
+ const signer = await this._getSigner();
382
382
  return (0, read_actions_1.getRemainingAllocations)(signer, options);
383
383
  }
384
384
  /**
@@ -397,7 +397,7 @@ class EVMAdapter {
397
397
  * ```
398
398
  */
399
399
  async previewDeposit(options) {
400
- const signer = await this.getSigner();
400
+ const signer = await this._getSigner();
401
401
  return (0, read_actions_1.previewDeposit)(signer, options);
402
402
  }
403
403
  /**
@@ -415,7 +415,7 @@ class EVMAdapter {
415
415
  * ```
416
416
  */
417
417
  async previewRedeem(options) {
418
- const signer = await this.getSigner();
418
+ const signer = await this._getSigner();
419
419
  return (0, read_actions_1.previewRedeem)(signer, options);
420
420
  }
421
421
  /**
@@ -430,7 +430,7 @@ class EVMAdapter {
430
430
  * ```
431
431
  */
432
432
  async allowance(options) {
433
- const signer = await this.getSigner();
433
+ const signer = await this._getSigner();
434
434
  return (0, read_actions_1.allowance)(signer, options);
435
435
  }
436
436
  /**
@@ -444,7 +444,7 @@ class EVMAdapter {
444
444
  * ```
445
445
  */
446
446
  async balanceOf(options) {
447
- const signer = await this.getSigner();
447
+ const signer = await this._getSigner();
448
448
  return (0, read_actions_1.balanceOf)(signer, options);
449
449
  }
450
450
  /**
@@ -459,7 +459,7 @@ class EVMAdapter {
459
459
  * ```
460
460
  */
461
461
  async maxDeposit(options) {
462
- const signer = await this.getSigner();
462
+ const signer = await this._getSigner();
463
463
  return (0, read_actions_1.maxDeposit)(signer, options);
464
464
  }
465
465
  /**
@@ -475,7 +475,7 @@ class EVMAdapter {
475
475
  * ```
476
476
  */
477
477
  async getIdleLiquidity(options) {
478
- const signer = await this.getSigner();
478
+ const signer = await this._getSigner();
479
479
  return (0, read_actions_1.getIdleLiquidity)(signer, options);
480
480
  }
481
481
  /**
@@ -489,7 +489,7 @@ class EVMAdapter {
489
489
  * ```
490
490
  */
491
491
  async lagDuration(options) {
492
- const signer = await this.getSigner();
492
+ const signer = await this._getSigner();
493
493
  return (0, read_actions_1.lagDuration)(signer, options);
494
494
  }
495
495
  /**
@@ -504,7 +504,7 @@ class EVMAdapter {
504
504
  * ```
505
505
  */
506
506
  async getWithdrawalEpoch(options) {
507
- const signer = await this.getSigner();
507
+ const signer = await this._getSigner();
508
508
  return (0, read_actions_1.getWithdrawalEpoch)(signer, options);
509
509
  }
510
510
  /**
@@ -521,7 +521,7 @@ class EVMAdapter {
521
521
  * ```
522
522
  */
523
523
  async getBurnableAmountByReceiver(options) {
524
- const signer = await this.getSigner();
524
+ const signer = await this._getSigner();
525
525
  return (0, read_actions_1.getBurnableAmountByReceiver)(signer, options);
526
526
  }
527
527
  /**
@@ -536,7 +536,7 @@ class EVMAdapter {
536
536
  * ```
537
537
  */
538
538
  async getRequirementByDate(options) {
539
- const signer = await this.getSigner();
539
+ const signer = await this._getSigner();
540
540
  return (0, read_actions_1.getRequirementByDate)(signer, options);
541
541
  }
542
542
  /**
@@ -551,7 +551,7 @@ class EVMAdapter {
551
551
  * ```
552
552
  */
553
553
  async getScheduledTransactionsByDate(options) {
554
- const signer = await this.getSigner();
554
+ const signer = await this._getSigner();
555
555
  return (0, read_actions_1.getScheduledTransactionsByDate)(signer, options);
556
556
  }
557
557
  }
@@ -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 (options.minSharesOut !== undefined) {
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.toString());
421
- const tx = await program.methods
422
- .depositChecked(depositAmountRaw, new anchor_1.BN(minSharesOut.toString()))
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 (options.minAssetsOut !== undefined) {
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.toString());
643
- const tx = await program.methods
644
- .redeemChecked(redeemSharesRaw, new anchor_1.BN(minAssetsOut.toString()))
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,
@@ -29,7 +29,7 @@ const errors_1 = require("../errors");
29
29
  * characters, or is shaped like an EVM address.
30
30
  */
31
31
  function validateAppName(value) {
32
- const docsHint = 'See https://docs.augustdigital.io/developers/typescript-sdk#app-name';
32
+ const docsHint = 'See https://docs.augustdigital.io/developers/typescript-sdk/javascript-sdk#app-name';
33
33
  if (typeof value !== 'string' || value.trim().length === 0) {
34
34
  throw new errors_1.AugustValidationError('INVALID_INPUT', `August SDK: \`appName\` is required. Pass a stable kebab-case slug identifying your application (e.g. "acme-trader"). ${docsHint}`);
35
35
  }
@@ -3,3 +3,13 @@
3
3
  * This is an internal constant - not exposed to SDK users.
4
4
  */
5
5
  export declare const SENTRY_DSN = "https://ca39246016d0b43154f0640314cbd3b5@o4507215496609792.ingest.de.sentry.io/4511864614813776";
6
+ /**
7
+ * `appName` slugs of applications August/Upshift operate themselves.
8
+ *
9
+ * Traffic from these is tagged `partner.tier: 'internal'` so that
10
+ * `partner.tier:unverified` in Sentry already means "external integrator"
11
+ * before the backend verification endpoint exists. Anything not listed stays
12
+ * `unverified`; the future verified flow adds a `verified` tier alongside
13
+ * rather than replacing this list.
14
+ */
15
+ export declare const FIRST_PARTY_APP_NAMES: ReadonlySet<string>;
@@ -1,9 +1,25 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SENTRY_DSN = void 0;
3
+ exports.FIRST_PARTY_APP_NAMES = exports.SENTRY_DSN = void 0;
4
4
  /**
5
5
  * Sentry DSN for SDK analytics.
6
6
  * This is an internal constant - not exposed to SDK users.
7
7
  */
8
8
  exports.SENTRY_DSN = 'https://ca39246016d0b43154f0640314cbd3b5@o4507215496609792.ingest.de.sentry.io/4511864614813776';
9
+ /**
10
+ * `appName` slugs of applications August/Upshift operate themselves.
11
+ *
12
+ * Traffic from these is tagged `partner.tier: 'internal'` so that
13
+ * `partner.tier:unverified` in Sentry already means "external integrator"
14
+ * before the backend verification endpoint exists. Anything not listed stays
15
+ * `unverified`; the future verified flow adds a `verified` tier alongside
16
+ * rather than replacing this list.
17
+ */
18
+ exports.FIRST_PARTY_APP_NAMES = new Set([
19
+ 'upshift-web-app',
20
+ 'upshift-earn',
21
+ 'upshift-prime',
22
+ 'august-cli',
23
+ 'august-mcp',
24
+ ]);
9
25
  //# sourceMappingURL=constants.js.map
@@ -2,9 +2,10 @@
2
2
  * Analytics module for SDK usage tracking via Sentry.
3
3
  *
4
4
  * Features:
5
- * - User identification (API key hash, wallet, fingerprint, session)
6
- * - Method call tracking with timing
7
- * - Cache hit/miss rate monitoring
5
+ * - User identification (API key hash, wallet, domain, fingerprint, session)
6
+ * - Method call tracking with timing, classified by {@link METHOD_CATEGORIES}
7
+ * - Application attribution (`app.name`, `partner.id`, `partner.tier`,
8
+ * `sdk.surface`) on every event and span
8
9
  * - API response time tracking
9
10
  * - Chain/network usage distribution
10
11
  *
@@ -12,12 +13,14 @@
12
13
  * ```typescript
13
14
  * // Analytics enabled by default
14
15
  * const sdk = new AugustSDK({
16
+ * appName: 'acme-trader',
15
17
  * providers: { 1: 'https://...' },
16
18
  * keys: { august: '...' },
17
19
  * });
18
20
  *
19
21
  * // Opt-out of analytics
20
22
  * const sdk = new AugustSDK({
23
+ * appName: 'acme-trader',
21
24
  * providers: { 1: 'https://...' },
22
25
  * keys: { august: '...' },
23
26
  * analytics: { enabled: false },
@@ -29,7 +32,7 @@ export { hashApiKey, getSessionId, generateFingerprint, createUserIdentity, getU
29
32
  export { initializeSentry, updateUser, clearUser, isAnalyticsEnabled, getSentry, resetAnalytics, captureSdkException, } from './sentry';
30
33
  export { getSentrySDK, getSentryRuntime } from './sentry-runtime';
31
34
  export { readEnv, isAnalyticsDisabledViaEnv, isAnalyticsForcedOnViaEnv, isNodeDevOrTestEnv, } from './env';
32
- export { trackApiCall, trackNetworkSwitch, getCacheStats, resetCacheStats, } from './metrics';
35
+ export { trackApiCall, trackNetworkSwitch, trackKeyVerification, getCacheStats, resetCacheStats, } from './metrics';
33
36
  export { sanitizeArgs, sanitizeObject, computeArgShape } from './sanitize';
34
37
  export { withMethodTracking, withSyncMethodTracking, instrumentClass, } from './instrumentation';
35
38
  export { METHOD_CATEGORIES, getMethodCategory, type MethodCategory, } from './method-taxonomy';
@@ -3,9 +3,10 @@
3
3
  * Analytics module for SDK usage tracking via Sentry.
4
4
  *
5
5
  * Features:
6
- * - User identification (API key hash, wallet, fingerprint, session)
7
- * - Method call tracking with timing
8
- * - Cache hit/miss rate monitoring
6
+ * - User identification (API key hash, wallet, domain, fingerprint, session)
7
+ * - Method call tracking with timing, classified by {@link METHOD_CATEGORIES}
8
+ * - Application attribution (`app.name`, `partner.id`, `partner.tier`,
9
+ * `sdk.surface`) on every event and span
9
10
  * - API response time tracking
10
11
  * - Chain/network usage distribution
11
12
  *
@@ -13,12 +14,14 @@
13
14
  * ```typescript
14
15
  * // Analytics enabled by default
15
16
  * const sdk = new AugustSDK({
17
+ * appName: 'acme-trader',
16
18
  * providers: { 1: 'https://...' },
17
19
  * keys: { august: '...' },
18
20
  * });
19
21
  *
20
22
  * // Opt-out of analytics
21
23
  * const sdk = new AugustSDK({
24
+ * appName: 'acme-trader',
22
25
  * providers: { 1: 'https://...' },
23
26
  * keys: { august: '...' },
24
27
  * analytics: { enabled: false },
@@ -26,7 +29,7 @@
26
29
  * ```
27
30
  */
28
31
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.chainIdToTagValue = exports.getMethodCategory = exports.METHOD_CATEGORIES = exports.instrumentClass = exports.withSyncMethodTracking = exports.withMethodTracking = exports.computeArgShape = exports.sanitizeObject = exports.sanitizeArgs = exports.resetCacheStats = exports.getCacheStats = exports.trackNetworkSwitch = exports.trackApiCall = exports.isNodeDevOrTestEnv = exports.isAnalyticsForcedOnViaEnv = exports.isAnalyticsDisabledViaEnv = exports.readEnv = exports.getSentryRuntime = exports.getSentrySDK = exports.captureSdkException = exports.resetAnalytics = exports.getSentry = exports.isAnalyticsEnabled = exports.clearUser = exports.updateUser = exports.initializeSentry = exports.getUserId = exports.createUserIdentity = exports.generateFingerprint = exports.getSessionId = exports.hashApiKey = void 0;
32
+ exports.chainIdToTagValue = exports.getMethodCategory = exports.METHOD_CATEGORIES = exports.instrumentClass = exports.withSyncMethodTracking = exports.withMethodTracking = exports.computeArgShape = exports.sanitizeObject = exports.sanitizeArgs = exports.resetCacheStats = exports.getCacheStats = exports.trackKeyVerification = exports.trackNetworkSwitch = exports.trackApiCall = exports.isNodeDevOrTestEnv = exports.isAnalyticsForcedOnViaEnv = exports.isAnalyticsDisabledViaEnv = exports.readEnv = exports.getSentryRuntime = exports.getSentrySDK = exports.captureSdkException = exports.resetAnalytics = exports.getSentry = exports.isAnalyticsEnabled = exports.clearUser = exports.updateUser = exports.initializeSentry = exports.getUserId = exports.createUserIdentity = exports.generateFingerprint = exports.getSessionId = exports.hashApiKey = void 0;
30
33
  // User identity utilities
31
34
  var user_identity_1 = require("./user-identity");
32
35
  Object.defineProperty(exports, "hashApiKey", { enumerable: true, get: function () { return user_identity_1.hashApiKey; } });
@@ -57,6 +60,7 @@ Object.defineProperty(exports, "isNodeDevOrTestEnv", { enumerable: true, get: fu
57
60
  var metrics_1 = require("./metrics");
58
61
  Object.defineProperty(exports, "trackApiCall", { enumerable: true, get: function () { return metrics_1.trackApiCall; } });
59
62
  Object.defineProperty(exports, "trackNetworkSwitch", { enumerable: true, get: function () { return metrics_1.trackNetworkSwitch; } });
63
+ Object.defineProperty(exports, "trackKeyVerification", { enumerable: true, get: function () { return metrics_1.trackKeyVerification; } });
60
64
  Object.defineProperty(exports, "getCacheStats", { enumerable: true, get: function () { return metrics_1.getCacheStats; } });
61
65
  Object.defineProperty(exports, "resetCacheStats", { enumerable: true, get: function () { return metrics_1.resetCacheStats; } });
62
66
  // Sanitization utilities
@@ -40,6 +40,10 @@ function withMethodTracking(methodName, method, getChainId) {
40
40
  op: 'sdk.method',
41
41
  name: methodName,
42
42
  attributes: {
43
+ // Scope tags only reach the root span in Sentry's span dataset;
44
+ // child spans need the identity copied on as attributes or they
45
+ // cannot be filtered by app or partner.
46
+ ...(0, sentry_1.getSpanAttributes)(),
43
47
  chainId: chainId?.toString() || 'unknown',
44
48
  'sdk.chain': (0, chain_name_1.chainIdToTagValue)(chainId),
45
49
  'sdk.category': category,
@@ -222,12 +226,12 @@ function trackSyncMethodCall(methodName, metrics, args) {
222
226
  // Measurements omitted: sync methods have no span of their own, so setMeasurement
223
227
  // would attach to whatever parent transaction happens to be active on the scope,
224
228
  // overwriting its counters. The breadcrumb above already captures success/failure.
229
+ // `sdk.category` and `sdk.chain` stay off the global scope: concurrent sync
230
+ // calls would race on them and stamp stale values onto unrelated events (the
231
+ // breadcrumb above carries both per call). `sdk.last_chainId` stays because
232
+ // `isMutedChainEvent` in sentry.ts reads it to drop muted-chain events.
225
233
  sdk.setTag('sdk.last_sync_method', methodName);
226
- if (metrics.category) {
227
- sdk.setTag('sdk.category', metrics.category);
228
- }
229
234
  if (metrics.chainId !== undefined) {
230
- sdk.setTag('sdk.chain', (0, chain_name_1.chainIdToTagValue)(metrics.chainId));
231
235
  sdk.setTag('sdk.last_chainId', metrics.chainId.toString());
232
236
  }
233
237
  }