@augustdigital/sdk 8.15.0 → 8.16.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.
@@ -19,7 +19,7 @@ export declare const Solana: {
19
19
  isSolanaAddress: typeof import("./utils").isSolanaAddress;
20
20
  isSolana: (signature: string) => boolean;
21
21
  getProgram: ({ provider, idl, programId, network, }: {
22
- idl: any;
22
+ idl?: any;
23
23
  programId?: string;
24
24
  } & import("./types").ISolanaConnectionOptions) => import("@coral-xyz/anchor").Program<any>;
25
25
  getProvider: ({ connection, publicKey, signTransaction, }: {
@@ -83,9 +83,6 @@ export declare const Solana: {
83
83
  "mainnet-beta": {
84
84
  vault: string;
85
85
  };
86
- testnet: {
87
- vault: string;
88
- };
89
86
  localnet: {
90
87
  vault: string;
91
88
  };
@@ -128,7 +125,36 @@ declare class SolanaAdapter {
128
125
  get connection(): web3.Connection;
129
126
  get provider(): AnchorProvider;
130
127
  setWalletProvider(_publicKey: PublicKey | string, signTransaction: (<T extends Transaction | web3.VersionedTransaction>(transaction: T) => Promise<T>) | undefined): void;
131
- getProgram(programIdl: any): import("@coral-xyz/anchor").Program<any>;
128
+ /**
129
+ * Build an Anchor `Program` bound to this adapter's provider and network.
130
+ *
131
+ * The program id is resolved as: explicit `programId` → the `address` carried
132
+ * by a custom `programIdl` → the canonical deployment for this adapter's
133
+ * network. A copy of the SDK's bundled `vaultIdl` defers to the network
134
+ * default (its embedded `address` is a build stamp, not network-aware), so
135
+ * forwarding it on devnet never silently targets the mainnet program.
136
+ *
137
+ * @param programIdl - Anchor IDL to bind. Defaults to the SDK's bundled
138
+ * `august_vault` IDL. A custom IDL's `address` is honoured when it differs
139
+ * from the bundled build stamp.
140
+ * @param programId - Base58 program id that overrides both the IDL's address
141
+ * and the network default. Use this to target a non-canonical deployment.
142
+ * @returns An Anchor `Program` for the resolved program id. No RPC is made —
143
+ * construction is offline.
144
+ * @throws {@link AugustValidationError} if no program id can be resolved
145
+ * because this adapter's network has no canonical deployment (e.g.
146
+ * `testnet`) and neither `programId` nor a custom IDL address was supplied.
147
+ *
148
+ * @example
149
+ * ```ts
150
+ * // canonical program on the adapter's network
151
+ * const program = sdk.solana.getProgram();
152
+ *
153
+ * // a different deployment, same interface
154
+ * const legacy = sdk.solana.getProgram(vaultIdl, '7B8n9vL51b6ibqRAd1adZsi3x3kxtq5NZaondh22Vkyq');
155
+ * ```
156
+ */
157
+ getProgram(programIdl?: any, programId?: string): import("@coral-xyz/anchor").Program<any>;
132
158
  getVaultState(vaultProgramId: PublicKey | string, idl: any, vaultAddress?: PublicKey | string): Promise<{
133
159
  vaultState: unknown | null;
134
160
  depositMintDecimals: number | null;
@@ -193,6 +219,15 @@ declare class SolanaAdapter {
193
219
  * @param redeemShares `bigint` (raw share units) or `number` (UI amount).
194
220
  */
195
221
  vaultRedeem(vaultProgramId: PublicKey | string, idl: any, publicKey: PublicKey | string, redeemShares: number | bigint, sendTransaction: (transaction: Transaction | web3.VersionedTransaction, connection: Connection, options?: SendTransactionOptions) => Promise<web3.TransactionSignature>, vaultAddress?: PublicKey | string): Promise<any>;
222
+ /**
223
+ * Canonical program id for a program type on this adapter's network.
224
+ *
225
+ * @param type - Program to look up. Only `'vault'` (august_vault) exists today.
226
+ * @returns The base58 program id.
227
+ * @throws {@link AugustValidationError} if the canonical program is not
228
+ * deployed on this adapter's network (e.g. `testnet`). Previously an
229
+ * unmapped network threw a bare `TypeError`.
230
+ */
196
231
  getProgramId(type: 'vault'): string;
197
232
  }
198
233
  export default SolanaAdapter;
@@ -46,6 +46,7 @@ const web3_js_1 = require("@solana/web3.js");
46
46
  const utils_1 = require("./utils");
47
47
  const vault_actions_1 = require("./vault.actions");
48
48
  const constants_1 = require("./constants");
49
+ const core_1 = require("../../core");
49
50
  exports.Solana = {
50
51
  utils: utils_1.SolanaUtils,
51
52
  constants: SolanaConstants,
@@ -108,11 +109,41 @@ class SolanaAdapter {
108
109
  });
109
110
  }
110
111
  }
111
- getProgram(programIdl) {
112
+ /**
113
+ * Build an Anchor `Program` bound to this adapter's provider and network.
114
+ *
115
+ * The program id is resolved as: explicit `programId` → the `address` carried
116
+ * by a custom `programIdl` → the canonical deployment for this adapter's
117
+ * network. A copy of the SDK's bundled `vaultIdl` defers to the network
118
+ * default (its embedded `address` is a build stamp, not network-aware), so
119
+ * forwarding it on devnet never silently targets the mainnet program.
120
+ *
121
+ * @param programIdl - Anchor IDL to bind. Defaults to the SDK's bundled
122
+ * `august_vault` IDL. A custom IDL's `address` is honoured when it differs
123
+ * from the bundled build stamp.
124
+ * @param programId - Base58 program id that overrides both the IDL's address
125
+ * and the network default. Use this to target a non-canonical deployment.
126
+ * @returns An Anchor `Program` for the resolved program id. No RPC is made —
127
+ * construction is offline.
128
+ * @throws {@link AugustValidationError} if no program id can be resolved
129
+ * because this adapter's network has no canonical deployment (e.g.
130
+ * `testnet`) and neither `programId` nor a custom IDL address was supplied.
131
+ *
132
+ * @example
133
+ * ```ts
134
+ * // canonical program on the adapter's network
135
+ * const program = sdk.solana.getProgram();
136
+ *
137
+ * // a different deployment, same interface
138
+ * const legacy = sdk.solana.getProgram(vaultIdl, '7B8n9vL51b6ibqRAd1adZsi3x3kxtq5NZaondh22Vkyq');
139
+ * ```
140
+ */
141
+ getProgram(programIdl, programId) {
112
142
  return utils_1.SolanaUtils.getProgram({
113
143
  network: this._network,
114
144
  provider: this._provider,
115
145
  idl: programIdl,
146
+ programId,
116
147
  });
117
148
  }
118
149
  async getVaultState(vaultProgramId, idl, vaultAddress) {
@@ -238,9 +269,22 @@ class SolanaAdapter {
238
269
  sendTransaction,
239
270
  });
240
271
  }
272
+ /**
273
+ * Canonical program id for a program type on this adapter's network.
274
+ *
275
+ * @param type - Program to look up. Only `'vault'` (august_vault) exists today.
276
+ * @returns The base58 program id.
277
+ * @throws {@link AugustValidationError} if the canonical program is not
278
+ * deployed on this adapter's network (e.g. `testnet`). Previously an
279
+ * unmapped network threw a bare `TypeError`.
280
+ */
241
281
  getProgramId(type) {
242
- const network = this._network;
243
- return constants_1.programIds[network][type];
282
+ const deployment = (0, constants_1.getDeployedProgramIds)(this._network);
283
+ if (!deployment) {
284
+ throw new core_1.AugustValidationError('INVALID_INPUT', `No canonical august_vault deployment for Solana network '${this._network}'. ` +
285
+ `Deployed networks: ${Object.keys(constants_1.programIds).join(', ')}.`);
286
+ }
287
+ return deployment[type];
244
288
  }
245
289
  }
246
290
  exports.default = SolanaAdapter;
@@ -9,7 +9,7 @@ import { isSolanaAddress } from '../../core/helpers/chain-address';
9
9
  export { isSolanaAddress };
10
10
  declare function isSolana(signature: string): boolean;
11
11
  declare function getProgram({ provider, idl, programId, network, }: {
12
- idl: any;
12
+ idl?: any;
13
13
  programId?: string;
14
14
  } & ISolanaConnectionOptions): Program<any>;
15
15
  declare function getBestRpcEndpoint({ endpoint, network, connection, }: ISolanaConnectionOptions): Promise<"http://127.0.0.1:8899" | `https://${string}`>;
@@ -132,9 +132,6 @@ export declare const SolanaUtils: {
132
132
  "mainnet-beta": {
133
133
  vault: string;
134
134
  };
135
- testnet: {
136
- vault: string;
137
- };
138
135
  localnet: {
139
136
  vault: string;
140
137
  };
@@ -39,18 +39,32 @@ function isSolana(signature) {
39
39
  return (signature.length >= 80 && signature.length <= 100);
40
40
  }
41
41
  function getProgram({ provider, idl, programId, network, }) {
42
- if (!idl) {
43
- return new anchor_1.Program(constants_1.vaultIdl, provider);
42
+ const baseIdl = idl ?? constants_1.vaultIdl;
43
+ // Precedence: explicit `programId` → a custom IDL's `address` → the network
44
+ // default → the bundled IDL's embedded `address`.
45
+ //
46
+ // The custom-address check compares by VALUE, not reference. Keying off
47
+ // `idl === vaultIdl` broke for a structurally-identical-but-not-reference-equal
48
+ // copy (second bundle instance, or JSON round-tripped), silently retargeting
49
+ // devnet callers at mainnet. Every copy carries the same build stamp, so it
50
+ // still defers to the network default — but a genuinely custom IDL is honoured.
51
+ const suppliedAddress = typeof baseIdl?.address === 'string' && baseIdl.address !== constants_1.vaultIdl.address
52
+ ? baseIdl.address
53
+ : undefined;
54
+ const explicitId = programId ?? suppliedAddress;
55
+ if (explicitId) {
56
+ return new anchor_1.Program({ ...baseIdl, address: explicitId }, provider);
44
57
  }
45
- // If programId is provided, create a modified IDL with the correct address
46
- if (programId) {
47
- const modifiedIdl = {
48
- ...idl,
49
- address: programId,
50
- };
51
- return new anchor_1.Program(modifiedIdl, provider);
58
+ if (network) {
59
+ const networkDefault = (0, constants_1.getDeployedProgramIds)(network)?.vault;
60
+ if (!networkDefault) {
61
+ throw new core_1.AugustValidationError('INVALID_INPUT', `No canonical august_vault deployment for Solana network '${network}'. ` +
62
+ `Deployed networks: ${Object.keys(constants_1.programIds).join(', ')}. ` +
63
+ `Pass an explicit \`programId\` (or an IDL carrying the target \`address\`) to target a program on this network.`);
64
+ }
65
+ return new anchor_1.Program({ ...baseIdl, address: networkDefault }, provider);
52
66
  }
53
- return new anchor_1.Program(idl, provider);
67
+ return new anchor_1.Program(baseIdl, provider);
54
68
  }
55
69
  // ============================================================================
56
70
  // SOLANA PROVIDERS
@@ -77,6 +77,10 @@ exports.METHOD_CATEGORIES = {
77
77
  fetchUserTokenBalance: 'read.solana',
78
78
  fetchUserShareBalance: 'read.solana',
79
79
  fetchUserShareBalanceRaw: 'read.solana',
80
+ // Both are offline resolvers (no RPC) — classified so the partner dashboard
81
+ // sees program-targeting calls instead of dropping them into 'unknown'.
82
+ getProgram: 'read.solana',
83
+ getProgramId: 'read.solana',
80
84
  // submitTransaction broadcasts a signed Soroban tx — it mutates on-chain
81
85
  // state and belongs in the write bucket even though Stellar adapter call
82
86
  // shape mirrors the read helpers (returns a hash, takes signed XDR).
@@ -3,4 +3,4 @@
3
3
  * Generated during publish from package.json version
4
4
  * This file is gitignored and created at publish time
5
5
  */
6
- export declare const SDK_VERSION = "8.15.0";
6
+ export declare const SDK_VERSION = "8.16.0";
@@ -6,5 +6,5 @@ exports.SDK_VERSION = void 0;
6
6
  * Generated during publish from package.json version
7
7
  * This file is gitignored and created at publish time
8
8
  */
9
- exports.SDK_VERSION = '8.15.0';
9
+ exports.SDK_VERSION = '8.16.0';
10
10
  //# sourceMappingURL=version.js.map
@@ -1,4 +1,4 @@
1
- import type { IAddress, IContractRunner, INormalizedNumber, IPoolFunctions, ITokenizedVault, IVault } from '../../types';
1
+ import type { IAddress, IContractRunner, INormalizedNumber, IPoolFunctions, ITokenizedVault, IVault, IVaultFreshness } from '../../types';
2
2
  import { ethers } from 'ethers';
3
3
  import type { WalletClient } from 'viem';
4
4
  /**
@@ -59,6 +59,24 @@ export declare function getYieldLastRealizedOn(provider: IContractRunner, vaultA
59
59
  * Shared across all chain adapters (EVM, Solana, Stellar).
60
60
  */
61
61
  export declare function formatVaultApy(tokenizedVault: ITokenizedVault): IVault['apy'];
62
+ /**
63
+ * Map the backend `freshness` object onto the camelCased {@link IVaultFreshness}
64
+ * shape carried on `IVault`. Shared across all chain adapters (EVM, Solana,
65
+ * Stellar) so every surface reports provenance identically.
66
+ *
67
+ * Each of the three stamps is passed through independently: a missing member
68
+ * becomes `null` and is never defaulted from one of the others. That is the point
69
+ * of the object — `apy_computed_at` and `share_ratio_snapshot_at` describe two
70
+ * different pipelines, and collapsing them would erase the very staleness signal
71
+ * (snapshot newer than APY) the field exists to expose.
72
+ *
73
+ * @param tokenizedVault - Backend tokenized-vault payload. `freshness` is absent on
74
+ * responses predating the backend change, and may be explicitly null.
75
+ * @returns The mapped freshness object, or `null` when the backend reported none.
76
+ * Values are the backend's RFC 3339 UTC strings verbatim — no reformatting, so
77
+ * the trailing `Z` is preserved.
78
+ */
79
+ export declare function mapVaultFreshness(tokenizedVault: ITokenizedVault | undefined | null): IVaultFreshness | null;
62
80
  /**
63
81
  * Map strategists from backend subaccounts or hardcoded list.
64
82
  * Shared across all chain adapters.
@@ -6,6 +6,7 @@ exports.getVaultRewards = getVaultRewards;
6
6
  exports.getIdleAssets = getIdleAssets;
7
7
  exports.getYieldLastRealizedOn = getYieldLastRealizedOn;
8
8
  exports.formatVaultApy = formatVaultApy;
9
+ exports.mapVaultFreshness = mapVaultFreshness;
9
10
  exports.mapStrategists = mapStrategists;
10
11
  exports.mapComposabilityIntegrations = mapComposabilityIntegrations;
11
12
  exports.backendTvlToNormalizedBn = backendTvlToNormalizedBn;
@@ -235,6 +236,33 @@ function formatVaultApy(tokenizedVault) {
235
236
  underlyingApy: (reported_apy?.underlying_apy ?? 0) * 100,
236
237
  };
237
238
  }
239
+ /**
240
+ * Map the backend `freshness` object onto the camelCased {@link IVaultFreshness}
241
+ * shape carried on `IVault`. Shared across all chain adapters (EVM, Solana,
242
+ * Stellar) so every surface reports provenance identically.
243
+ *
244
+ * Each of the three stamps is passed through independently: a missing member
245
+ * becomes `null` and is never defaulted from one of the others. That is the point
246
+ * of the object — `apy_computed_at` and `share_ratio_snapshot_at` describe two
247
+ * different pipelines, and collapsing them would erase the very staleness signal
248
+ * (snapshot newer than APY) the field exists to expose.
249
+ *
250
+ * @param tokenizedVault - Backend tokenized-vault payload. `freshness` is absent on
251
+ * responses predating the backend change, and may be explicitly null.
252
+ * @returns The mapped freshness object, or `null` when the backend reported none.
253
+ * Values are the backend's RFC 3339 UTC strings verbatim — no reformatting, so
254
+ * the trailing `Z` is preserved.
255
+ */
256
+ function mapVaultFreshness(tokenizedVault) {
257
+ const freshness = tokenizedVault?.freshness;
258
+ if (!freshness)
259
+ return null;
260
+ return {
261
+ apyComputedAt: freshness.apy_computed_at ?? null,
262
+ shareRatioSnapshotAt: freshness.share_ratio_snapshot_at ?? null,
263
+ cachedAt: freshness.cached_at ?? null,
264
+ };
265
+ }
238
266
  /**
239
267
  * Map strategists from backend subaccounts or hardcoded list.
240
268
  * Shared across all chain adapters.
@@ -398,6 +426,7 @@ function buildBackendVault(tokenizedVault, overrides) {
398
426
  composabilityIntegrations: mapComposabilityIntegrations(tokenizedVault),
399
427
  strategists: mapStrategists(tokenizedVault),
400
428
  cachedAt: tokenizedVault.cached_at ?? null,
429
+ freshness: mapVaultFreshness(tokenizedVault),
401
430
  dailyPnlPerShare: mapDailyPnlPerShare(tokenizedVault.daily_pnl_per_share),
402
431
  enabled_historical_price_horizons: tokenizedVault.enabled_historical_price_horizons || [],
403
432
  latest_reported_tvl: tokenizedVault.latest_reported_tvl,
@@ -615,6 +644,7 @@ async function buildFormattedVault(provider, tokenizedVault, contractCalls) {
615
644
  defaultApyHorizon: tokenizedVault?.default_apy_horizon ?? null,
616
645
  latest_reported_tvl: tokenizedVault?.latest_reported_tvl,
617
646
  cachedAt: tokenizedVault?.cached_at ?? null,
647
+ freshness: mapVaultFreshness(tokenizedVault),
618
648
  showCapFilled: tokenizedVault?.show_cap_filled ?? null,
619
649
  apyOverride: tokenizedVault?.apy_override ?? null,
620
650
  };