@perena/vault-sdk 1.0.20 → 1.0.24

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/dist/index.js CHANGED
@@ -233,8 +233,8 @@ var require_roles = __commonJS({
233
233
  return kit_1.AccountRole.WRITABLE;
234
234
  return role;
235
235
  }
236
- function stripSignerFromAccounts(accounts) {
237
- return accounts.map((acc) => ({
236
+ function stripSignerFromAccounts(accounts2) {
237
+ return accounts2.map((acc) => ({
238
238
  ...acc,
239
239
  role: downgradeRoleFromSigner(acc.role)
240
240
  }));
@@ -250,9 +250,9 @@ var require_meta = __commonJS({
250
250
  exports2.toCustomAccountMeta = toCustomAccountMeta;
251
251
  exports2.toCustomAccountMetaFromWeb3AccountMeta = toCustomAccountMetaFromWeb3AccountMeta;
252
252
  var roles_1 = require_roles();
253
- function toCustomAccountMeta(address10, isWritable, requiredAtaDetails, isSigner) {
253
+ function toCustomAccountMeta(address12, isWritable, requiredAtaDetails, isSigner) {
254
254
  const role = (0, roles_1.getAccountRole)(isWritable ?? false, isSigner ?? false);
255
- return { address: address10, role, isRequiredAta: requiredAtaDetails };
255
+ return { address: address12, role, isRequiredAta: requiredAtaDetails };
256
256
  }
257
257
  function toCustomAccountMetaFromWeb3AccountMeta(web3AccountMeta) {
258
258
  return toCustomAccountMeta(web3AccountMeta.pubkey.toBase58(), web3AccountMeta.isWritable, void 0, web3AccountMeta.isSigner);
@@ -344,8 +344,8 @@ var require_refs = __commonJS({
344
344
  var roles_1 = require_roles();
345
345
  var accounts_1 = require_accounts();
346
346
  var args_1 = require_args();
347
- function buildIndicesForCpi(accounts, poolIndex) {
348
- return accounts.map((acc) => {
347
+ function buildIndicesForCpi(accounts2, poolIndex) {
348
+ return accounts2.map((acc) => {
349
349
  const idx = poolIndex.get(acc.address);
350
350
  if (idx === void 0) {
351
351
  throw new Error(`Account ${acc.address} not found in pool`);
@@ -355,8 +355,8 @@ var require_refs = __commonJS({
355
355
  }
356
356
  function buildDeduplicatedPool(accountLists) {
357
357
  const poolMap = /* @__PURE__ */ new Map();
358
- for (const accounts of accountLists) {
359
- for (const acc of accounts) {
358
+ for (const accounts2 of accountLists) {
359
+ for (const acc of accounts2) {
360
360
  const existing = poolMap.get(acc.address);
361
361
  if (!existing) {
362
362
  poolMap.set(acc.address, { ...acc });
@@ -380,8 +380,8 @@ var require_refs = __commonJS({
380
380
  poolIndex.set(acc.address, i);
381
381
  }
382
382
  });
383
- for (const accounts of accountLists) {
384
- for (const acc of accounts) {
383
+ for (const accounts2 of accountLists) {
384
+ for (const acc of accounts2) {
385
385
  const existingIdx = poolIndex.get(acc.address);
386
386
  if (existingIdx === void 0) {
387
387
  const idx = pool.length;
@@ -594,29 +594,29 @@ var require_transaction = __commonJS({
594
594
  exports2.sendVersionedTransaction = sendVersionedTransaction;
595
595
  var web3_js_1 = require("@solana/web3.js");
596
596
  async function fetchLookupTables(connection, lookupTables) {
597
- const accounts = await Promise.all(lookupTables.map(async (lookupTable) => {
597
+ const accounts2 = await Promise.all(lookupTables.map(async (lookupTable) => {
598
598
  const response = await connection.getAddressLookupTable(new web3_js_1.PublicKey(lookupTable));
599
599
  if (!response.value) {
600
600
  throw new Error(`Lookup table not found: ${lookupTable}`);
601
601
  }
602
602
  return response.value;
603
603
  }));
604
- return accounts;
604
+ return accounts2;
605
605
  }
606
606
  async function getSignatureStatus(connection, signature) {
607
607
  return (await connection.getSignatureStatuses([signature], {
608
608
  searchTransactionHistory: true
609
609
  })).value[0];
610
610
  }
611
- async function sendVersionedTransaction({ connection, payer, instructions, lookupTables }) {
611
+ async function sendVersionedTransaction({ connection, payer, instructions: instructions2, lookupTables }) {
612
612
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
613
613
  const lookupTableAccounts = await fetchLookupTables(connection, lookupTables);
614
- const message = new web3_js_1.TransactionMessage({
614
+ const message2 = new web3_js_1.TransactionMessage({
615
615
  payerKey: payer.publicKey,
616
616
  recentBlockhash: blockhash,
617
- instructions
617
+ instructions: instructions2
618
618
  }).compileToV0Message(lookupTableAccounts);
619
- const tx = new web3_js_1.VersionedTransaction(message);
619
+ const tx = new web3_js_1.VersionedTransaction(message2);
620
620
  tx.sign([payer]);
621
621
  const signature = await connection.sendRawTransaction(tx.serialize(), {
622
622
  skipPreflight: true
@@ -1200,8 +1200,8 @@ var require_cpiClient = __commonJS({
1200
1200
  var kit_1 = require("@solana/kit");
1201
1201
  var common_1 = require_dist();
1202
1202
  var constants_1 = require_constants3();
1203
- function account(address10, role) {
1204
- return { address: address10, role };
1203
+ function account(address12, role) {
1204
+ return { address: address12, role };
1205
1205
  }
1206
1206
  function requiredAddress(value, label) {
1207
1207
  if (!value) {
@@ -1209,37 +1209,37 @@ var require_cpiClient = __commonJS({
1209
1209
  }
1210
1210
  return value;
1211
1211
  }
1212
- function orderedDepositAccounts(accounts) {
1212
+ function orderedDepositAccounts(accounts2) {
1213
1213
  return [
1214
- account(accounts.group, kit_1.AccountRole.READONLY),
1215
- account(accounts.marginfiAccount, kit_1.AccountRole.WRITABLE),
1216
- account(accounts.authority, kit_1.AccountRole.READONLY_SIGNER),
1217
- account(accounts.bank, kit_1.AccountRole.WRITABLE),
1218
- account(accounts.signerTokenAccount, kit_1.AccountRole.WRITABLE),
1219
- account(accounts.liquidityVault, kit_1.AccountRole.WRITABLE),
1220
- account(accounts.tokenProgram, kit_1.AccountRole.READONLY)
1214
+ account(accounts2.group, kit_1.AccountRole.READONLY),
1215
+ account(accounts2.marginfiAccount, kit_1.AccountRole.WRITABLE),
1216
+ account(accounts2.authority, kit_1.AccountRole.READONLY_SIGNER),
1217
+ account(accounts2.bank, kit_1.AccountRole.WRITABLE),
1218
+ account(accounts2.signerTokenAccount, kit_1.AccountRole.WRITABLE),
1219
+ account(accounts2.liquidityVault, kit_1.AccountRole.WRITABLE),
1220
+ account(accounts2.tokenProgram, kit_1.AccountRole.READONLY)
1221
1221
  ];
1222
1222
  }
1223
- function orderedCreateAccountAccounts(accounts) {
1223
+ function orderedCreateAccountAccounts(accounts2) {
1224
1224
  return [
1225
- account(accounts.marginfiGroup, kit_1.AccountRole.READONLY),
1226
- account(accounts.marginfiAccount, kit_1.AccountRole.WRITABLE),
1227
- account(accounts.authority, kit_1.AccountRole.READONLY_SIGNER),
1228
- account(accounts.feePayer, kit_1.AccountRole.WRITABLE_SIGNER),
1229
- account(accounts.instructionsSysvar, kit_1.AccountRole.READONLY),
1230
- account(accounts.systemProgram, kit_1.AccountRole.READONLY)
1225
+ account(accounts2.marginfiGroup, kit_1.AccountRole.READONLY),
1226
+ account(accounts2.marginfiAccount, kit_1.AccountRole.WRITABLE),
1227
+ account(accounts2.authority, kit_1.AccountRole.READONLY_SIGNER),
1228
+ account(accounts2.feePayer, kit_1.AccountRole.WRITABLE_SIGNER),
1229
+ account(accounts2.instructionsSysvar, kit_1.AccountRole.READONLY),
1230
+ account(accounts2.systemProgram, kit_1.AccountRole.READONLY)
1231
1231
  ];
1232
1232
  }
1233
- function orderedWithdrawAccounts(accounts) {
1233
+ function orderedWithdrawAccounts(accounts2) {
1234
1234
  return [
1235
- account(accounts.group, kit_1.AccountRole.WRITABLE),
1236
- account(accounts.marginfiAccount, kit_1.AccountRole.WRITABLE),
1237
- account(accounts.authority, kit_1.AccountRole.READONLY_SIGNER),
1238
- account(accounts.bank, kit_1.AccountRole.WRITABLE),
1239
- account(accounts.destinationTokenAccount, kit_1.AccountRole.WRITABLE),
1240
- account(accounts.bankLiquidityVaultAuthority, kit_1.AccountRole.READONLY),
1241
- account(accounts.liquidityVault, kit_1.AccountRole.WRITABLE),
1242
- account(accounts.tokenProgram, kit_1.AccountRole.READONLY)
1235
+ account(accounts2.group, kit_1.AccountRole.WRITABLE),
1236
+ account(accounts2.marginfiAccount, kit_1.AccountRole.WRITABLE),
1237
+ account(accounts2.authority, kit_1.AccountRole.READONLY_SIGNER),
1238
+ account(accounts2.bank, kit_1.AccountRole.WRITABLE),
1239
+ account(accounts2.destinationTokenAccount, kit_1.AccountRole.WRITABLE),
1240
+ account(accounts2.bankLiquidityVaultAuthority, kit_1.AccountRole.READONLY),
1241
+ account(accounts2.liquidityVault, kit_1.AccountRole.WRITABLE),
1242
+ account(accounts2.tokenProgram, kit_1.AccountRole.READONLY)
1243
1243
  ];
1244
1244
  }
1245
1245
  var CpiClient = class {
@@ -1249,7 +1249,7 @@ var require_cpiClient = __commonJS({
1249
1249
  this.accounts = config.accounts ?? constants_1.MARGINFI_MAIN_USDC_ACCOUNTS;
1250
1250
  }
1251
1251
  create_account_cpi(params) {
1252
- const accounts = params.accounts ?? this.createAccountAccounts({
1252
+ const accounts2 = params.accounts ?? this.createAccountAccounts({
1253
1253
  marginfiAccount: params.marginfiAccount,
1254
1254
  authority: params.authority,
1255
1255
  feePayer: params.feePayer
@@ -1258,7 +1258,7 @@ var require_cpiClient = __commonJS({
1258
1258
  cpiType: params.cpiType ?? common_1.CpiTypes.MARGINFI_ACCOUNT_INITIALIZE,
1259
1259
  programId: this.programId,
1260
1260
  accounts: [
1261
- ...orderedCreateAccountAccounts(accounts),
1261
+ ...orderedCreateAccountAccounts(accounts2),
1262
1262
  ...params.remainingAccounts ?? []
1263
1263
  ],
1264
1264
  data: (0, common_1.encodeU16AndOptionalU16)(params.accountIndex ?? constants_1.MARGINFI_ACCOUNT_INDEX, params.thirdPartyId ?? constants_1.MARGINFI_THIRD_PARTY_ID, "accountIndex", "thirdPartyId"),
@@ -1266,7 +1266,7 @@ var require_cpiClient = __commonJS({
1266
1266
  };
1267
1267
  }
1268
1268
  deposit_cpi(params) {
1269
- const accounts = params.accounts ?? this.depositAccounts({
1269
+ const accounts2 = params.accounts ?? this.depositAccounts({
1270
1270
  marginfiAccount: params.marginfiAccount,
1271
1271
  authority: params.authority,
1272
1272
  signerTokenAccount: params.signerTokenAccount
@@ -1275,7 +1275,7 @@ var require_cpiClient = __commonJS({
1275
1275
  cpiType: params.cpiType ?? common_1.CpiTypes.MARGINFI_DEPOSIT,
1276
1276
  programId: this.programId,
1277
1277
  accounts: [
1278
- ...orderedDepositAccounts(accounts),
1278
+ ...orderedDepositAccounts(accounts2),
1279
1279
  ...params.remainingAccounts ?? []
1280
1280
  ],
1281
1281
  data: (0, common_1.encodeU64AndOptionalBool)(params.amount, params.depositUpToLimit),
@@ -1283,20 +1283,20 @@ var require_cpiClient = __commonJS({
1283
1283
  };
1284
1284
  }
1285
1285
  withdraw_cpi(params) {
1286
- const accounts = params.accounts ?? this.withdrawAccounts({
1286
+ const accounts2 = params.accounts ?? this.withdrawAccounts({
1287
1287
  marginfiAccount: params.marginfiAccount,
1288
1288
  authority: params.authority,
1289
1289
  destinationTokenAccount: params.destinationTokenAccount
1290
1290
  });
1291
1291
  const bankAndOracleRemainingAccounts = [
1292
1292
  account(this.accounts.bank, kit_1.AccountRole.READONLY),
1293
- ...this.accounts.oracleAccounts.map((address10) => account(address10, kit_1.AccountRole.READONLY))
1293
+ ...this.accounts.oracleAccounts.map((address12) => account(address12, kit_1.AccountRole.READONLY))
1294
1294
  ];
1295
1295
  return {
1296
1296
  cpiType: params.cpiType ?? common_1.CpiTypes.MARGINFI_WITHDRAW,
1297
1297
  programId: this.programId,
1298
1298
  accounts: [
1299
- ...orderedWithdrawAccounts(accounts),
1299
+ ...orderedWithdrawAccounts(accounts2),
1300
1300
  ...params.remainingAccounts ?? [],
1301
1301
  ...bankAndOracleRemainingAccounts
1302
1302
  ],
@@ -1414,11 +1414,17 @@ __export(index_exports, {
1414
1414
  JupiterPriceSource: () => JupiterPriceSource,
1415
1415
  JupiterSwapBuilder: () => JupiterSwapBuilder,
1416
1416
  KaminoPositionProvider: () => KaminoPositionProvider,
1417
+ LOCAL_PROTOCOL_ADMIN: () => LOCAL_PROTOCOL_ADMIN,
1418
+ LivePriceSource: () => LivePriceSource,
1417
1419
  MAX_PRICE_STALENESS_THRESHOLD_SECS: () => MAX_PRICE_STALENESS_THRESHOLD_SECS,
1418
1420
  ManagerRedepositAssetBuilder: () => ManagerRedepositAssetBuilder,
1419
1421
  ManagerWithdrawAssetBuilder: () => ManagerWithdrawAssetBuilder,
1420
1422
  MarginfiPositionProvider: () => MarginfiPositionProvider,
1421
1423
  MockYieldTracker: () => MockYieldTracker,
1424
+ NEST_API_BASE_URL: () => NEST_API_BASE_URL,
1425
+ NEST_RWA_SHARE_MINT: () => NEST_RWA_SHARE_MINT,
1426
+ NEST_VAULT_SLUG: () => NEST_VAULT_SLUG,
1427
+ NestPriceSource: () => NestPriceSource,
1422
1428
  OracleService: () => OracleService,
1423
1429
  PROGRAM_FEE_EXEMPT_OWNER_WHITELIST: () => PROGRAM_FEE_EXEMPT_OWNER_WHITELIST,
1424
1430
  PROTOCOL_ADMIN: () => PROTOCOL_ADMIN,
@@ -1461,6 +1467,7 @@ __export(index_exports, {
1461
1467
  WithdrawalQueueService: () => WithdrawalQueueService,
1462
1468
  addCashflowUpdate: () => addCashflowUpdate,
1463
1469
  address: () => import_kit10.address,
1470
+ applyEffectiveApy: () => applyEffectiveApy,
1464
1471
  confirmYieldPayment: () => confirmYieldPayment,
1465
1472
  createAccount: () => createAccount,
1466
1473
  createLiveConsensusOracleDeps: () => createLiveConsensusOracleDeps,
@@ -1472,6 +1479,9 @@ __export(index_exports, {
1472
1479
  dateToStr: () => dateToStr,
1473
1480
  defaultKeypairPath: () => defaultKeypairPath,
1474
1481
  deleteAccount: () => deleteAccount,
1482
+ fetchNestTokenPrice: () => fetchNestTokenPrice,
1483
+ findSquadsWalletRoute: () => findSquadsWalletRoute,
1484
+ formatSettlementSimulation: () => formatSettlementSimulation,
1475
1485
  fromUiAmount: () => fromUiAmount,
1476
1486
  getAccounts: () => getAccounts,
1477
1487
  getBalance: () => getBalance,
@@ -1487,13 +1497,18 @@ __export(index_exports, {
1487
1497
  loadKeypair: () => loadKeypair,
1488
1498
  makeProvider: () => makeProvider,
1489
1499
  mintTokensTo: () => mintTokensTo,
1500
+ prepareVaultTransaction: () => prepareVaultTransaction,
1490
1501
  resolveKeypairPath: () => resolveKeypairPath,
1502
+ resolveSquadsWalletRoute: () => resolveSquadsWalletRoute,
1491
1503
  roundToNextUtcMidnight: () => roundToNextUtcMidnight,
1492
1504
  runLiveConsensusOracle: () => runLiveConsensusOracle,
1505
+ simulateConsensusOracleSettlement: () => simulateConsensusOracleSettlement,
1493
1506
  systemClock: () => systemClock,
1494
1507
  toUiAmount: () => toUiAmount,
1495
1508
  updateAccount: () => updateAccount,
1496
- updateDynamicApr: () => updateDynamicApr
1509
+ updateDynamicApr: () => updateDynamicApr,
1510
+ validateSquadsWalletRoutes: () => validateSquadsWalletRoutes,
1511
+ vaultAuthorityForWallet: () => vaultAuthorityForWallet
1497
1512
  });
1498
1513
  module.exports = __toCommonJS(index_exports);
1499
1514
 
@@ -1506,6 +1521,9 @@ var VAULT_PROGRAM_ID = (0, import_kit.address)(
1506
1521
  );
1507
1522
  var VAULT_PROGRAM_PUBLIC_KEY = new import_web3.PublicKey(VAULT_PROGRAM_ID);
1508
1523
  var PROTOCOL_ADMIN = (0, import_kit.address)(
1524
+ "4jMRBkpWrfhhwFYTwG3o7hmsXQwbJUwdyUX8htB6KwLJ"
1525
+ );
1526
+ var LOCAL_PROTOCOL_ADMIN = (0, import_kit.address)(
1509
1527
  "BQJZAhDnvgSGHjdAbzQEXRBYzSBuWgSYqDzhDnUSRWGR"
1510
1528
  );
1511
1529
  var PROTOCOL_FEE_RECIPIENT = (0, import_kit.address)(
@@ -1517,7 +1535,7 @@ var PROGRAM_FEE_EXEMPT_OWNER_WHITELIST = [
1517
1535
  (0, import_kit.address)("LYC8YiiSzQfPpxUW2tpxfuPKGZwywAJhXKUfDP2B66f")
1518
1536
  ];
1519
1537
  var VAULT_CREATOR_WHITELIST = [
1520
- (0, import_kit.address)("11111111111111111111111111111111")
1538
+ (0, import_kit.address)("4jMRBkpWrfhhwFYTwG3o7hmsXQwbJUwdyUX8htB6KwLJ")
1521
1539
  ];
1522
1540
  var TOKEN_PROGRAM_ID = (0, import_kit.address)(
1523
1541
  import_spl_token.TOKEN_2022_PROGRAM_ID.toBase58()
@@ -1763,8 +1781,7 @@ var IDL = {
1763
1781
  {
1764
1782
  "name": "fee_asset_mint",
1765
1783
  "docs": [
1766
- "Base-asset mint used to pay performance fees on settlement. Must match",
1767
- "an `is_base` holding; choose a mint whose vault ATA has liquidity."
1784
+ "Legacy fee-asset account retained in this instruction's account schema."
1768
1785
  ]
1769
1786
  },
1770
1787
  {
@@ -1827,7 +1844,7 @@ var IDL = {
1827
1844
  {
1828
1845
  "name": "fee_vault",
1829
1846
  "docs": [
1830
- "Per-vault fee-vault PDA: token authority + accounting for accrued fees."
1847
+ "Legacy fee-vault account retained in this instruction's account schema."
1831
1848
  ],
1832
1849
  "writable": true
1833
1850
  },
@@ -1921,84 +1938,18 @@ var IDL = {
1921
1938
  "signer": true
1922
1939
  },
1923
1940
  {
1924
- "name": "vault"
1925
- },
1926
- {
1927
- "name": "fee_asset_mint",
1928
- "docs": [
1929
- "Vault base asset whose fee-vault ATA should be swept. Must match an",
1930
- "`is_base` holding with a fresh price."
1931
- ]
1932
- },
1933
- {
1934
- "name": "fee_vault",
1935
- "docs": [
1936
- "Per-vault fee-vault PDA: token authority + accounting for accrued fees."
1937
- ],
1941
+ "name": "vault",
1938
1942
  "writable": true
1939
1943
  },
1940
1944
  {
1941
- "name": "fee_vault_ata",
1942
- "writable": true,
1943
- "pda": {
1944
- "seeds": [
1945
- {
1946
- "kind": "account",
1947
- "path": "fee_vault"
1948
- },
1949
- {
1950
- "kind": "account",
1951
- "path": "fee_asset_token_program"
1952
- },
1953
- {
1954
- "kind": "account",
1955
- "path": "fee_asset_mint"
1956
- }
1957
- ],
1958
- "program": {
1959
- "kind": "const",
1960
- "value": [
1961
- 140,
1962
- 151,
1963
- 37,
1964
- 143,
1965
- 78,
1966
- 36,
1967
- 137,
1968
- 241,
1969
- 187,
1970
- 61,
1971
- 16,
1972
- 41,
1973
- 20,
1974
- 142,
1975
- 13,
1976
- 131,
1977
- 11,
1978
- 90,
1979
- 19,
1980
- 153,
1981
- 218,
1982
- 255,
1983
- 16,
1984
- 132,
1985
- 4,
1986
- 142,
1987
- 123,
1988
- 216,
1989
- 219,
1990
- 233,
1991
- 248,
1992
- 89
1993
- ]
1994
- }
1995
- }
1945
+ "name": "share_mint",
1946
+ "writable": true
1996
1947
  },
1997
1948
  {
1998
1949
  "name": "fee_collector"
1999
1950
  },
2000
1951
  {
2001
- "name": "fee_collector_fee_asset_ata",
1952
+ "name": "fee_collector_share_ata",
2002
1953
  "writable": true,
2003
1954
  "pda": {
2004
1955
  "seeds": [
@@ -2008,11 +1959,11 @@ var IDL = {
2008
1959
  },
2009
1960
  {
2010
1961
  "kind": "account",
2011
- "path": "fee_asset_token_program"
1962
+ "path": "share_token_program"
2012
1963
  },
2013
1964
  {
2014
1965
  "kind": "account",
2015
- "path": "fee_asset_mint"
1966
+ "path": "share_mint"
2016
1967
  }
2017
1968
  ],
2018
1969
  "program": {
@@ -2058,7 +2009,7 @@ var IDL = {
2058
2009
  "name": "protocol_fee_collector"
2059
2010
  },
2060
2011
  {
2061
- "name": "protocol_fee_collector_fee_asset_ata",
2012
+ "name": "protocol_fee_collector_share_ata",
2062
2013
  "writable": true,
2063
2014
  "pda": {
2064
2015
  "seeds": [
@@ -2068,11 +2019,11 @@ var IDL = {
2068
2019
  },
2069
2020
  {
2070
2021
  "kind": "account",
2071
- "path": "fee_asset_token_program"
2022
+ "path": "share_token_program"
2072
2023
  },
2073
2024
  {
2074
2025
  "kind": "account",
2075
- "path": "fee_asset_mint"
2026
+ "path": "share_mint"
2076
2027
  }
2077
2028
  ],
2078
2029
  "program": {
@@ -2115,7 +2066,7 @@ var IDL = {
2115
2066
  }
2116
2067
  },
2117
2068
  {
2118
- "name": "fee_asset_token_program"
2069
+ "name": "share_token_program"
2119
2070
  },
2120
2071
  {
2121
2072
  "name": "associated_token_program",
@@ -2998,7 +2949,9 @@ var IDL = {
2998
2949
  {
2999
2950
  "name": "share_mint",
3000
2951
  "docs": [
3001
- "Curator-supplied share mint. Its decimals must match `asset_mint`.",
2952
+ "Curator-supplied share mint. Its decimals define the vault accounting",
2953
+ "precision. `asset_mint` may use a different precision, which is stored",
2954
+ "on its holding and handled by holding-price conversion.",
3002
2955
  "Unless `for_migration`, it must have zero supply with mint authority on",
3003
2956
  "the curator; authority is transferred to the vault PDA on success.",
3004
2957
  "Migration uses the legacy bank mint and defers transfer."
@@ -3222,8 +3175,8 @@ var IDL = {
3222
3175
  {
3223
3176
  "name": "fee_vault",
3224
3177
  "docs": [
3225
- "Per-vault fee-vault PDA: token authority + accounting. The mint fee",
3226
- "accrues here and is swept to the fee collector by the permissionless crank."
3178
+ "Legacy fee-vault account retained in this instruction's account schema.",
3179
+ "New fees accrue as pending vault shares."
3227
3180
  ],
3228
3181
  "writable": true
3229
3182
  },
@@ -3517,8 +3470,8 @@ var IDL = {
3517
3470
  {
3518
3471
  "name": "fee_vault",
3519
3472
  "docs": [
3520
- "Per-vault fee-vault PDA: token authority + accounting. The mint fee",
3521
- "accrues here and is swept to the fee collector by the permissionless crank."
3473
+ "Legacy fee-vault account retained in this instruction's account schema.",
3474
+ "New fees accrue as pending vault shares."
3522
3475
  ],
3523
3476
  "writable": true
3524
3477
  },
@@ -4013,8 +3966,8 @@ var IDL = {
4013
3966
  {
4014
3967
  "name": "fee_vault",
4015
3968
  "docs": [
4016
- "Per-vault fee-vault PDA: token authority + accounting. Mint fees",
4017
- "accrue here and are swept by the permissionless fee crank."
3969
+ "Legacy fee-vault account retained in this instruction's account schema.",
3970
+ "New fees accrue as pending vault shares."
4018
3971
  ],
4019
3972
  "writable": true
4020
3973
  },
@@ -4315,8 +4268,8 @@ var IDL = {
4315
4268
  {
4316
4269
  "name": "fee_vault",
4317
4270
  "docs": [
4318
- "Per-vault fee-vault PDA: token authority + accounting. Mint fees",
4319
- "accrue here and are swept by the permissionless fee crank."
4271
+ "Legacy fee-vault account retained in this instruction's account schema.",
4272
+ "New fees accrue as pending vault shares."
4320
4273
  ],
4321
4274
  "writable": true
4322
4275
  },
@@ -5106,8 +5059,8 @@ var IDL = {
5106
5059
  {
5107
5060
  "name": "fee_vault",
5108
5061
  "docs": [
5109
- "Per-vault fee-vault PDA: token authority + accounting. The burn fee accrues",
5110
- "here and is swept to the fee collector by the permissionless crank."
5062
+ "Legacy fee-vault account retained in this instruction's account schema.",
5063
+ "New fees accrue as pending vault shares."
5111
5064
  ],
5112
5065
  "writable": true
5113
5066
  },
@@ -5395,8 +5348,8 @@ var IDL = {
5395
5348
  {
5396
5349
  "name": "fee_vault",
5397
5350
  "docs": [
5398
- "Per-vault fee-vault PDA: token authority + accounting. The burn fee accrues",
5399
- "here and is swept to the fee collector by the permissionless crank."
5351
+ "Legacy fee-vault account retained in this instruction's account schema.",
5352
+ "New fees accrue as pending vault shares."
5400
5353
  ],
5401
5354
  "writable": true
5402
5355
  },
@@ -5690,8 +5643,8 @@ var IDL = {
5690
5643
  {
5691
5644
  "name": "fee_vault",
5692
5645
  "docs": [
5693
- "Per-vault fee-vault PDA: token authority + accounting. The burn fee accrues",
5694
- "here and is swept to the fee collector by the permissionless crank."
5646
+ "Legacy fee-vault account retained in this instruction's account schema.",
5647
+ "New fees accrue as pending vault shares."
5695
5648
  ],
5696
5649
  "writable": true
5697
5650
  },
@@ -5995,8 +5948,8 @@ var IDL = {
5995
5948
  {
5996
5949
  "name": "fee_vault",
5997
5950
  "docs": [
5998
- "Per-vault fee-vault PDA: token authority + accounting. The burn fee accrues",
5999
- "here and is swept to the fee collector by the permissionless crank."
5951
+ "Legacy fee-vault account retained in this instruction's account schema.",
5952
+ "New fees accrue as pending vault shares."
6000
5953
  ],
6001
5954
  "writable": true
6002
5955
  },
@@ -7417,9 +7370,6 @@ var IDL = {
7417
7370
  },
7418
7371
  {
7419
7372
  "name": "idle_bank_tranche",
7420
- "docs": [
7421
- "path rejects initialized state because it cannot represent junior claims."
7422
- ],
7423
7373
  "pda": {
7424
7374
  "seeds": [
7425
7375
  {
@@ -7578,7 +7528,7 @@ var IDL = {
7578
7528
  {
7579
7529
  "name": "yielding_bank_tranche",
7580
7530
  "docs": [
7581
- "state so an active senior-price regime cannot be hidden by omission."
7531
+ "tranche was already consumed by its regular vault migrations."
7582
7532
  ],
7583
7533
  "pda": {
7584
7534
  "seeds": [
@@ -7756,9 +7706,6 @@ var IDL = {
7756
7706
  },
7757
7707
  {
7758
7708
  "name": "vault_tranche_state",
7759
- "docs": [
7760
- "be initialized and consistent with destination.tranching_enabled."
7761
- ],
7762
7709
  "writable": true,
7763
7710
  "pda": {
7764
7711
  "seeds": [
@@ -9782,6 +9729,69 @@ var IDL = {
9782
9729
  }
9783
9730
  ]
9784
9731
  },
9732
+ {
9733
+ "name": "trigger_bank_circuit_breaker",
9734
+ "discriminator": [
9735
+ 250,
9736
+ 236,
9737
+ 165,
9738
+ 211,
9739
+ 181,
9740
+ 241,
9741
+ 74,
9742
+ 84
9743
+ ],
9744
+ "accounts": [
9745
+ {
9746
+ "name": "bank_state",
9747
+ "writable": true,
9748
+ "pda": {
9749
+ "seeds": [
9750
+ {
9751
+ "kind": "const",
9752
+ "value": [
9753
+ 66,
9754
+ 65,
9755
+ 78,
9756
+ 75
9757
+ ]
9758
+ },
9759
+ {
9760
+ "kind": "account",
9761
+ "path": "bank_state"
9762
+ }
9763
+ ]
9764
+ }
9765
+ },
9766
+ {
9767
+ "name": "bank_manager",
9768
+ "writable": true,
9769
+ "signer": true
9770
+ },
9771
+ {
9772
+ "name": "system_program",
9773
+ "address": "11111111111111111111111111111111"
9774
+ },
9775
+ {
9776
+ "name": "token_program",
9777
+ "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
9778
+ }
9779
+ ],
9780
+ "args": [
9781
+ {
9782
+ "name": "is_halted",
9783
+ "type": "bool"
9784
+ },
9785
+ {
9786
+ "name": "is_halted_deposit",
9787
+ "type": "bool"
9788
+ },
9789
+ {
9790
+ "name": "is_halted_withdrawal",
9791
+ "type": "bool"
9792
+ }
9793
+ ]
9794
+ },
9785
9795
  {
9786
9796
  "name": "trigger_vault_circuit_breaker",
9787
9797
  "discriminator": [
@@ -10543,8 +10553,8 @@ var IDL = {
10543
10553
  {
10544
10554
  "name": "destination_fee_vault",
10545
10555
  "docs": [
10546
- "Destination vault's fee-vault PDA: the mint fee accrues here and is swept",
10547
- "to the fee collector by the permissionless crank."
10556
+ "Legacy fee-vault account retained in this instruction's account schema.",
10557
+ "New fees accrue as pending vault shares."
10548
10558
  ],
10549
10559
  "writable": true
10550
10560
  },
@@ -11029,224 +11039,239 @@ var IDL = {
11029
11039
  ],
11030
11040
  "errors": [
11031
11041
  {
11032
- "code": 6e3,
11033
- "name": "MintSupplyNonZero",
11034
- "msg": "Supplied share mint already has non-zero supply"
11042
+ "code": 14001,
11043
+ "name": "Unauthorized",
11044
+ "msg": "You are not authorized to perform this action."
11045
+ },
11046
+ {
11047
+ "code": 14002,
11048
+ "name": "InvalidBankMint",
11049
+ "msg": "Invalid mint"
11035
11050
  },
11036
11051
  {
11037
- "code": 6001,
11038
- "name": "InvalidAssetMint",
11039
- "msg": "Supplied mint is not accepted by this vault"
11052
+ "code": 14003,
11053
+ "name": "AccountingIssue",
11054
+ "msg": "Accounting issue"
11040
11055
  },
11041
11056
  {
11042
- "code": 6002,
11043
- "name": "ZeroDepositAmount",
11044
- "msg": "Deposit amount must be greater than zero"
11057
+ "code": 14004,
11058
+ "name": "VaultAccountingIssue",
11059
+ "msg": "Vault accounting issue"
11045
11060
  },
11046
11061
  {
11047
- "code": 6003,
11048
- "name": "ExceedsTvlLimit",
11049
- "msg": "Deposit would exceed the vault's TVL limit"
11062
+ "code": 14005,
11063
+ "name": "BankAccountingIssue",
11064
+ "msg": "Bank accounting issue"
11050
11065
  },
11051
11066
  {
11052
- "code": 6004,
11053
- "name": "ZeroBurnAmount",
11054
- "msg": "Burn amount must be greater than zero"
11067
+ "code": 14006,
11068
+ "name": "OnchainAccountingIssue",
11069
+ "msg": "Onchain accounting issue"
11055
11070
  },
11056
11071
  {
11057
- "code": 6005,
11058
- "name": "ZeroAssetAmount",
11059
- "msg": "Asset amount must be greater than zero"
11072
+ "code": 14007,
11073
+ "name": "ExternalAccountingIssue",
11074
+ "msg": "External accounting issue"
11060
11075
  },
11061
11076
  {
11062
- "code": 6006,
11063
- "name": "InsufficientVaultLiquidity",
11064
- "msg": "Insufficient vault liquidity to satisfy withdrawal"
11077
+ "code": 14008,
11078
+ "name": "MintSlippage",
11079
+ "msg": "Minting failed due to slippage."
11065
11080
  },
11066
11081
  {
11067
- "code": 6007,
11068
- "name": "MintAuthorityNotCurator",
11069
- "msg": "Mint authority is not the curator"
11082
+ "code": 14009,
11083
+ "name": "BurningSlippage",
11084
+ "msg": "Burning failed due to slippage."
11070
11085
  },
11071
11086
  {
11072
- "code": 6008,
11073
- "name": "ZeroTotalSupply",
11074
- "msg": "Vault total supply is zero"
11087
+ "code": 14010,
11088
+ "name": "TeamAccountAlreadyExists",
11089
+ "msg": "Team account already exists"
11075
11090
  },
11076
11091
  {
11077
- "code": 6009,
11092
+ "code": 14011,
11093
+ "name": "OracleAccountAlreadyExists",
11094
+ "msg": "Oracle account already exists"
11095
+ },
11096
+ {
11097
+ "code": 14012,
11078
11098
  "name": "StaleOracle",
11079
- "msg": "Vault oracle is stale"
11099
+ "msg": "Stale oracle"
11080
11100
  },
11081
11101
  {
11082
- "code": 6010,
11083
- "name": "InvalidOracleUpdate",
11084
- "msg": "Invalid oracle update"
11102
+ "code": 14013,
11103
+ "name": "LocalSignificantPriceChange",
11104
+ "msg": "Price change is too large locally"
11085
11105
  },
11086
11106
  {
11087
- "code": 6011,
11088
- "name": "InvalidInitialMintSharePrice",
11089
- "msg": "Initial mint share price must be greater than zero"
11107
+ "code": 14014,
11108
+ "name": "SignificantPriceChange",
11109
+ "msg": "Price change is too large"
11090
11110
  },
11091
11111
  {
11092
- "code": 6012,
11093
- "name": "MaxApyExceeded",
11094
- "msg": "Oracle NAV update exceeds the vault's maximum acceptable APY"
11112
+ "code": 14015,
11113
+ "name": "RoundingImpact",
11114
+ "msg": "Rounding impacts the protocol"
11095
11115
  },
11096
11116
  {
11097
- "code": 6013,
11098
- "name": "InvalidApyConfig",
11099
- "msg": "Invalid APY configuration"
11117
+ "code": 14016,
11118
+ "name": "BankIsHalted",
11119
+ "msg": "Bank is halted"
11100
11120
  },
11101
11121
  {
11102
- "code": 6014,
11103
- "name": "InvalidFeeConfig",
11104
- "msg": "Invalid fee configuration"
11122
+ "code": 14017,
11123
+ "name": "VaultIsHalted",
11124
+ "msg": "Vault is halted"
11105
11125
  },
11106
11126
  {
11107
- "code": 6015,
11108
- "name": "VaultHasLiveAssets",
11109
- "msg": "Vault has live supply, TVL, or holdings"
11127
+ "code": 14018,
11128
+ "name": "ConversionOverflow",
11129
+ "msg": "Conversion Overflow"
11110
11130
  },
11111
11131
  {
11112
- "code": 6016,
11113
- "name": "DepositMintsZeroShares",
11114
- "msg": "Deposit would mint zero shares"
11132
+ "code": 14019,
11133
+ "name": "_Reserved8019",
11134
+ "msg": "Reserved"
11115
11135
  },
11116
11136
  {
11117
- "code": 6017,
11118
- "name": "InsufficientAccruedApyBalance",
11119
- "msg": "Insufficient accrued APY balance"
11137
+ "code": 14020,
11138
+ "name": "InvalidArgument",
11139
+ "msg": "Invalid argument"
11120
11140
  },
11121
11141
  {
11122
- "code": 6018,
11123
- "name": "InvalidRole",
11124
- "msg": "Invalid role configuration"
11142
+ "code": 14021,
11143
+ "name": "UserSanityCheck",
11144
+ "msg": "User Sanity Check"
11125
11145
  },
11126
11146
  {
11127
- "code": 6019,
11128
- "name": "InvalidProtocolInteraction",
11129
- "msg": "Invalid protocol interaction CPI"
11147
+ "code": 14022,
11148
+ "name": "MathOverflow",
11149
+ "msg": "Math overflow"
11130
11150
  },
11131
11151
  {
11132
- "code": 6020,
11133
- "name": "_Reserved7020",
11134
- "msg": "Reserved"
11152
+ "code": 14023,
11153
+ "name": "InvalidMarginFiAccount",
11154
+ "msg": "Invalid MarginFi account - must be correct PDA for this vault"
11135
11155
  },
11136
11156
  {
11137
- "code": 6021,
11138
- "name": "InvalidExternalLiquidity",
11139
- "msg": "Invalid external liquidity configuration"
11157
+ "code": 14024,
11158
+ "name": "InvalidStartMarker",
11159
+ "msg": "Invalid start marker"
11140
11160
  },
11141
11161
  {
11142
- "code": 6022,
11143
- "name": "SwapBalanceUnchanged",
11144
- "msg": "Swap did not change both source and destination balances"
11162
+ "code": 14025,
11163
+ "name": "OracleUpdateOnEmptyReserve",
11164
+ "msg": "Unable to push oracle update on an empty vault reserve"
11145
11165
  },
11146
11166
  {
11147
- "code": 6023,
11148
- "name": "ProtocolBalanceUnchanged",
11149
- "msg": "Protocol interaction did not change the affected token balance"
11167
+ "code": 14026,
11168
+ "name": "InvalidRemainingAccountsLength",
11169
+ "msg": "Invalid remaining accounts length"
11150
11170
  },
11151
11171
  {
11152
- "code": 6024,
11153
- "name": "ExcessiveSwapSlippage",
11154
- "msg": "Swap TVL loss exceeds the allowed slippage"
11172
+ "code": 14027,
11173
+ "name": "WithdrawalExceedsBalance",
11174
+ "msg": "Specified withdrawal exceeds available balance"
11155
11175
  },
11156
11176
  {
11157
- "code": 6025,
11158
- "name": "TranchingNotEnabled",
11159
- "msg": "Vault tranching is not enabled"
11177
+ "code": 14028,
11178
+ "name": "InsufficientPendingYield",
11179
+ "msg": "Insufficient pending yield"
11160
11180
  },
11161
11181
  {
11162
- "code": 6026,
11163
- "name": "TranchingAlreadyEnabled",
11164
- "msg": "Vault tranching is already enabled"
11182
+ "code": 14029,
11183
+ "name": "NotSupported",
11184
+ "msg": "Not supported"
11165
11185
  },
11166
11186
  {
11167
- "code": 6027,
11168
- "name": "TrancheStateRequired",
11169
- "msg": "Tranche state account is required"
11187
+ "code": 14030,
11188
+ "name": "ExceedsMaxYieldingTvl",
11189
+ "msg": "Exceeds maximum yielding TVL"
11170
11190
  },
11171
11191
  {
11172
- "code": 6028,
11173
- "name": "InvalidTrancheConfig",
11174
- "msg": "Invalid tranche configuration"
11192
+ "code": 14031,
11193
+ "name": "TranchingNotEnabled",
11194
+ "msg": "Tranching is not enabled for this bank"
11175
11195
  },
11176
11196
  {
11177
- "code": 6029,
11178
- "name": "InvalidTrancheMint",
11179
- "msg": "Invalid tranche mint"
11197
+ "code": 14032,
11198
+ "name": "InvalidLeverageFactor",
11199
+ "msg": "Invalid leverage factor - must be at least 10000 (1x)"
11180
11200
  },
11181
11201
  {
11182
- "code": 6030,
11183
- "name": "LossesDisabled",
11184
- "msg": "Vault losses are not enabled"
11202
+ "code": 14033,
11203
+ "name": "InsufficientStakedAmount",
11204
+ "msg": "Insufficient staked amount"
11185
11205
  },
11186
11206
  {
11187
- "code": 6031,
11188
- "name": "WithdrawalQueueNotExpired",
11189
- "msg": "Withdrawal queue is not yet expired"
11207
+ "code": 14034,
11208
+ "name": "JuniorTrancheEmpty",
11209
+ "msg": "Junior tranche has no value"
11190
11210
  },
11191
11211
  {
11192
- "code": 6032,
11193
- "name": "InvalidWithdrawalQueue",
11194
- "msg": "Invalid withdrawal queue"
11212
+ "code": 14035,
11213
+ "name": "InvalidTrancheConfig",
11214
+ "msg": "Invalid tranche config parameter"
11215
+ },
11216
+ {
11217
+ "code": 14036,
11218
+ "name": "WithdrawalQueueNotExpired",
11219
+ "msg": "Withdrawal queue lockup period has not expired"
11195
11220
  },
11196
11221
  {
11197
- "code": 6033,
11198
- "name": "AssetPriceNotSet",
11199
- "msg": "Destination asset has no price set; a consensus oracle price is required before swapping"
11222
+ "code": 14037,
11223
+ "name": "InvalidWithdrawalQueue",
11224
+ "msg": "Withdrawal queue entry is not in a valid state"
11200
11225
  },
11201
11226
  {
11202
- "code": 6034,
11203
- "name": "AssetHoldingNotEmpty",
11204
- "msg": "Asset holding still has a balance and cannot be removed"
11227
+ "code": 14038,
11228
+ "name": "InvalidAccount",
11229
+ "msg": "Account does not belong to the expected parent"
11205
11230
  },
11206
11231
  {
11207
- "code": 6035,
11208
- "name": "CannotRemoveBaseHolding",
11209
- "msg": "The base asset holding cannot be removed"
11232
+ "code": 14039,
11233
+ "name": "MissingAccount",
11234
+ "msg": "Required optional account is missing"
11210
11235
  },
11211
11236
  {
11212
- "code": 6036,
11213
- "name": "UnauthorizedPriceUpdater",
11214
- "msg": "Caller is not authorized to trigger an asset price update"
11237
+ "code": 14040,
11238
+ "name": "TrancheWipedOut",
11239
+ "msg": "Junior tranche is wiped out and cannot accept new stakes"
11215
11240
  },
11216
11241
  {
11217
- "code": 6037,
11218
- "name": "InvalidStalenessConfig",
11219
- "msg": "Invalid asset-price staleness threshold"
11242
+ "code": 14041,
11243
+ "name": "VaultLossNotAccepted",
11244
+ "msg": "Vault does not accept losses \u2014 enable losses_accepted before retrying"
11220
11245
  },
11221
11246
  {
11222
- "code": 6038,
11223
- "name": "AssetRebalanceRateLimitExceeded",
11224
- "msg": "Asset was rebalanced too recently"
11247
+ "code": 14042,
11248
+ "name": "CapitalLossExceedsReserve",
11249
+ "msg": "Capital loss exceeds available yielding reserve"
11225
11250
  },
11226
11251
  {
11227
- "code": 6039,
11228
- "name": "InvalidShareTokenProgram",
11229
- "msg": "Share token program does not match the vault/tranche mint configuration"
11252
+ "code": 14043,
11253
+ "name": "RollingWithdrawalLimitExceeded",
11254
+ "msg": "Rolling withdrawal limit exceeded"
11230
11255
  },
11231
11256
  {
11232
- "code": 6040,
11233
- "name": "UnauthorizedVaultCreator",
11234
- "msg": "Caller is not on the vault-creator whitelist"
11257
+ "code": 14044,
11258
+ "name": "VaultAlreadyMigrated",
11259
+ "msg": "Legacy vault has already been migrated"
11235
11260
  },
11236
11261
  {
11237
- "code": 6041,
11238
- "name": "InvalidShareMintDecimals",
11239
- "msg": "Share mint decimals must match the deposit asset mint decimals"
11262
+ "code": 14045,
11263
+ "name": "InvalidMigrationState",
11264
+ "msg": "Legacy vault migration is incomplete or invalid"
11240
11265
  },
11241
11266
  {
11242
- "code": 6042,
11243
- "name": "InvalidFeeExemption",
11244
- "msg": "Invalid fee-exemption PDA signer or seeds"
11267
+ "code": 14046,
11268
+ "name": "InvalidMigrationMintAuthority",
11269
+ "msg": "Mint authority does not match the expected migration source"
11245
11270
  },
11246
11271
  {
11247
- "code": 6043,
11248
- "name": "ExceedsJuniorDepositCap",
11249
- "msg": "Deposit would exceed the junior tranche deposit cap"
11272
+ "code": 14047,
11273
+ "name": "BankMigrationIncomplete",
11274
+ "msg": "Legacy bank or tranche migration is incomplete \u2014 source accounting and escrow must be fully drained before mint authority transfer"
11250
11275
  }
11251
11276
  ],
11252
11277
  "types": [
@@ -11846,21 +11871,11 @@ var IDL = {
11846
11871
  {
11847
11872
  "name": "FeeVault",
11848
11873
  "docs": [
11849
- "Per-vault fee custody + accounting account.",
11850
- "",
11851
- "The PDA is both the token authority over the fee-asset ATAs that physically",
11852
- "hold accrued fees and the ledger of what is owed to whom. All four fee types",
11853
- "\u2014 mint, burn, performance, and protocol \u2014 accrue here.",
11854
- "",
11855
- "Ledger amounts (`*_owed` / `*_collected`) are denominated in the vault's",
11856
- "**accounting unit** (the same unit as TVL / holding prices), not raw token",
11857
- "units. Token custody may still be split across ATAs for different base-asset",
11858
- "mints; the permissionless fee crank converts each ATA's balance to accounting",
11859
- "value via that mint's fresh holding price, pays out, and reduces these",
11860
- "counters by the accounting value cleared.",
11874
+ "Legacy per-vault fee custody account.",
11861
11875
  "",
11862
- "Mint/burn/performance go to `vault.roles.fee_collector`, protocol goes to the",
11863
- "hardcoded protocol fee recipient."
11876
+ "New fee accrual is denominated in canonical vault shares and stored on",
11877
+ "`VaultAccounting`. This account remains in existing instruction schemas for",
11878
+ "compatibility; its historical accounting-unit counters are no longer updated."
11864
11879
  ],
11865
11880
  "serialization": "bytemuck",
11866
11881
  "repr": {
@@ -12085,8 +12100,9 @@ var IDL = {
12085
12100
  {
12086
12101
  "name": "migrate_amount",
12087
12102
  "docs": [
12088
- "Reserved for partial migration; partial migration is unsupported, so this",
12089
- "must be `None` (a full vault migration). A `Some(_)` value is rejected."
12103
+ "Partial migration remains unsupported. `None` performs a regular full",
12104
+ "vault migration; `Some(0)` explicitly marks the final in-scope vault and",
12105
+ "permits bounded terminal source-accounting reconciliation."
12090
12106
  ],
12091
12107
  "type": {
12092
12108
  "option": "u64"
@@ -13390,10 +13406,16 @@ var IDL = {
13390
13406
  }
13391
13407
  },
13392
13408
  {
13393
- "name": "_padding_bool",
13409
+ "name": "migration_in_progress",
13394
13410
  "docs": [
13395
- "Reserved padding (previously `apy_settle_skip`). Kept as a field to",
13396
- "preserve the on-chain account layout for already-deployed vaults."
13411
+ "True while a legacy migration destination is still receiving backing",
13412
+ "and receipt-supply accounting. Oracle mutation and NAV settlement stay",
13413
+ "disabled until every configured receipt mint authority has moved to this vault",
13414
+ "and migration finalization clears the flag.",
13415
+ "",
13416
+ "This occupies the former `apy_settle_skip` padding byte, preserving the",
13417
+ "on-chain account layout for already-deployed vaults. Existing vaults read",
13418
+ "it as false."
13397
13419
  ],
13398
13420
  "type": {
13399
13421
  "defined": {
@@ -13704,7 +13726,7 @@ var IDL = {
13704
13726
  {
13705
13727
  "name": "tvl_limit",
13706
13728
  "docs": [
13707
- "Maximum TVL in deposit-asset base units. `0` disables the cap."
13729
+ "Maximum TVL in vault accounting units. `0` disables the cap."
13708
13730
  ],
13709
13731
  "type": "u64"
13710
13732
  },
@@ -14764,7 +14786,7 @@ var IDL = {
14764
14786
  {
14765
14787
  "name": "total_mint_supply",
14766
14788
  "docs": [
14767
- "Total supply of the vault's share mint."
14789
+ "Effective share supply: physical mint supply plus unminted fee shares."
14768
14790
  ],
14769
14791
  "type": "u64"
14770
14792
  },
@@ -14818,12 +14840,26 @@ var IDL = {
14818
14840
  }
14819
14841
  }
14820
14842
  },
14843
+ {
14844
+ "name": "pending_curator_fee_shares",
14845
+ "docs": [
14846
+ "Vault shares owed to the curator but not yet minted."
14847
+ ],
14848
+ "type": "u64"
14849
+ },
14850
+ {
14851
+ "name": "pending_protocol_fee_shares",
14852
+ "docs": [
14853
+ "Vault shares owed to the protocol but not yet minted."
14854
+ ],
14855
+ "type": "u64"
14856
+ },
14821
14857
  {
14822
14858
  "name": "_padding1",
14823
14859
  "type": {
14824
14860
  "array": [
14825
14861
  "u64",
14826
- 32
14862
+ 30
14827
14863
  ]
14828
14864
  }
14829
14865
  },
@@ -14872,8 +14908,8 @@ var IDL = {
14872
14908
  {
14873
14909
  "name": "asset_decimals",
14874
14910
  "docs": [
14875
- "Decimals of the deposit asset, cached so deposit/withdraw paths don't",
14876
- "need to deserialize the mint account."
14911
+ "Vault accounting precision. This matches the vault share mint; each",
14912
+ "holding stores its own mint precision independently."
14877
14913
  ],
14878
14914
  "type": "u8"
14879
14915
  },
@@ -14905,7 +14941,7 @@ var IDL = {
14905
14941
  {
14906
14942
  "name": "tvl_limit",
14907
14943
  "docs": [
14908
- "Maximum TVL in deposit-asset base units. `0` disables the cap."
14944
+ "Maximum TVL in vault accounting units. `0` disables the cap."
14909
14945
  ],
14910
14946
  "type": "u64"
14911
14947
  },
@@ -15689,8 +15725,8 @@ function coerceBool(value) {
15689
15725
  if (value && typeof value.toBool === "function") {
15690
15726
  return value.toBool();
15691
15727
  }
15692
- const record = value;
15693
- return Boolean(record?.value ?? record?.[0]);
15728
+ const record2 = value;
15729
+ return Boolean(record2?.value ?? record2?.[0]);
15694
15730
  }
15695
15731
 
15696
15732
  // src/client/builders/base.ts
@@ -15726,8 +15762,8 @@ function coerceBool2(value) {
15726
15762
  if (value && typeof value.toBool === "function") {
15727
15763
  return value.toBool();
15728
15764
  }
15729
- const record = value;
15730
- return Boolean(record?.value ?? record?.[0]);
15765
+ const record2 = value;
15766
+ return Boolean(record2?.value ?? record2?.[0]);
15731
15767
  }
15732
15768
  function pubkeyToAddress(value) {
15733
15769
  if (typeof value === "string") return (0, import_kit5.address)(value);
@@ -15737,8 +15773,8 @@ function pubkeyToAddress(value) {
15737
15773
  return (0, import_kit5.address)(String(value));
15738
15774
  }
15739
15775
  function tokenProgramAddressFromIdlEnum(value) {
15740
- const record = value;
15741
- if (record && "token2022" in record) {
15776
+ const record2 = value;
15777
+ if (record2 && "token2022" in record2) {
15742
15778
  return TOKEN_PROGRAM_ID;
15743
15779
  }
15744
15780
  return (0, import_kit5.address)(import_spl_token2.TOKEN_PROGRAM_ID.toBase58());
@@ -16112,7 +16148,7 @@ var CreateVaultBuilder = class extends VaultBuilderBase {
16112
16148
  const [vault] = await this.pda.deriveVaultPda(vaultId);
16113
16149
  const [vaultOracle] = await this.pda.deriveVaultOraclePda(vault);
16114
16150
  const [feeVault] = await this.pda.deriveFeeAuthorityPda(vault);
16115
- const assetDecimals = (await (0, import_token.fetchMint)(this.rpc, txArgs.strictAssetMint)).data.decimals;
16151
+ const accountingDecimals = (await (0, import_token.fetchMint)(this.rpc, txArgs.shareMint)).data.decimals;
16116
16152
  return {
16117
16153
  curator: txArgs.curator,
16118
16154
  vault,
@@ -16137,7 +16173,7 @@ var CreateVaultBuilder = class extends VaultBuilderBase {
16137
16173
  initialMintSharePrice: null,
16138
16174
  basePriceOracleType: txArgs.basePriceOracleType ?? 1,
16139
16175
  basePrice: new import_core3.BN(
16140
- (txArgs.basePrice ?? 10n ** BigInt(assetDecimals)).toString()
16176
+ (txArgs.basePrice ?? 10n ** BigInt(accountingDecimals)).toString()
16141
16177
  ),
16142
16178
  basePriceOracleAccount: txArgs.basePriceOracleAccount ?? DEFAULT_PRICE_ORACLE_ACCOUNT,
16143
16179
  forMigration: txArgs.forMigration ?? false
@@ -16313,8 +16349,9 @@ var SetProtocolFeeBuilder = class extends VaultBuilderBase {
16313
16349
  const [derivedVaultOracle] = await this.pda.deriveVaultOraclePda(
16314
16350
  txArgs.vault
16315
16351
  );
16352
+ const defaultProtocolAuthority = this.program.programId.toBase58() === VAULT_PROGRAM_ID ? LOCAL_PROTOCOL_ADMIN : PROTOCOL_ADMIN;
16316
16353
  return {
16317
- protocolAuthority: txArgs.protocolAuthority ?? PROTOCOL_ADMIN,
16354
+ protocolAuthority: txArgs.protocolAuthority ?? defaultProtocolAuthority,
16318
16355
  vault: txArgs.vault,
16319
16356
  vaultOracle: txArgs.vaultOracle ?? derivedVaultOracle,
16320
16357
  args: {
@@ -16511,82 +16548,53 @@ var CrankPerformanceFeesBuilder = class extends VaultBuilderBase {
16511
16548
  return this.program.methods.crankPerformanceFees().accountsPartial({
16512
16549
  cranker: (0, import_common18.toWeb3Pk)(args.cranker),
16513
16550
  vault: (0, import_common18.toWeb3Pk)(args.vault),
16514
- feeAssetMint: (0, import_common18.toWeb3Pk)(args.feeAssetMint),
16515
- feeVault: (0, import_common18.toWeb3Pk)(args.feeVault),
16516
- feeVaultAta: (0, import_common18.toWeb3Pk)(args.feeVaultAta),
16551
+ shareMint: (0, import_common18.toWeb3Pk)(args.shareMint),
16517
16552
  feeCollector: (0, import_common18.toWeb3Pk)(args.feeCollector),
16518
- feeCollectorFeeAssetAta: (0, import_common18.toWeb3Pk)(args.feeCollectorFeeAssetAta),
16553
+ feeCollectorShareAta: (0, import_common18.toWeb3Pk)(args.feeCollectorShareAta),
16519
16554
  protocolFeeCollector: (0, import_common18.toWeb3Pk)(args.protocolFeeCollector),
16520
- protocolFeeCollectorFeeAssetAta: (0, import_common18.toWeb3Pk)(
16521
- args.protocolFeeCollectorFeeAssetAta
16555
+ protocolFeeCollectorShareAta: (0, import_common18.toWeb3Pk)(
16556
+ args.protocolFeeCollectorShareAta
16522
16557
  ),
16523
- feeAssetTokenProgram: (0, import_common18.toWeb3Pk)(args.feeAssetTokenProgram),
16558
+ shareTokenProgram: (0, import_common18.toWeb3Pk)(args.shareTokenProgram),
16524
16559
  associatedTokenProgram: import_spl_token6.ASSOCIATED_TOKEN_PROGRAM_ID,
16525
16560
  systemProgram: import_web38.SystemProgram.programId
16526
16561
  }).instruction().then(import_common18.toKitInstruction);
16527
16562
  }
16528
16563
  async deriveIxArgs(txArgs) {
16529
- const feeAssetMint = await resolveVaultBaseAssetMint(
16564
+ const vaultState = await this.account.fetchVault(txArgs.vault);
16565
+ const shareMint = (0, import_common18.fromWeb3Pk)(vaultState.mint);
16566
+ const shareTokenProgram = txArgs.shareTokenProgram ?? tokenProgramAddressFromIdlEnum(vaultState.mintTokenProgram);
16567
+ const feeCollector = await resolveVaultFeeCollector(
16530
16568
  this.account,
16531
16569
  txArgs.vault,
16532
- txArgs.feeAssetMint
16570
+ txArgs.feeCollector
16533
16571
  );
16534
- const [feeVault] = await this.pda.deriveFeeAuthorityPda(txArgs.vault);
16535
- const [feeCollector, feeAssetTokenProgram] = await Promise.all([
16536
- resolveVaultFeeCollector(this.account, txArgs.vault, txArgs.feeCollector),
16537
- resolveFeeAssetTokenProgram(
16538
- this.account,
16539
- txArgs.vault,
16540
- feeAssetMint,
16541
- txArgs.feeAssetTokenProgram
16542
- )
16543
- ]);
16544
16572
  const protocolFeeCollector = resolveProtocolFeeRecipient(
16545
16573
  txArgs.protocolFeeCollector
16546
16574
  );
16547
16575
  return {
16548
16576
  cranker: txArgs.cranker,
16549
16577
  vault: txArgs.vault,
16550
- feeAssetMint,
16551
- feeVault,
16552
- feeVaultAta: (0, import_common18.getAtaAddress)(
16553
- feeAssetMint,
16554
- feeVault,
16555
- feeAssetTokenProgram,
16556
- true
16557
- ),
16578
+ shareMint,
16558
16579
  feeCollector,
16559
- feeCollectorFeeAssetAta: (0, import_common18.getAtaAddress)(
16560
- feeAssetMint,
16580
+ feeCollectorShareAta: (0, import_common18.getAtaAddress)(
16581
+ shareMint,
16561
16582
  feeCollector,
16562
- feeAssetTokenProgram
16583
+ shareTokenProgram
16563
16584
  ),
16564
16585
  protocolFeeCollector,
16565
16586
  // The protocol fee recipient is a hardcoded protocol-controlled address
16566
16587
  // that may be off-curve (e.g. a PDA / multisig vault), so allow an
16567
16588
  // off-curve owner when deriving its ATA.
16568
- protocolFeeCollectorFeeAssetAta: (0, import_common18.getAtaAddress)(
16569
- feeAssetMint,
16589
+ protocolFeeCollectorShareAta: (0, import_common18.getAtaAddress)(
16590
+ shareMint,
16570
16591
  protocolFeeCollector,
16571
- feeAssetTokenProgram,
16592
+ shareTokenProgram,
16572
16593
  true
16573
16594
  ),
16574
- feeAssetTokenProgram
16595
+ shareTokenProgram
16575
16596
  };
16576
16597
  }
16577
- async buildPreambleInstructions(args) {
16578
- const payer = (0, import_common18.toWeb3Pk)(args.cranker);
16579
- return [
16580
- (0, import_spl_token6.createAssociatedTokenAccountIdempotentInstruction)(
16581
- payer,
16582
- (0, import_common18.toWeb3Pk)(args.feeVaultAta),
16583
- (0, import_common18.toWeb3Pk)(args.feeVault),
16584
- (0, import_common18.toWeb3Pk)(args.feeAssetMint),
16585
- (0, import_common18.toWeb3Pk)(args.feeAssetTokenProgram),
16586
- import_spl_token6.ASSOCIATED_TOKEN_PROGRAM_ID
16587
- )
16588
- ].map(import_common18.toKitInstruction);
16589
- }
16590
16598
  async buildPlanExtras(args) {
16591
16599
  return {
16592
16600
  postSuccessCacheInvalidations: [{ vaultPda: args.vault }]
@@ -16594,11 +16602,10 @@ var CrankPerformanceFeesBuilder = class extends VaultBuilderBase {
16594
16602
  }
16595
16603
  async getTx(txArgs) {
16596
16604
  const args = await this.deriveIxArgs(txArgs);
16597
- const preambleInstructions = await this.buildPreambleInstructions(args);
16598
16605
  const instruction = await this.getIx(args);
16599
16606
  const extras = await this.buildPlanExtras(args);
16600
16607
  return {
16601
- instructions: [...preambleInstructions, instruction],
16608
+ instructions: [instruction],
16602
16609
  ...extras ?? {}
16603
16610
  };
16604
16611
  }
@@ -18158,7 +18165,7 @@ var VaultReallocationBuilder = class extends VaultBuilderBase {
18158
18165
  }
18159
18166
  async buildPreambleInstructions(args) {
18160
18167
  const payer = (0, import_common34.toWeb3Pk)(args.manager);
18161
- const instructions = [
18168
+ const instructions2 = [
18162
18169
  (0, import_spl_token17.createAssociatedTokenAccountIdempotentInstruction)(
18163
18170
  payer,
18164
18171
  (0, import_common34.toWeb3Pk)(args.allocationMintAta),
@@ -18193,7 +18200,7 @@ var VaultReallocationBuilder = class extends VaultBuilderBase {
18193
18200
  )
18194
18201
  ];
18195
18202
  if (args.sourceVault && args.sourceShareMint && args.sourceVaultMintAta && args.allocationSourceShareAta) {
18196
- instructions.push(
18203
+ instructions2.push(
18197
18204
  (0, import_spl_token17.createAssociatedTokenAccountIdempotentInstruction)(
18198
18205
  payer,
18199
18206
  (0, import_common34.toWeb3Pk)(args.sourceVaultMintAta),
@@ -18212,7 +18219,7 @@ var VaultReallocationBuilder = class extends VaultBuilderBase {
18212
18219
  )
18213
18220
  );
18214
18221
  }
18215
- return instructions.map(import_common34.toKitInstruction);
18222
+ return instructions2.map(import_common34.toKitInstruction);
18216
18223
  }
18217
18224
  async buildPlanExtras(args) {
18218
18225
  return {
@@ -18447,15 +18454,129 @@ function makeProvider(connection, payer) {
18447
18454
  });
18448
18455
  }
18449
18456
 
18457
+ // src/utils/squads.ts
18458
+ var squads = __toESM(require("@sqds/multisig"));
18459
+ var import_web321 = require("@solana/web3.js");
18460
+ function validateVaultIndex(vaultIndex) {
18461
+ if (!Number.isSafeInteger(vaultIndex) || vaultIndex < 0) {
18462
+ throw new Error("Squads vaultIndex must be a non-negative safe integer");
18463
+ }
18464
+ }
18465
+ function resolveSquadsWalletRoute(route) {
18466
+ validateVaultIndex(route.vaultIndex);
18467
+ const wallet = new import_web321.PublicKey(route.wallet);
18468
+ const multisigPda = new import_web321.PublicKey(route.multisigPda);
18469
+ const [vaultPda] = squads.getVaultPda({
18470
+ multisigPda,
18471
+ index: route.vaultIndex
18472
+ });
18473
+ return { ...route, wallet, multisigPda, vaultPda };
18474
+ }
18475
+ function findSquadsWalletRoute(wallet, routes) {
18476
+ const walletKey = typeof wallet === "string" ? new import_web321.PublicKey(wallet) : wallet;
18477
+ const route = routes.find(
18478
+ (candidate) => candidate.wallet === walletKey.toBase58()
18479
+ );
18480
+ return route ? resolveSquadsWalletRoute(route) : void 0;
18481
+ }
18482
+ function validateSquadsWalletRoutes(routes) {
18483
+ const wallets = /* @__PURE__ */ new Set();
18484
+ for (const route of routes) {
18485
+ const resolved = resolveSquadsWalletRoute(route);
18486
+ const wallet = resolved.wallet.toBase58();
18487
+ if (wallets.has(wallet)) {
18488
+ throw new Error(`Duplicate Squads route for wallet ${wallet}`);
18489
+ }
18490
+ wallets.add(wallet);
18491
+ }
18492
+ }
18493
+ function vaultAuthorityForWallet(wallet, routes) {
18494
+ const walletKey = typeof wallet === "string" ? new import_web321.PublicKey(wallet) : wallet;
18495
+ return findSquadsWalletRoute(walletKey, routes)?.vaultPda ?? walletKey;
18496
+ }
18497
+ async function prepareVaultTransaction(args) {
18498
+ const { connection, proposer, instructions: instructions2 } = args;
18499
+ const route = findSquadsWalletRoute(proposer, args.squadsRoutes ?? []);
18500
+ if (!route) {
18501
+ return {
18502
+ kind: "direct",
18503
+ transaction: new import_web321.Transaction().add(...instructions2),
18504
+ authority: proposer
18505
+ };
18506
+ }
18507
+ const multisig = await squads.accounts.Multisig.fromAccountAddress(
18508
+ connection,
18509
+ route.multisigPda
18510
+ );
18511
+ const member = multisig.members.find(
18512
+ (candidate) => candidate.key.equals(proposer)
18513
+ );
18514
+ if (!member) {
18515
+ throw new Error(
18516
+ `Wallet ${proposer.toBase58()} is not a member of Squads multisig ${route.multisigPda.toBase58()}`
18517
+ );
18518
+ }
18519
+ if (!squads.types.Permissions.has(
18520
+ member.permissions,
18521
+ squads.types.Permission.Initiate
18522
+ )) {
18523
+ throw new Error(
18524
+ `Wallet ${proposer.toBase58()} cannot initiate proposals for Squads multisig ${route.multisigPda.toBase58()}`
18525
+ );
18526
+ }
18527
+ const transactionIndex = BigInt(multisig.transactionIndex.toString()) + 1n;
18528
+ const { blockhash } = await connection.getLatestBlockhash("confirmed");
18529
+ const transactionMessage = new import_web321.TransactionMessage({
18530
+ payerKey: route.vaultPda,
18531
+ recentBlockhash: blockhash,
18532
+ instructions: [...instructions2]
18533
+ });
18534
+ const createVaultTransactionIx = squads.instructions.vaultTransactionCreate({
18535
+ multisigPda: route.multisigPda,
18536
+ transactionIndex,
18537
+ creator: proposer,
18538
+ vaultIndex: route.vaultIndex,
18539
+ ephemeralSigners: 0,
18540
+ transactionMessage,
18541
+ memo: route.memo
18542
+ });
18543
+ const createProposalIx = squads.instructions.proposalCreate({
18544
+ multisigPda: route.multisigPda,
18545
+ transactionIndex,
18546
+ creator: proposer
18547
+ });
18548
+ const [proposalPda] = squads.getProposalPda({
18549
+ multisigPda: route.multisigPda,
18550
+ transactionIndex
18551
+ });
18552
+ const [vaultTransactionPda] = squads.getTransactionPda({
18553
+ multisigPda: route.multisigPda,
18554
+ index: transactionIndex
18555
+ });
18556
+ return {
18557
+ kind: "squads",
18558
+ transaction: new import_web321.Transaction().add(
18559
+ createVaultTransactionIx,
18560
+ createProposalIx
18561
+ ),
18562
+ authority: route.vaultPda,
18563
+ multisigPda: route.multisigPda,
18564
+ vaultIndex: route.vaultIndex,
18565
+ transactionIndex,
18566
+ proposalPda,
18567
+ vaultTransactionPda
18568
+ };
18569
+ }
18570
+
18450
18571
  // src/utils/token.ts
18451
18572
  var import_spl_token18 = require("@solana/spl-token");
18452
- var import_web321 = require("@solana/web3.js");
18573
+ var import_web322 = require("@solana/web3.js");
18453
18574
  var import_common37 = __toESM(require_dist());
18454
18575
  async function createTokenMintIxs(connection, payer, authority, decimals, tokenProgram = import_spl_token18.TOKEN_2022_PROGRAM_ID) {
18455
- const mint = import_web321.Keypair.generate();
18576
+ const mint = import_web322.Keypair.generate();
18456
18577
  const lamports = await (0, import_spl_token18.getMinimumBalanceForRentExemptMint)(connection);
18457
18578
  const ixs = [
18458
- import_web321.SystemProgram.createAccount({
18579
+ import_web322.SystemProgram.createAccount({
18459
18580
  fromPubkey: payer,
18460
18581
  newAccountPubkey: mint.publicKey,
18461
18582
  space: import_spl_token18.MINT_SIZE,
@@ -18481,7 +18602,7 @@ async function createTokenMint(connection, payer, decimals, tokenProgram = impor
18481
18602
  tokenProgram
18482
18603
  );
18483
18604
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
18484
- const tx = new import_web321.Transaction().add(...ixs);
18605
+ const tx = new import_web322.Transaction().add(...ixs);
18485
18606
  tx.feePayer = payer.publicKey;
18486
18607
  tx.recentBlockhash = blockhash;
18487
18608
  tx.sign(payer, mint);
@@ -18520,7 +18641,7 @@ async function mintTokensTo(connection, payer, mint, destination, amount, tokenP
18520
18641
  tokenProgramPk
18521
18642
  )
18522
18643
  ];
18523
- const tx = new import_web321.Transaction().add(...ixs);
18644
+ const tx = new import_web322.Transaction().add(...ixs);
18524
18645
  await connection.sendTransaction(tx, [payer]);
18525
18646
  }
18526
18647
 
@@ -18793,8 +18914,8 @@ var WithdrawalQueueService = class {
18793
18914
  /** All withdrawal-queue accounts owned by the vault program. */
18794
18915
  async fetchAllQueues() {
18795
18916
  const program = this.client.program.account;
18796
- const accounts = await program.vaultWithdrawalQueue.all();
18797
- return accounts.map(
18917
+ const accounts2 = await program.vaultWithdrawalQueue.all();
18918
+ return accounts2.map(
18798
18919
  (entry) => this.toSnapshot((0, import_common38.fromWeb3Pk)(entry.publicKey), entry.account)
18799
18920
  );
18800
18921
  }
@@ -19153,21 +19274,85 @@ var JupiterPriceSource = class {
19153
19274
  }
19154
19275
  };
19155
19276
 
19156
- // src/services/consensusOracle/jupiterBalanceSource.ts
19157
- var import_web322 = require("@solana/web3.js");
19158
- var import_spl_token19 = require("@solana/spl-token");
19159
- var import_common40 = __toESM(require_dist());
19160
- var DEFAULT_BASE_URL2 = "https://lite-api.jup.ag/ultra/v1/balances";
19161
- var JupiterBalanceSource = class {
19162
- constructor(connection, opts = {}) {
19163
- this.connection = connection;
19164
- this.baseUrl = opts.baseUrl ?? DEFAULT_BASE_URL2;
19165
- this.fetchFn = opts.fetchFn ?? fetch;
19166
- this.rpcOnly = opts.rpcOnly ?? false;
19167
- this.log = opts.log ?? (() => {
19168
- });
19169
- }
19170
- async fetchBalances(owner) {
19277
+ // src/services/consensusOracle/nestPriceSource.ts
19278
+ var import_kit12 = require("@solana/kit");
19279
+ var NEST_API_BASE_URL = "https://api.nest.credit/v1";
19280
+ var NEST_VAULT_SLUG = "nest-perena-vault";
19281
+ var NEST_RWA_SHARE_MINT = (0, import_kit12.address)(
19282
+ "VyXKJnVhkSkB6KAozSZCiLQbuB1k1r6Nu4etNYVo5LJ"
19283
+ );
19284
+ async function fetchNestTokenPrice(nestVaultSlug = NEST_VAULT_SLUG, opts = {}) {
19285
+ const baseUrl = (opts.baseUrl ?? NEST_API_BASE_URL).replace(/\/$/, "");
19286
+ const response = await (opts.fetchFn ?? fetch)(
19287
+ `${baseUrl}/vaults/${encodeURIComponent(nestVaultSlug)}/price`
19288
+ );
19289
+ if (!response.ok) {
19290
+ throw new Error(
19291
+ `Nest price API request failed: ${response.status} ${response.statusText}`
19292
+ );
19293
+ }
19294
+ const body = await response.json();
19295
+ const price = [body.data?.interpolatedPrice, body.data?.price].map(Number).find((candidate) => Number.isFinite(candidate) && candidate > 0);
19296
+ if (price === void 0) {
19297
+ throw new Error("Nest price API returned no positive share price");
19298
+ }
19299
+ return price;
19300
+ }
19301
+ var NestPriceSource = class {
19302
+ constructor(opts = {}) {
19303
+ this.shareMint = opts.shareMint ?? NEST_RWA_SHARE_MINT;
19304
+ this.nestVaultSlug = opts.nestVaultSlug ?? NEST_VAULT_SLUG;
19305
+ this.options = { baseUrl: opts.baseUrl, fetchFn: opts.fetchFn };
19306
+ }
19307
+ async fetchUsdPrices(mints) {
19308
+ if (!mints.some((mint) => mint.toString() === this.shareMint.toString())) {
19309
+ return {};
19310
+ }
19311
+ return {
19312
+ [this.shareMint.toString()]: await fetchNestTokenPrice(
19313
+ this.nestVaultSlug,
19314
+ this.options
19315
+ )
19316
+ };
19317
+ }
19318
+ };
19319
+
19320
+ // src/services/consensusOracle/livePriceSource.ts
19321
+ var LivePriceSource = class {
19322
+ constructor(opts = {}) {
19323
+ this.jupiter = opts.jupiter ?? new JupiterPriceSource();
19324
+ this.nest = opts.nest ?? new NestPriceSource();
19325
+ }
19326
+ async fetchUsdPrices(mints) {
19327
+ const unique = [
19328
+ ...new Map(mints.map((mint) => [mint.toString(), mint])).values()
19329
+ ];
19330
+ const nestMint = this.nest.shareMint.toString();
19331
+ const jupiterMints = unique.filter((mint) => mint.toString() !== nestMint);
19332
+ const nestMints = unique.filter((mint) => mint.toString() === nestMint);
19333
+ const [jupiterPrices, nestPrices] = await Promise.all([
19334
+ this.jupiter.fetchUsdPrices(jupiterMints),
19335
+ this.nest.fetchUsdPrices(nestMints)
19336
+ ]);
19337
+ return { ...jupiterPrices, ...nestPrices };
19338
+ }
19339
+ };
19340
+
19341
+ // src/services/consensusOracle/jupiterBalanceSource.ts
19342
+ var import_web323 = require("@solana/web3.js");
19343
+ var import_spl_token19 = require("@solana/spl-token");
19344
+ var import_common40 = __toESM(require_dist());
19345
+ var DEFAULT_BASE_URL2 = "https://lite-api.jup.ag/ultra/v1/balances";
19346
+ var JupiterBalanceSource = class {
19347
+ constructor(connection, opts = {}) {
19348
+ this.connection = connection;
19349
+ this.baseUrl = opts.baseUrl ?? DEFAULT_BASE_URL2;
19350
+ this.fetchFn = opts.fetchFn ?? fetch;
19351
+ this.rpcOnly = opts.rpcOnly ?? false;
19352
+ this.log = opts.log ?? (() => {
19353
+ });
19354
+ }
19355
+ async fetchBalances(owner) {
19171
19356
  if (!this.rpcOnly) {
19172
19357
  try {
19173
19358
  const fromJup = await this.fetchFromJupiter(owner);
@@ -19211,7 +19396,7 @@ var JupiterBalanceSource = class {
19211
19396
  for (const programId of [import_spl_token19.TOKEN_PROGRAM_ID, import_spl_token19.TOKEN_2022_PROGRAM_ID]) {
19212
19397
  const { value } = await this.connection.getParsedTokenAccountsByOwner(
19213
19398
  ownerPk,
19214
- { programId: new import_web322.PublicKey(programId) }
19399
+ { programId: new import_web323.PublicKey(programId) }
19215
19400
  );
19216
19401
  for (const { account } of value) {
19217
19402
  const info = account.data.parsed?.info;
@@ -19261,12 +19446,12 @@ var StaticPositionProvider = class {
19261
19446
  };
19262
19447
 
19263
19448
  // src/services/consensusOracle/kaminoPositionProvider.ts
19264
- var import_kit12 = require("@solana/kit");
19265
- var import_web323 = require("@solana/web3.js");
19449
+ var import_kit13 = require("@solana/kit");
19450
+ var import_web324 = require("@solana/web3.js");
19266
19451
  var import_klend_sdk = require("@kamino-finance/klend-sdk");
19267
19452
  async function readKaminoBalance(manager, vault, sharesHolder) {
19268
19453
  const userShares = await manager.getUserSharesBalanceSingleVault(
19269
- (0, import_kit12.address)(sharesHolder.toBase58()),
19454
+ (0, import_kit13.address)(sharesHolder.toBase58()),
19270
19455
  vault
19271
19456
  );
19272
19457
  const tokensPerShare = await manager.getTokensPerShareSingleVault(vault);
@@ -19282,7 +19467,7 @@ var KaminoPositionProvider = class {
19282
19467
  async positionsFor(ctx) {
19283
19468
  const refs = ctx.refs.filter((r) => r.kind === "kamino");
19284
19469
  if (refs.length === 0) return [];
19285
- const rpc = (0, import_kit12.createSolanaRpc)(this.rpcUrl);
19470
+ const rpc = (0, import_kit13.createSolanaRpc)(this.rpcUrl);
19286
19471
  const slotDuration = await (0, import_klend_sdk.getMedianSlotDurationInMsFromLastEpochs)();
19287
19472
  const manager = new import_klend_sdk.KaminoManager(rpc, slotDuration);
19288
19473
  const out = [];
@@ -19295,11 +19480,11 @@ var KaminoPositionProvider = class {
19295
19480
  );
19296
19481
  continue;
19297
19482
  }
19298
- const kVault = new import_klend_sdk.KaminoVault(rpc, (0, import_kit12.address)(vaultState));
19483
+ const kVault = new import_klend_sdk.KaminoVault(rpc, (0, import_kit13.address)(vaultState));
19299
19484
  const amount = await readKaminoBalance(
19300
19485
  manager,
19301
19486
  kVault,
19302
- new import_web323.PublicKey(sharesHolder)
19487
+ new import_web324.PublicKey(sharesHolder)
19303
19488
  );
19304
19489
  out.push({ mint: ref.mint, amount });
19305
19490
  }
@@ -19308,7 +19493,7 @@ var KaminoPositionProvider = class {
19308
19493
  };
19309
19494
 
19310
19495
  // src/services/consensusOracle/marginfiPositionProvider.ts
19311
- var import_web324 = require("@solana/web3.js");
19496
+ var import_web325 = require("@solana/web3.js");
19312
19497
  var import_marginfi_client_v2 = require("@mrgnlabs/marginfi-client-v2");
19313
19498
  function parseBankPksFromMarginfiAccount(data) {
19314
19499
  const DISCRIMINATOR = 8;
@@ -19321,7 +19506,7 @@ function parseBankPksFromMarginfiAccount(data) {
19321
19506
  if (base + BALANCE_SIZE > data.length) break;
19322
19507
  const active = data[base];
19323
19508
  if (!active) continue;
19324
- out.push(new import_web324.PublicKey(data.subarray(base + 1, base + 33)));
19509
+ out.push(new import_web325.PublicKey(data.subarray(base + 1, base + 33)));
19325
19510
  }
19326
19511
  return out;
19327
19512
  }
@@ -19359,8 +19544,8 @@ var MarginfiPositionProvider = class {
19359
19544
  async positionsFor(ctx) {
19360
19545
  const refs = ctx.refs.filter((r) => r.kind === "marginfi");
19361
19546
  if (refs.length === 0) return [];
19362
- const explicitBanks = refs.map((r) => r.marginfiBank).filter(Boolean).map((bank) => new import_web324.PublicKey(bank));
19363
- const autoAccountPks = refs.filter((r) => !r.marginfiBank).map((r) => r.marginfiAccount).filter(Boolean).map((account) => new import_web324.PublicKey(account));
19547
+ const explicitBanks = refs.map((r) => r.marginfiBank).filter(Boolean).map((bank) => new import_web325.PublicKey(bank));
19548
+ const autoAccountPks = refs.filter((r) => !r.marginfiBank).map((r) => r.marginfiAccount).filter(Boolean).map((account) => new import_web325.PublicKey(account));
19364
19549
  const autoBanks = [];
19365
19550
  for (const accountPk of autoAccountPks) {
19366
19551
  try {
@@ -19391,14 +19576,14 @@ var MarginfiPositionProvider = class {
19391
19576
  if (bank) {
19392
19577
  const amount = await readMarginfiBalance(
19393
19578
  client,
19394
- new import_web324.PublicKey(account),
19395
- new import_web324.PublicKey(bank)
19579
+ new import_web325.PublicKey(account),
19580
+ new import_web325.PublicKey(bank)
19396
19581
  );
19397
19582
  out.push({ mint: ref.mint, amount });
19398
19583
  } else {
19399
19584
  const balances = await readAllMarginfiBalances(
19400
19585
  client,
19401
- new import_web324.PublicKey(account)
19586
+ new import_web325.PublicKey(account)
19402
19587
  );
19403
19588
  for (const { mint, amount } of balances) {
19404
19589
  out.push({ mint: mint.toBase58(), amount });
@@ -19414,11 +19599,15 @@ function createLiveConsensusOracleDeps(connection, opts = {}) {
19414
19599
  const log = opts.log ?? (() => {
19415
19600
  });
19416
19601
  const deps = {
19417
- priceSource: new JupiterPriceSource(),
19602
+ priceSource: new LivePriceSource(),
19418
19603
  balanceSource: new JupiterBalanceSource(connection, {
19419
19604
  rpcOnly: opts.rpcOnly ?? false,
19420
19605
  log
19421
- })
19606
+ }),
19607
+ yieldTracker: {
19608
+ getTotalOutstandingYield,
19609
+ getYieldPayments
19610
+ }
19422
19611
  };
19423
19612
  if (opts.includeExternalPositions ?? true) {
19424
19613
  deps.externalPositions = new ExternalPositionRegistry(
@@ -19433,8 +19622,861 @@ function createLiveConsensusOracleDeps(connection, opts = {}) {
19433
19622
  }
19434
19623
 
19435
19624
  // src/services/consensusOracle/consensusOracleService.ts
19436
- var import_web325 = require("@solana/web3.js");
19625
+ var import_web327 = require("@solana/web3.js");
19437
19626
  var import_common41 = __toESM(require_dist());
19627
+
19628
+ // src/services/consensusOracle/settlementSimulator.ts
19629
+ var import_kit14 = require("@solana/kit");
19630
+ var import_web326 = require("@solana/web3.js");
19631
+ var DEFAULT_SHARE_PRICE = 1000000n;
19632
+ var BPS_DENOMINATOR2 = 10000n;
19633
+ var SECONDS_PER_YEAR = 31536000n;
19634
+ var DEFAULT_STALENESS_SECS = 86400n;
19635
+ var CONSENSUS_MAX_DIFF_BPS = 8n;
19636
+ var MIN_CONSENSUS_SIGNERS = 2;
19637
+ var MAX_HOLDINGS = 12;
19638
+ var MAX_SIGNERS = 4;
19639
+ var ENTRY_SIZE = 272;
19640
+ var ENTRIES_OFFSET = 40;
19641
+ var PRICE_OFFSET = 40;
19642
+ var EXTERNAL_OFFSET = PRICE_OFFSET + MAX_HOLDINGS * 8;
19643
+ var APY_SCALE = 1000000000000000000n;
19644
+ var APY_LN_2 = 693147180559945309n;
19645
+ var APY_SERIES_TERMS = 32;
19646
+ function simulateConsensusOracleSettlement(args) {
19647
+ const warnings = [];
19648
+ const blockers = [];
19649
+ const vaultAccounting = record(args.vault.accounting);
19650
+ const feesConfig = record(args.vault.config.fees);
19651
+ const apyConfig = record(args.vault.config.apy);
19652
+ const tranchingEnabled = bool(args.vault.tranchingEnabled);
19653
+ const currentTvl = bigint(vaultAccounting.tvl);
19654
+ const pendingCuratorShares = bigint(vaultAccounting.pendingCuratorFeeShares);
19655
+ const pendingProtocolShares = bigint(
19656
+ vaultAccounting.pendingProtocolFeeShares
19657
+ );
19658
+ const cachedSupply = bigint(vaultAccounting.totalMintSupply);
19659
+ const reconciledSupply = args.physicalShareSupply === void 0 ? cachedSupply : args.physicalShareSupply + pendingCuratorShares + pendingProtocolShares;
19660
+ if (args.physicalShareSupply === void 0) {
19661
+ warnings.push(
19662
+ "regular share-mint supply was unavailable; using cached effective supply"
19663
+ );
19664
+ } else if (reconciledSupply !== cachedSupply) {
19665
+ warnings.push(
19666
+ `crank supply reconciliation changes regular supply ${cachedSupply} -> ${reconciledSupply}`
19667
+ );
19668
+ }
19669
+ const holdings = args.vault.holdings.map(decodeHolding);
19670
+ const oracle = decodeOracleData(args.oracleData, args.nowTs);
19671
+ const signerEntry = oracle.entries.find(
19672
+ (entry) => entry.signer === args.signer.toString()
19673
+ );
19674
+ if (!signerEntry) {
19675
+ blockers.push(`signer ${args.signer} is not registered in the oracle`);
19676
+ } else {
19677
+ signerEntry.lastUpdateTs = args.nowTs;
19678
+ for (const update of args.updates) {
19679
+ signerEntry.prices[update.holdingIndex] = update.price;
19680
+ signerEntry.externalAmounts[update.holdingIndex] = update.externalAmount;
19681
+ }
19682
+ }
19683
+ const consensus = applyConsensus(
19684
+ holdings,
19685
+ oracle.entries,
19686
+ args.nowTs,
19687
+ oracle.stalenessThresholdSecs
19688
+ );
19689
+ const proposedUpdatesLanded = args.updates.filter(
19690
+ (update) => consensus.find(
19691
+ (result) => result.holdingIndex === update.holdingIndex && result.wouldUpdateHolding
19692
+ )
19693
+ ).length;
19694
+ const consensusSummary = {
19695
+ allProposedUpdatesLand: proposedUpdatesLanded === args.updates.length && args.updates.length > 0,
19696
+ proposedUpdatesLanded,
19697
+ proposedUpdatesTotal: args.updates.length
19698
+ };
19699
+ const currentTranche = tranchingEnabled ? decodeTrancheState(args.trancheState, args, warnings, blockers) : void 0;
19700
+ const current = snapshot(
19701
+ currentTvl,
19702
+ reconciledSupply,
19703
+ bigint(vaultAccounting.mintSharePrice),
19704
+ currentTranche
19705
+ );
19706
+ let grossNav;
19707
+ try {
19708
+ grossNav = grossNavFromHoldings(
19709
+ holdings,
19710
+ args.nowTs,
19711
+ positiveOrDefault(
19712
+ bigint(args.vault.config.priceStalenessThresholdSecs),
19713
+ DEFAULT_STALENESS_SECS
19714
+ )
19715
+ );
19716
+ } catch (error) {
19717
+ blockers.push(message(error));
19718
+ }
19719
+ if (grossNav === void 0 || blockers.length > 0) {
19720
+ return {
19721
+ nowTs: args.nowTs,
19722
+ assetDecimals: args.vault.config.assetDecimals,
19723
+ ...consensusSummary,
19724
+ canSettle: false,
19725
+ blockers,
19726
+ warnings,
19727
+ consensus,
19728
+ grossNav,
19729
+ current
19730
+ };
19731
+ }
19732
+ try {
19733
+ const settlement = settleVault({
19734
+ grossNav,
19735
+ nowTs: args.nowTs,
19736
+ currentTvl,
19737
+ currentSharePrice: bigint(vaultAccounting.mintSharePrice),
19738
+ totalSupply: reconciledSupply,
19739
+ lossesEnabled: bool(args.vault.lossesEnabled),
19740
+ accountingLastUpdateTs: bigint(vaultAccounting.lastUpdateTs),
19741
+ priorSettledNavTs: oracle.settledNavTs,
19742
+ performanceFeeBps: number(feesConfig.performanceFeeBps),
19743
+ protocolFeeBps: number(feesConfig.protocolFeeBps),
19744
+ hwmSharePrice: bigint(vaultAccounting.hwmSharePrice),
19745
+ fixedApyBps: number(apyConfig.fixedApyBps),
19746
+ maxApyBps: number(apyConfig.maxApyBps),
19747
+ apyAnchorSharePrice: bigint(apyConfig.anchorSharePrice),
19748
+ apyAnchorTs: bigint(apyConfig.anchorTs),
19749
+ tranche: currentTranche
19750
+ });
19751
+ return {
19752
+ nowTs: args.nowTs,
19753
+ assetDecimals: args.vault.config.assetDecimals,
19754
+ ...consensusSummary,
19755
+ canSettle: true,
19756
+ blockers,
19757
+ warnings,
19758
+ consensus,
19759
+ grossNav,
19760
+ settledAccountingNav: settlement.settledAccountingNav,
19761
+ current,
19762
+ projected: settlement.projected,
19763
+ performanceFees: settlement.performanceFees
19764
+ };
19765
+ } catch (error) {
19766
+ blockers.push(message(error));
19767
+ return {
19768
+ nowTs: args.nowTs,
19769
+ assetDecimals: args.vault.config.assetDecimals,
19770
+ ...consensusSummary,
19771
+ canSettle: false,
19772
+ blockers,
19773
+ warnings,
19774
+ consensus,
19775
+ grossNav,
19776
+ current
19777
+ };
19778
+ }
19779
+ }
19780
+ function applyConsensus(holdings, entries, nowTs, stalenessThresholdSecs) {
19781
+ const results = [];
19782
+ for (let index = 0; index < holdings.length; index += 1) {
19783
+ const holding = holdings[index];
19784
+ if (holding.cleared || holding.priceOracleType !== "consensusoracle") {
19785
+ continue;
19786
+ }
19787
+ const reports = entries.filter(
19788
+ (entry) => entry.signer !== import_web326.PublicKey.default.toBase58() && isFresh(entry.lastUpdateTs, nowTs, stalenessThresholdSecs) && (entry.prices[index] ?? 0n) > 0n
19789
+ );
19790
+ const prices = reports.map((entry) => entry.prices[index] ?? 0n);
19791
+ const amounts = reports.map((entry) => entry.externalAmounts[index] ?? 0n);
19792
+ let reason;
19793
+ if (reports.length < MIN_CONSENSUS_SIGNERS) {
19794
+ reason = `only ${reports.length} fresh priced report(s); need ${MIN_CONSENSUS_SIGNERS}`;
19795
+ } else if (!withinDeviation(prices)) {
19796
+ reason = `price reports exceed ${CONSENSUS_MAX_DIFF_BPS}bps pairwise deviation`;
19797
+ } else if (!withinDeviation(amounts)) {
19798
+ reason = `external-amount reports exceed ${CONSENSUS_MAX_DIFF_BPS}bps pairwise deviation`;
19799
+ }
19800
+ if (reason) {
19801
+ results.push({
19802
+ holdingIndex: index,
19803
+ mint: holding.mint,
19804
+ reportCount: reports.length,
19805
+ wouldUpdateHolding: false,
19806
+ reason
19807
+ });
19808
+ continue;
19809
+ }
19810
+ const settledPrice = average(prices);
19811
+ const settledExternalAmount = average(amounts);
19812
+ const latestTs = reports.reduce(
19813
+ (latest, entry) => entry.lastUpdateTs > latest ? entry.lastUpdateTs : latest,
19814
+ 0n
19815
+ );
19816
+ const wouldUpdateHolding = latestTs > holding.lastUpdateTs && latestTs <= nowTs;
19817
+ if (wouldUpdateHolding) {
19818
+ holding.price = settledPrice;
19819
+ holding.externalAmount = settledExternalAmount;
19820
+ holding.lastUpdateTs = latestTs;
19821
+ if (!holding.isBase && holding.localAmount === 0n && holding.externalAmount === 0n) {
19822
+ holding.cleared = true;
19823
+ }
19824
+ }
19825
+ results.push({
19826
+ holdingIndex: index,
19827
+ mint: holding.mint,
19828
+ reportCount: reports.length,
19829
+ settledPrice,
19830
+ settledExternalAmount,
19831
+ wouldUpdateHolding,
19832
+ reason: wouldUpdateHolding ? void 0 : `aggregate timestamp ${latestTs} is not newer than holding timestamp ${holding.lastUpdateTs}`
19833
+ });
19834
+ }
19835
+ return results;
19836
+ }
19837
+ function settleVault(args) {
19838
+ if (args.grossNav < args.currentTvl && !args.lossesEnabled) {
19839
+ throw new Error(
19840
+ `crank would fail LossesDisabled: gross NAV ${args.grossNav} < current TVL ${args.currentTvl}`
19841
+ );
19842
+ }
19843
+ const priorTs = args.priorSettledNavTs > 0n ? args.priorSettledNavTs : max(args.accountingLastUpdateTs, args.apyAnchorTs);
19844
+ const nextApyValue = args.tranche ? args.grossNav : sharePriceForValue(args.grossNav, args.totalSupply);
19845
+ if (nextApyValue !== void 0) {
19846
+ validateRealizedApy(
19847
+ args.tranche ? args.currentTvl : args.currentSharePrice,
19848
+ priorTs,
19849
+ nextApyValue,
19850
+ args.nowTs,
19851
+ args.maxApyBps
19852
+ );
19853
+ }
19854
+ let regularValue;
19855
+ let regularSharePrice = args.currentSharePrice;
19856
+ let curatorFee = 0n;
19857
+ let protocolFee = 0n;
19858
+ let settledAccountingNav;
19859
+ if (args.tranche) {
19860
+ settledAccountingNav = args.grossNav;
19861
+ regularValue = settleTrancheNav(
19862
+ args.tranche,
19863
+ args.currentTvl,
19864
+ settledAccountingNav,
19865
+ args.nowTs
19866
+ );
19867
+ const juniorFees = settleShareClassPerformanceFee(
19868
+ args.tranche.junior,
19869
+ args.performanceFeeBps,
19870
+ args.protocolFeeBps
19871
+ );
19872
+ const regularFees = settleRegularPerformanceFee(
19873
+ regularValue,
19874
+ args.totalSupply,
19875
+ args.hwmSharePrice,
19876
+ args.performanceFeeBps,
19877
+ args.protocolFeeBps
19878
+ );
19879
+ regularValue = regularFees.netValue;
19880
+ regularSharePrice = sharePriceForValue(regularValue, args.totalSupply) ?? regularSharePrice;
19881
+ curatorFee = juniorFees.curator + regularFees.fees.curator;
19882
+ protocolFee = juniorFees.protocol + regularFees.fees.protocol;
19883
+ } else {
19884
+ settledAccountingNav = settleFixedApyNav({
19885
+ currentSharePrice: args.currentSharePrice,
19886
+ reportedNav: args.grossNav,
19887
+ nowTs: args.nowTs,
19888
+ totalSupply: args.totalSupply,
19889
+ fixedApyBps: args.fixedApyBps,
19890
+ anchorSharePrice: args.apyAnchorSharePrice,
19891
+ anchorTs: args.apyAnchorTs
19892
+ });
19893
+ const regularFees = settleRegularPerformanceFee(
19894
+ settledAccountingNav,
19895
+ args.totalSupply,
19896
+ args.hwmSharePrice,
19897
+ args.performanceFeeBps,
19898
+ args.protocolFeeBps
19899
+ );
19900
+ regularValue = regularFees.netValue;
19901
+ regularSharePrice = sharePriceForValue(regularValue, args.totalSupply) ?? regularSharePrice;
19902
+ curatorFee = regularFees.fees.curator;
19903
+ protocolFee = regularFees.fees.protocol;
19904
+ }
19905
+ const totalFees = curatorFee + protocolFee;
19906
+ const netRegularBacking = mulDiv2(
19907
+ args.totalSupply,
19908
+ regularSharePrice,
19909
+ DEFAULT_SHARE_PRICE
19910
+ );
19911
+ let mintedShares = 0n;
19912
+ if (totalFees > 0n) {
19913
+ mintedShares = args.totalSupply === 0n ? totalFees : mulDiv2(totalFees, args.totalSupply, netRegularBacking);
19914
+ if (mintedShares === 0n) {
19915
+ throw new Error(
19916
+ "crank would fail ZeroAssetAmount while accruing fee shares"
19917
+ );
19918
+ }
19919
+ }
19920
+ const projectedSupply = args.totalSupply + mintedShares;
19921
+ const projected = snapshot(
19922
+ // Fee value is carved out, then added back when converted to vault shares.
19923
+ settledAccountingNav,
19924
+ projectedSupply,
19925
+ regularSharePrice,
19926
+ args.tranche
19927
+ );
19928
+ return {
19929
+ settledAccountingNav,
19930
+ projected,
19931
+ performanceFees: {
19932
+ curator: curatorFee,
19933
+ protocol: protocolFee,
19934
+ total: totalFees,
19935
+ mintedShares
19936
+ }
19937
+ };
19938
+ }
19939
+ function settleTrancheNav(tranche, currentTvl, nextTvl, nowTs) {
19940
+ const before = tranche.junior.value + tranche.senior.value;
19941
+ if (before === 0n) {
19942
+ tranche.lastSettledTs = nowTs;
19943
+ return nextTvl;
19944
+ }
19945
+ if (currentTvl <= 0n || before > currentTvl) {
19946
+ throw new Error(
19947
+ `crank would fail InvalidArgument: tranche value ${before}, current TVL ${currentTvl}`
19948
+ );
19949
+ }
19950
+ const after = mulDiv2(before, nextTvl, currentTvl);
19951
+ if (after >= before) {
19952
+ let gain = after - before;
19953
+ const entitlement = seniorEntitlement(tranche, nowTs);
19954
+ const seniorGain = entitlement < gain ? entitlement : gain;
19955
+ tranche.senior.value += seniorGain;
19956
+ gain -= seniorGain;
19957
+ if (gain > 0n) {
19958
+ if (tranche.junior.totalSupply > 0n) tranche.junior.value += gain;
19959
+ else tranche.senior.value += gain;
19960
+ }
19961
+ } else {
19962
+ const loss = before - after;
19963
+ const juniorLoss = tranche.junior.value < loss ? tranche.junior.value : loss;
19964
+ tranche.junior.value -= juniorLoss;
19965
+ tranche.senior.value -= loss - juniorLoss;
19966
+ }
19967
+ refreshShareClass(tranche.junior);
19968
+ refreshShareClass(tranche.senior);
19969
+ tranche.lastSettledTs = nowTs;
19970
+ return nextTvl - tranche.junior.value - tranche.senior.value;
19971
+ }
19972
+ function seniorEntitlement(tranche, nowTs) {
19973
+ if (tranche.seniorApyAnchorTs <= 0n) {
19974
+ tranche.seniorApyAnchorSharePrice = tranche.senior.sharePrice;
19975
+ tranche.seniorApyAnchorTs = tranche.lastSettledTs > 0n ? tranche.lastSettledTs : nowTs;
19976
+ }
19977
+ if (tranche.seniorFixedApyBps === 0 || tranche.seniorApyAnchorSharePrice === 0n || tranche.senior.totalSupply === 0n || tranche.seniorApyAnchorTs <= 0n || nowTs <= tranche.seniorApyAnchorTs) {
19978
+ return 0n;
19979
+ }
19980
+ const targetPrice = applyEffectiveApy(
19981
+ tranche.seniorApyAnchorSharePrice,
19982
+ tranche.seniorFixedApyBps,
19983
+ nowTs - tranche.seniorApyAnchorTs
19984
+ );
19985
+ const targetValue = mulDiv2(
19986
+ targetPrice,
19987
+ tranche.senior.totalSupply,
19988
+ DEFAULT_SHARE_PRICE
19989
+ );
19990
+ return targetValue > tranche.senior.value ? targetValue - tranche.senior.value : 0n;
19991
+ }
19992
+ function settleShareClassPerformanceFee(shareClass, performanceFeeBps, protocolFeeBps) {
19993
+ refreshShareClass(shareClass);
19994
+ const grossPrice = shareClass.sharePrice;
19995
+ if (shareClass.hwmSharePrice === 0n) {
19996
+ shareClass.hwmSharePrice = grossPrice;
19997
+ return noFees();
19998
+ }
19999
+ if (performanceFeeBps + protocolFeeBps === 0 || shareClass.totalSupply === 0n || grossPrice <= shareClass.hwmSharePrice) {
20000
+ return noFees();
20001
+ }
20002
+ const gainValue = mulDiv2(
20003
+ grossPrice - shareClass.hwmSharePrice,
20004
+ shareClass.totalSupply,
20005
+ DEFAULT_SHARE_PRICE
20006
+ );
20007
+ const fees = feeAmounts(gainValue, performanceFeeBps, protocolFeeBps);
20008
+ const total = fees.curator + fees.protocol;
20009
+ if (total > 0n) {
20010
+ shareClass.value -= total;
20011
+ refreshShareClass(shareClass);
20012
+ shareClass.hwmSharePrice = shareClass.sharePrice;
20013
+ }
20014
+ return fees;
20015
+ }
20016
+ function settleRegularPerformanceFee(grossValue, supply, hwmSharePrice, performanceFeeBps, protocolFeeBps) {
20017
+ if (supply === 0n) return { netValue: grossValue, fees: noFees() };
20018
+ const grossPrice = sharePriceForValue(grossValue, supply);
20019
+ if (hwmSharePrice === 0n || grossPrice <= hwmSharePrice || performanceFeeBps + protocolFeeBps === 0) {
20020
+ return { netValue: grossValue, fees: noFees() };
20021
+ }
20022
+ const gainValue = mulDiv2(
20023
+ supply,
20024
+ grossPrice - hwmSharePrice,
20025
+ DEFAULT_SHARE_PRICE
20026
+ );
20027
+ const fees = feeAmounts(gainValue, performanceFeeBps, protocolFeeBps);
20028
+ return {
20029
+ netValue: grossValue - fees.curator - fees.protocol,
20030
+ fees
20031
+ };
20032
+ }
20033
+ function settleFixedApyNav(args) {
20034
+ if (args.fixedApyBps === 0 || args.currentSharePrice === 0n || args.totalSupply === 0n || args.anchorSharePrice === 0n || args.anchorTs <= 0n) {
20035
+ return args.reportedNav;
20036
+ }
20037
+ if (args.nowTs <= args.anchorTs) {
20038
+ const anchoredNav = mulDiv2(
20039
+ args.totalSupply,
20040
+ args.anchorSharePrice,
20041
+ DEFAULT_SHARE_PRICE
20042
+ );
20043
+ if (args.reportedNav !== anchoredNav) {
20044
+ throw new Error("crank would fail InvalidOracleUpdate at APY anchor");
20045
+ }
20046
+ return args.reportedNav;
20047
+ }
20048
+ const fixedPrice = applyEffectiveApy(
20049
+ args.anchorSharePrice,
20050
+ args.fixedApyBps,
20051
+ args.nowTs - args.anchorTs
20052
+ );
20053
+ const fixedNav = mulDiv2(args.totalSupply, fixedPrice, DEFAULT_SHARE_PRICE);
20054
+ return args.reportedNav >= fixedNav ? fixedNav : args.reportedNav;
20055
+ }
20056
+ function validateRealizedApy(priorValue, priorTs, nextValue, nextTs, maxApyBps) {
20057
+ if (maxApyBps === 0 || priorValue === 0n || priorTs <= 0n || nextValue <= priorValue) {
20058
+ return;
20059
+ }
20060
+ const elapsed = nextTs - priorTs;
20061
+ if (elapsed <= 0n) throw new Error("crank would fail MaxApyExceeded");
20062
+ const lhs = (nextValue - priorValue) * BPS_DENOMINATOR2 * SECONDS_PER_YEAR;
20063
+ const rhs = BigInt(maxApyBps) * priorValue * elapsed;
20064
+ if (lhs > rhs) {
20065
+ const implied = lhs / (priorValue * elapsed);
20066
+ throw new Error(
20067
+ `crank would fail MaxApyExceeded: implied ${implied}bps > ${maxApyBps}bps`
20068
+ );
20069
+ }
20070
+ }
20071
+ function grossNavFromHoldings(holdings, nowTs, stalenessSecs) {
20072
+ let nav = 0n;
20073
+ for (const holding of holdings) {
20074
+ if (holding.cleared) continue;
20075
+ const amount = holding.localAmount + holding.externalAmount;
20076
+ if (amount === 0n && !holding.isBase) continue;
20077
+ if (holding.price <= 0n) {
20078
+ throw new Error(`crank blocked: holding ${holding.mint} is unpriced`);
20079
+ }
20080
+ if (holding.priceOracleType !== "none" && (holding.lastUpdateTs <= 0n || nowTs - holding.lastUpdateTs < 0n || nowTs - holding.lastUpdateTs > stalenessSecs)) {
20081
+ throw new Error(
20082
+ `crank blocked: holding ${holding.mint} price is stale (ts=${holding.lastUpdateTs})`
20083
+ );
20084
+ }
20085
+ if (amount > 0n) {
20086
+ nav += mulDiv2(amount, holding.price, 10n ** BigInt(holding.decimals));
20087
+ }
20088
+ }
20089
+ return nav;
20090
+ }
20091
+ function decodeOracleData(data, nowTs) {
20092
+ if (data.length < ENTRIES_OFFSET + MAX_SIGNERS * ENTRY_SIZE) {
20093
+ throw new Error(`oracle payload is too short (${data.length} bytes)`);
20094
+ }
20095
+ const entries = [];
20096
+ for (let signerIndex = 0; signerIndex < MAX_SIGNERS; signerIndex += 1) {
20097
+ const offset = ENTRIES_OFFSET + signerIndex * ENTRY_SIZE;
20098
+ const signerBytes = new Uint8Array(data.slice(offset, offset + 32));
20099
+ const prices = Array.from(
20100
+ { length: MAX_HOLDINGS },
20101
+ (_, holdingIndex) => readU64(data, offset + PRICE_OFFSET + holdingIndex * 8)
20102
+ );
20103
+ const externalAmounts = Array.from(
20104
+ { length: MAX_HOLDINGS },
20105
+ (_, holdingIndex) => readU64(data, offset + EXTERNAL_OFFSET + holdingIndex * 8)
20106
+ );
20107
+ entries.push({
20108
+ signer: new import_web326.PublicKey(signerBytes).toBase58(),
20109
+ lastUpdateTs: readI64(data, offset + 32),
20110
+ prices,
20111
+ externalAmounts
20112
+ });
20113
+ }
20114
+ const pendingOffset = ENTRIES_OFFSET + MAX_SIGNERS * ENTRY_SIZE;
20115
+ const pendingEffectiveTs = readI64(data, pendingOffset + 128);
20116
+ const pendingCount = data[pendingOffset + 136] ?? 0;
20117
+ if (pendingCount > 0 && pendingCount <= MAX_SIGNERS && nowTs >= pendingEffectiveTs) {
20118
+ for (let index = 0; index < MAX_SIGNERS; index += 1) {
20119
+ const signerBytes = new Uint8Array(
20120
+ data.slice(pendingOffset + index * 32, pendingOffset + (index + 1) * 32)
20121
+ );
20122
+ entries[index] = {
20123
+ signer: index < pendingCount ? new import_web326.PublicKey(signerBytes).toBase58() : import_web326.PublicKey.default.toBase58(),
20124
+ lastUpdateTs: 0n,
20125
+ prices: Array(MAX_HOLDINGS).fill(0n),
20126
+ externalAmounts: Array(MAX_HOLDINGS).fill(0n)
20127
+ };
20128
+ }
20129
+ }
20130
+ return {
20131
+ settledNavTs: readI64(data, 8),
20132
+ stalenessThresholdSecs: positiveOrDefault(
20133
+ readI64(data, 32),
20134
+ DEFAULT_STALENESS_SECS
20135
+ ),
20136
+ entries
20137
+ };
20138
+ }
20139
+ function decodeHolding(value) {
20140
+ const holding = record(value);
20141
+ const mintString = pubkeyString3(holding.mint);
20142
+ return {
20143
+ mint: (0, import_kit14.address)(mintString),
20144
+ decimals: number(holding.decimals),
20145
+ priceOracleType: variant(holding.priceOracleType),
20146
+ isBase: bool(holding.isBase),
20147
+ localAmount: bigint(holding.localAmount),
20148
+ externalAmount: bigint(holding.externalAmount),
20149
+ price: bigint(holding.price),
20150
+ lastUpdateTs: bigint(holding.lastUpdateTs),
20151
+ cleared: mintString === import_web326.PublicKey.default.toBase58()
20152
+ };
20153
+ }
20154
+ function decodeTrancheState(decoded, args, warnings, blockers) {
20155
+ if (!decoded) {
20156
+ blockers.push("tranching is enabled but the tranche state was unavailable");
20157
+ return void 0;
20158
+ }
20159
+ const junior = decodeShareClass(decoded.junior);
20160
+ const senior = decodeShareClass(decoded.senior);
20161
+ if (args.physicalJuniorSupply === void 0) {
20162
+ warnings.push(
20163
+ "junior mint supply unavailable; using cached tranche supply"
20164
+ );
20165
+ } else {
20166
+ junior.totalSupply = args.physicalJuniorSupply;
20167
+ refreshShareClass(junior);
20168
+ }
20169
+ if (args.physicalSeniorSupply === void 0) {
20170
+ warnings.push(
20171
+ "senior mint supply unavailable; using cached tranche supply"
20172
+ );
20173
+ } else {
20174
+ senior.totalSupply = args.physicalSeniorSupply;
20175
+ refreshShareClass(senior);
20176
+ }
20177
+ return {
20178
+ junior,
20179
+ senior,
20180
+ seniorFixedApyBps: number(decoded.config.seniorFixedApyBps),
20181
+ lastSettledTs: bigint(decoded.lastSettledTs),
20182
+ seniorApyAnchorSharePrice: bigint(decoded.seniorApyAnchorSharePrice),
20183
+ seniorApyAnchorTs: bigint(decoded.seniorApyAnchorTs)
20184
+ };
20185
+ }
20186
+ function decodeShareClass(value) {
20187
+ const decoded = record(value);
20188
+ return {
20189
+ value: bigint(decoded.value),
20190
+ totalSupply: bigint(decoded.totalSupply),
20191
+ sharePrice: bigint(decoded.sharePrice),
20192
+ hwmSharePrice: bigint(decoded.hwmSharePrice)
20193
+ };
20194
+ }
20195
+ function snapshot(tvl, regularSupply, regularSharePrice, tranche) {
20196
+ const regularValue = mulDiv2(
20197
+ regularSupply,
20198
+ regularSharePrice,
20199
+ DEFAULT_SHARE_PRICE
20200
+ );
20201
+ return {
20202
+ tvl,
20203
+ regular: {
20204
+ value: regularValue,
20205
+ totalSupply: regularSupply,
20206
+ sharePrice: regularSharePrice
20207
+ },
20208
+ ...tranche ? {
20209
+ junior: publicShareClass(tranche.junior),
20210
+ senior: publicShareClass(tranche.senior)
20211
+ } : {}
20212
+ };
20213
+ }
20214
+ function publicShareClass(value) {
20215
+ return {
20216
+ value: value.value,
20217
+ totalSupply: value.totalSupply,
20218
+ sharePrice: value.sharePrice
20219
+ };
20220
+ }
20221
+ function refreshShareClass(value) {
20222
+ value.sharePrice = value.totalSupply === 0n ? DEFAULT_SHARE_PRICE : mulDiv2(value.value, DEFAULT_SHARE_PRICE, value.totalSupply);
20223
+ }
20224
+ function sharePriceForValue(value, supply) {
20225
+ return supply === 0n ? void 0 : mulDiv2(value, DEFAULT_SHARE_PRICE, supply);
20226
+ }
20227
+ function feeAmounts(value, performanceFeeBps, protocolFeeBps) {
20228
+ return {
20229
+ curator: mulDiv2(value, BigInt(performanceFeeBps), BPS_DENOMINATOR2),
20230
+ protocol: mulDiv2(value, BigInt(protocolFeeBps), BPS_DENOMINATOR2)
20231
+ };
20232
+ }
20233
+ function noFees() {
20234
+ return { curator: 0n, protocol: 0n };
20235
+ }
20236
+ function withinDeviation(values) {
20237
+ for (let i = 0; i < values.length; i += 1) {
20238
+ for (let j = i + 1; j < values.length; j += 1) {
20239
+ const a = values[i];
20240
+ const b = values[j];
20241
+ if (a === b) continue;
20242
+ if (a === 0n || b === 0n) return false;
20243
+ const diff = abs(a * BPS_DENOMINATOR2 / b - BPS_DENOMINATOR2);
20244
+ if (diff > CONSENSUS_MAX_DIFF_BPS) return false;
20245
+ }
20246
+ }
20247
+ return true;
20248
+ }
20249
+ function average(values) {
20250
+ return values.reduce((sum, value) => sum + value, 0n) / BigInt(values.length);
20251
+ }
20252
+ function isFresh(lastTs, nowTs, staleness) {
20253
+ if (lastTs <= 0n) return false;
20254
+ const age = nowTs - lastTs;
20255
+ return age >= 0n && age <= staleness;
20256
+ }
20257
+ function applyEffectiveApy(anchor, apyBps, elapsedSecs) {
20258
+ if (anchor === 0n || apyBps === 0 || elapsedSecs === 0n) return anchor;
20259
+ if (apyBps < 0 || apyBps > 1e4) throw new Error("invalid APY bps");
20260
+ const base = APY_SCALE + mulDiv2(BigInt(apyBps), APY_SCALE, BPS_DENOMINATOR2);
20261
+ const wholeYears = elapsedSecs / SECONDS_PER_YEAR;
20262
+ const remainder = elapsedSecs % SECONDS_PER_YEAR;
20263
+ const wholeMultiplier = fixedPointPow(base, wholeYears);
20264
+ const fractionalMultiplier = remainder === 0n ? APY_SCALE : fixedPointExp(
20265
+ mulDiv2(
20266
+ fixedPointLnBetweenOneAndTwo(base),
20267
+ remainder,
20268
+ SECONDS_PER_YEAR
20269
+ )
20270
+ );
20271
+ return mulDiv2(
20272
+ anchor,
20273
+ fixedPointMul(wholeMultiplier, fractionalMultiplier),
20274
+ APY_SCALE
20275
+ );
20276
+ }
20277
+ function fixedPointMul(lhs, rhs) {
20278
+ const lhsWhole = lhs / APY_SCALE;
20279
+ const lhsRemainder = lhs % APY_SCALE;
20280
+ const rhsWhole = rhs / APY_SCALE;
20281
+ const rhsRemainder = rhs % APY_SCALE;
20282
+ return lhsWhole * rhs + lhsRemainder * rhsWhole + lhsRemainder * rhsRemainder / APY_SCALE;
20283
+ }
20284
+ function fixedPointPow(baseInput, exponentInput) {
20285
+ let base = baseInput;
20286
+ let exponent = exponentInput;
20287
+ let result = APY_SCALE;
20288
+ while (exponent > 0n) {
20289
+ if ((exponent & 1n) === 1n) result = fixedPointMul(result, base);
20290
+ exponent >>= 1n;
20291
+ if (exponent > 0n) base = fixedPointMul(base, base);
20292
+ }
20293
+ return result;
20294
+ }
20295
+ function fixedPointLnBetweenOneAndTwo(value) {
20296
+ if (value < APY_SCALE || value > 2n * APY_SCALE) {
20297
+ throw new Error("APY logarithm input out of range");
20298
+ }
20299
+ const z = mulDiv2(value - APY_SCALE, APY_SCALE, value + APY_SCALE);
20300
+ const zSquared = fixedPointMul(z, z);
20301
+ let power = z;
20302
+ let sum = 0n;
20303
+ for (let index = 0; index < APY_SERIES_TERMS; index += 1) {
20304
+ sum += power / BigInt(2 * index + 1);
20305
+ power = fixedPointMul(power, zSquared);
20306
+ }
20307
+ return sum * 2n;
20308
+ }
20309
+ function fixedPointExp(value) {
20310
+ if (value > APY_LN_2) throw new Error("APY exponent input out of range");
20311
+ let sum = APY_SCALE;
20312
+ let term = APY_SCALE;
20313
+ for (let divisor = 1; divisor <= APY_SERIES_TERMS; divisor += 1) {
20314
+ term = fixedPointMul(term, value) / BigInt(divisor);
20315
+ if (term === 0n) break;
20316
+ sum += term;
20317
+ }
20318
+ return sum;
20319
+ }
20320
+ function readU64(data, offset) {
20321
+ let value = 0n;
20322
+ for (let index = 0; index < 8; index += 1) {
20323
+ value |= BigInt(data[offset + index] ?? 0) << BigInt(index * 8);
20324
+ }
20325
+ return value;
20326
+ }
20327
+ function readI64(data, offset) {
20328
+ const value = readU64(data, offset);
20329
+ return value >= 0x8000000000000000n ? value - 0x10000000000000000n : value;
20330
+ }
20331
+ function mulDiv2(a, b, c) {
20332
+ if (c === 0n) throw new Error("division by zero in settlement simulation");
20333
+ return a * b / c;
20334
+ }
20335
+ function record(value) {
20336
+ return value && typeof value === "object" ? value : {};
20337
+ }
20338
+ function bigint(value) {
20339
+ if (value === void 0 || value === null) return 0n;
20340
+ if (typeof value === "bigint") return value;
20341
+ if (typeof value === "number" || typeof value === "string") {
20342
+ return BigInt(value);
20343
+ }
20344
+ return BigInt(String(value));
20345
+ }
20346
+ function number(value) {
20347
+ return Number(bigint(value));
20348
+ }
20349
+ function bool(value) {
20350
+ if (typeof value === "boolean") return value;
20351
+ if (typeof value === "number") return value !== 0;
20352
+ if (value && typeof value.toBool === "function") {
20353
+ return value.toBool();
20354
+ }
20355
+ const pod = value;
20356
+ return Boolean(pod?.value ?? pod?.[0]);
20357
+ }
20358
+ function variant(value) {
20359
+ return (value && typeof value === "object" ? Object.keys(value)[0] ?? "" : String(value ?? "")).toLowerCase();
20360
+ }
20361
+ function pubkeyString3(value) {
20362
+ if (typeof value === "string") return value;
20363
+ if (value && typeof value.toBase58 === "function") {
20364
+ return value.toBase58();
20365
+ }
20366
+ return String(value);
20367
+ }
20368
+ function positiveOrDefault(value, fallback) {
20369
+ return value > 0n ? value : fallback;
20370
+ }
20371
+ function max(a, b) {
20372
+ return a > b ? a : b;
20373
+ }
20374
+ function abs(value) {
20375
+ return value < 0n ? -value : value;
20376
+ }
20377
+ function message(error) {
20378
+ return error instanceof Error ? error.message : String(error);
20379
+ }
20380
+ function formatSettlementSimulation(simulation) {
20381
+ const lines = [];
20382
+ lines.push(
20383
+ ` proposed oracle values: ${simulation.allProposedUpdatesLand ? "WOULD REACH CONSENSUS" : "WOULD NOT ALL LAND"} (${simulation.proposedUpdatesLanded}/${simulation.proposedUpdatesTotal} holdings)`
20384
+ );
20385
+ lines.push(
20386
+ ` crank simulation: ${simulation.canSettle ? "WOULD SETTLE" : "BLOCKED"}`
20387
+ );
20388
+ for (const holding of simulation.consensus) {
20389
+ const detail = holding.settledPrice ? `price=${holding.settledPrice} external=${holding.settledExternalAmount}` : holding.reason ?? "no aggregate";
20390
+ lines.push(
20391
+ ` consensus #${holding.holdingIndex} ${holding.mint}: ${holding.reportCount} report(s), ${holding.wouldUpdateHolding ? "lands" : "unchanged"} (${detail})`
20392
+ );
20393
+ }
20394
+ if (simulation.grossNav !== void 0) {
20395
+ lines.push(
20396
+ ` gross NAV: ${formatUnits(
20397
+ simulation.grossNav,
20398
+ simulation.assetDecimals
20399
+ )} [${simulation.grossNav}]`
20400
+ );
20401
+ }
20402
+ if (simulation.settledAccountingNav !== void 0 && simulation.settledAccountingNav !== simulation.grossNav) {
20403
+ lines.push(
20404
+ ` accounting NAV after fixed APY: ${formatUnits(
20405
+ simulation.settledAccountingNav,
20406
+ simulation.assetDecimals
20407
+ )} [${simulation.settledAccountingNav}]`
20408
+ );
20409
+ }
20410
+ if (simulation.projected) {
20411
+ lines.push(
20412
+ ` TVL: ${formatTransition(
20413
+ simulation.current.tvl,
20414
+ simulation.projected.tvl,
20415
+ simulation.assetDecimals
20416
+ )}`
20417
+ );
20418
+ lines.push(
20419
+ ` regular: ${formatTransition(
20420
+ simulation.current.regular.sharePrice,
20421
+ simulation.projected.regular.sharePrice,
20422
+ 6
20423
+ )} per share`
20424
+ );
20425
+ lines.push(
20426
+ ` supply ${simulation.current.regular.totalSupply} -> ${simulation.projected.regular.totalSupply}, backing ${simulation.current.regular.value} -> ${simulation.projected.regular.value}`
20427
+ );
20428
+ if (simulation.current.junior && simulation.projected.junior) {
20429
+ lines.push(
20430
+ ` junior: ${formatTransition(
20431
+ simulation.current.junior.sharePrice,
20432
+ simulation.projected.junior.sharePrice,
20433
+ 6
20434
+ )} per share`
20435
+ );
20436
+ lines.push(
20437
+ ` supply ${simulation.current.junior.totalSupply} -> ${simulation.projected.junior.totalSupply}, value ${simulation.current.junior.value} -> ${simulation.projected.junior.value}`
20438
+ );
20439
+ }
20440
+ if (simulation.current.senior && simulation.projected.senior) {
20441
+ lines.push(
20442
+ ` senior: ${formatTransition(
20443
+ simulation.current.senior.sharePrice,
20444
+ simulation.projected.senior.sharePrice,
20445
+ 6
20446
+ )} per share`
20447
+ );
20448
+ lines.push(
20449
+ ` supply ${simulation.current.senior.totalSupply} -> ${simulation.projected.senior.totalSupply}, value ${simulation.current.senior.value} -> ${simulation.projected.senior.value}`
20450
+ );
20451
+ }
20452
+ }
20453
+ if (simulation.performanceFees) {
20454
+ lines.push(
20455
+ ` performance fees: curator=${simulation.performanceFees.curator} protocol=${simulation.performanceFees.protocol} total=${simulation.performanceFees.total} fee_shares=${simulation.performanceFees.mintedShares}`
20456
+ );
20457
+ }
20458
+ for (const blocker of simulation.blockers)
20459
+ lines.push(` BLOCKER: ${blocker}`);
20460
+ for (const warning of simulation.warnings)
20461
+ lines.push(` warning: ${warning}`);
20462
+ return lines;
20463
+ }
20464
+ function formatTransition(before, after, decimals) {
20465
+ return `${formatUnits(before, decimals)} [${before}] -> ${formatUnits(
20466
+ after,
20467
+ decimals
20468
+ )} [${after}]`;
20469
+ }
20470
+ function formatUnits(value, decimals) {
20471
+ const negative = value < 0n;
20472
+ const absolute = negative ? -value : value;
20473
+ const scale = 10n ** BigInt(decimals);
20474
+ const whole = absolute / scale;
20475
+ const fraction = (absolute % scale).toString().padStart(decimals, "0").replace(/0+$/, "");
20476
+ return `${negative ? "-" : ""}${whole}${fraction ? `.${fraction}` : ""}`;
20477
+ }
20478
+
20479
+ // src/services/consensusOracle/consensusOracleService.ts
19438
20480
  var SYSTEM_PROGRAM2 = "11111111111111111111111111111111";
19439
20481
  var CONSENSUS_ORACLE_VARIANT = "consensusoracle";
19440
20482
  function variantName2(value) {
@@ -19444,8 +20486,8 @@ function variantName2(value) {
19444
20486
  function coerceBool3(value) {
19445
20487
  if (typeof value === "boolean") return value;
19446
20488
  if (typeof value === "number") return value !== 0;
19447
- const record = value;
19448
- return Boolean(record?.value ?? record?.[0]);
20489
+ const record2 = value;
20490
+ return Boolean(record2?.value ?? record2?.[0]);
19449
20491
  }
19450
20492
  function priceInAccountingUnit(usd, baseUsd, assetDecimals) {
19451
20493
  return BigInt(Math.round(usd / baseUsd * 10 ** assetDecimals));
@@ -19467,7 +20509,7 @@ function parseExternalLiquidityRefs(vaultState) {
19467
20509
  if (!data || data.length < 40) continue;
19468
20510
  if (data[0] !== 1) continue;
19469
20511
  const pubkeyBytes = new Uint8Array(data.slice(8, 40));
19470
- const userAccount = new import_web325.PublicKey(pubkeyBytes).toBase58();
20512
+ const userAccount = new import_web327.PublicKey(pubkeyBytes).toBase58();
19471
20513
  refs.push({
19472
20514
  kind: "marginfi",
19473
20515
  mint: "",
@@ -19492,22 +20534,60 @@ var ConsensusOracleService = class {
19492
20534
  });
19493
20535
  const dryRun = opts.dryRun ?? false;
19494
20536
  const vaultState = await this.fetchDecodedVault(target.vault);
19495
- const consensusHoldings = selectConsensusHoldings(vaultState.holdings);
20537
+ const receiptMints = await this.fetchReceiptMints(target.vault, vaultState);
20538
+ const consensusHoldings = selectConsensusHoldings(
20539
+ vaultState.holdings,
20540
+ receiptMints
20541
+ );
20542
+ const filteredCount = vaultState.holdings.filter(
20543
+ (holding) => receiptMints.has((0, import_common41.fromWeb3Pk)(holding.mint).toString())
20544
+ ).length;
20545
+ if (filteredCount > 0) {
20546
+ log(
20547
+ `vault ${target.vault}: excluded ${filteredCount} vault/tranche receipt mint holding(s)`
20548
+ );
20549
+ }
19496
20550
  if (consensusHoldings.length === 0) {
19497
20551
  log(`vault ${target.vault}: no consensus holdings, skipping`);
19498
20552
  return { vault: target.vault, updates: [], dryRun };
19499
20553
  }
20554
+ const filteredTarget = filterTargetHoldings(target, receiptMints);
20555
+ await this.assertNoUnconfirmedYieldPayments(filteredTarget);
19500
20556
  const inputs = await this.gatherPricingInputs(
19501
- target,
20557
+ filteredTarget,
19502
20558
  vaultState,
19503
20559
  consensusHoldings
19504
20560
  );
19505
20561
  const updates = await this.buildUpdates(consensusHoldings, inputs);
19506
20562
  if (dryRun) {
19507
20563
  log(`vault ${target.vault}: dry run, ${updates.length} holding(s)`);
19508
- return { vault: target.vault, updates, dryRun: true };
20564
+ try {
20565
+ const settlementSimulation = await this.simulateDryRunSettlement(
20566
+ signer,
20567
+ target.vault,
20568
+ vaultState,
20569
+ updates
20570
+ );
20571
+ return {
20572
+ vault: target.vault,
20573
+ updates,
20574
+ dryRun: true,
20575
+ settlementSimulation
20576
+ };
20577
+ } catch (error) {
20578
+ const settlementSimulationError = error instanceof Error ? error.message : String(error);
20579
+ log(
20580
+ `vault ${target.vault}: settlement simulation unavailable: ${settlementSimulationError}`
20581
+ );
20582
+ return {
20583
+ vault: target.vault,
20584
+ updates,
20585
+ dryRun: true,
20586
+ settlementSimulationError
20587
+ };
20588
+ }
19509
20589
  }
19510
- const { updateSignature, crankSignature, crankSkippedReason } = await this.settleVault(signer, target.vault, updates, vaultState, log);
20590
+ const { updateSignature, crankSignature, crankSkippedReason } = await this.settleVault(signer, filteredTarget, updates, vaultState, log);
19511
20591
  return {
19512
20592
  vault: target.vault,
19513
20593
  updates,
@@ -19517,6 +20597,76 @@ var ConsensusOracleService = class {
19517
20597
  crankSkippedReason
19518
20598
  };
19519
20599
  }
20600
+ /** Read canonical supplies and replay the exact on-chain settlement path. */
20601
+ async simulateDryRunSettlement(signer, vault, vaultState, updates) {
20602
+ const tranchingEnabled = coerceBool3(vaultState.tranchingEnabled);
20603
+ const [oracleState, trancheState] = await Promise.all([
20604
+ this.client.account.fetchVaultOracleForVault(vault, { fresh: true }),
20605
+ tranchingEnabled ? this.client.account.fetchVaultTrancheStateForVault(vault, {
20606
+ fresh: true
20607
+ }) : Promise.resolve(void 0)
20608
+ ]);
20609
+ const mintKeys = [new import_web327.PublicKey(vaultState.mint)];
20610
+ if (trancheState) {
20611
+ mintKeys.push(
20612
+ new import_web327.PublicKey(trancheState.config.juniorMint),
20613
+ new import_web327.PublicKey(trancheState.config.seniorMint)
20614
+ );
20615
+ }
20616
+ const mintAccounts = await this.client.provider.connection.getMultipleAccountsInfo(
20617
+ mintKeys,
20618
+ "confirmed"
20619
+ );
20620
+ const supplies = mintAccounts.map((info, index) => {
20621
+ if (!info)
20622
+ throw new Error(`share mint ${mintKeys[index]} does not exist`);
20623
+ return readSplMintSupply(info.data);
20624
+ });
20625
+ return simulateConsensusOracleSettlement({
20626
+ vault: vaultState,
20627
+ oracleData: oracleState.data,
20628
+ trancheState,
20629
+ updates,
20630
+ signer: (0, import_common41.fromWeb3Pk)(signer.publicKey),
20631
+ nowTs: BigInt(Math.floor(this.clock.now() / 1e3)),
20632
+ physicalShareSupply: supplies[0],
20633
+ physicalJuniorSupply: tranchingEnabled ? supplies[1] : void 0,
20634
+ physicalSeniorSupply: tranchingEnabled ? supplies[2] : void 0
20635
+ });
20636
+ }
20637
+ /**
20638
+ * Fail closed while any configured yield account has an unsettled payment.
20639
+ * The payout must be confirmed only after it is visible in the same wallet
20640
+ * balance source used by this service. Until then, no oracle update is safe.
20641
+ */
20642
+ async assertNoUnconfirmedYieldPayments(target) {
20643
+ const accountNames = [
20644
+ ...new Set(
20645
+ (target.holdings ?? []).flatMap(
20646
+ (holding) => holding.yieldAccountNames ?? []
20647
+ )
20648
+ )
20649
+ ];
20650
+ if (accountNames.length === 0) return;
20651
+ if (!this.deps.yieldTracker) {
20652
+ throw new Error(
20653
+ `vault ${target.vault}: yield accounts are configured but no yield tracker is available`
20654
+ );
20655
+ }
20656
+ for (const accountName of accountNames) {
20657
+ const payments = await this.deps.yieldTracker.getYieldPayments(
20658
+ accountName
20659
+ );
20660
+ const unconfirmed = payments.filter(
20661
+ (payment) => payment.status !== "confirmed"
20662
+ );
20663
+ if (unconfirmed.length > 0) {
20664
+ throw new Error(
20665
+ `vault ${target.vault}: oracle update blocked because yield account "${accountName}" has ${unconfirmed.length} unconfirmed payment(s): ` + unconfirmed.map((payment) => payment.id).join(", ")
20666
+ );
20667
+ }
20668
+ }
20669
+ }
19520
20670
  /**
19521
20671
  * Drive several vaults in sequence. Non-fatal: a failure on one vault is
19522
20672
  * recorded and the rest still run (mirrors the oracle-updater daemon).
@@ -19605,6 +20755,28 @@ var ConsensusOracleService = class {
19605
20755
  fresh: true
19606
20756
  });
19607
20757
  }
20758
+ /**
20759
+ * Receipt mints issued by this vault are liabilities/shares, not underlying
20760
+ * assets for its own NAV. Exclude them even if they were registered as
20761
+ * consensus-priced holdings.
20762
+ */
20763
+ async fetchReceiptMints(vault, vaultState) {
20764
+ const receiptMints = /* @__PURE__ */ new Set();
20765
+ if (vaultState.mint) {
20766
+ receiptMints.add((0, import_common41.fromWeb3Pk)(vaultState.mint).toString());
20767
+ }
20768
+ if (!coerceBool3(vaultState.tranchingEnabled)) return receiptMints;
20769
+ const trancheState = await this.client.account.fetchVaultTrancheStateForVault(vault, {
20770
+ fresh: true
20771
+ });
20772
+ receiptMints.add(
20773
+ (0, import_common41.fromWeb3Pk)(trancheState.config.juniorMint).toString()
20774
+ );
20775
+ receiptMints.add(
20776
+ (0, import_common41.fromWeb3Pk)(trancheState.config.seniorMint).toString()
20777
+ );
20778
+ return receiptMints;
20779
+ }
19608
20780
  /** Fetch every external input the per-holding updates draw on, in parallel-ish. */
19609
20781
  async gatherPricingInputs(target, vaultState, consensusHoldings) {
19610
20782
  const manager = (0, import_common41.fromWeb3Pk)(vaultState.roles.manager);
@@ -19714,7 +20886,8 @@ var ConsensusOracleService = class {
19714
20886
  }
19715
20887
  // ── Settlement ───────────────────────────────────────────────────────────────
19716
20888
  /** Push the consensus report for all holdings, then settle NAV. */
19717
- async settleVault(signer, vault, updates, vaultState, log) {
20889
+ async settleVault(signer, target, updates, vaultState, log) {
20890
+ const vault = target.vault;
19718
20891
  log(
19719
20892
  `vault ${vault}: submitting ${updates.length} consensus asset update(s)`
19720
20893
  );
@@ -19724,6 +20897,7 @@ var ConsensusOracleService = class {
19724
20897
  );
19725
20898
  }
19726
20899
  await this.logProspectiveApy(vault, updates, vaultState, log);
20900
+ await this.assertNoUnconfirmedYieldPayments(target);
19727
20901
  const updateSignature = await this.oracle.updateAssetConsensusPrice(
19728
20902
  signer,
19729
20903
  {
@@ -19774,8 +20948,8 @@ var ConsensusOracleService = class {
19774
20948
  const nowSecs = BigInt(Math.floor(this.clock.now() / 1e3));
19775
20949
  const elapsedSecs = nowSecs - settledNavTs;
19776
20950
  if (elapsedSecs <= 0n) return;
19777
- const SECONDS_PER_YEAR2 = 365n * 24n * 3600n;
19778
- const apyBps = (prospectiveNav - settledNav) * SECONDS_PER_YEAR2 * 10000n / (settledNav * elapsedSecs);
20951
+ const SECONDS_PER_YEAR3 = 365n * 24n * 3600n;
20952
+ const apyBps = (prospectiveNav - settledNav) * SECONDS_PER_YEAR3 * 10000n / (settledNav * elapsedSecs);
19779
20953
  log(
19780
20954
  `vault ${vault}: prospective NAV ${prospectiveNav} vs settled ${settledNav} (elapsed ${elapsedSecs}s) \u2192 implied APY ${apyBps}bps`
19781
20955
  );
@@ -19791,13 +20965,23 @@ function readI64LE(data, offset) {
19791
20965
  if (value >= 0x8000000000000000n) value -= 0x10000000000000000n;
19792
20966
  return value;
19793
20967
  }
19794
- var ENTRY_SIZE = 272;
19795
- var ENTRIES_OFFSET = 40;
20968
+ function readSplMintSupply(data) {
20969
+ if (data.length < 44) {
20970
+ throw new Error(`invalid SPL mint account: expected at least 44 bytes`);
20971
+ }
20972
+ let supply = 0n;
20973
+ for (let i = 0; i < 8; i += 1) {
20974
+ supply |= BigInt(data[36 + i]) << BigInt(8 * i);
20975
+ }
20976
+ return supply;
20977
+ }
20978
+ var ENTRY_SIZE2 = 272;
20979
+ var ENTRIES_OFFSET2 = 40;
19796
20980
  var MAX_CONSENSUS_SIGNERS = 4;
19797
20981
  function signerInOracleData(data, signerBytes) {
19798
20982
  const ZERO_PUBKEY = new Uint8Array(32);
19799
20983
  for (let i = 0; i < MAX_CONSENSUS_SIGNERS; i++) {
19800
- const off = ENTRIES_OFFSET + i * ENTRY_SIZE;
20984
+ const off = ENTRIES_OFFSET2 + i * ENTRY_SIZE2;
19801
20985
  const slice = data.slice(off, off + 32);
19802
20986
  if (slice.length < 32) break;
19803
20987
  const bytes = new Uint8Array(slice);
@@ -19807,12 +20991,21 @@ function signerInOracleData(data, signerBytes) {
19807
20991
  }
19808
20992
  return false;
19809
20993
  }
19810
- function selectConsensusHoldings(holdings) {
20994
+ function selectConsensusHoldings(holdings, excludedMints = /* @__PURE__ */ new Set()) {
19811
20995
  return holdings.map((holding, holdingIndex) => ({ holding, holdingIndex })).filter(({ holding }) => {
19812
20996
  const mint = (0, import_common41.fromWeb3Pk)(holding.mint);
19813
- return mint !== SYSTEM_PROGRAM2 && variantName2(holding.priceOracleType).toLowerCase() === CONSENSUS_ORACLE_VARIANT;
20997
+ return mint !== SYSTEM_PROGRAM2 && !excludedMints.has(mint.toString()) && variantName2(holding.priceOracleType).toLowerCase() === CONSENSUS_ORACLE_VARIANT;
19814
20998
  });
19815
20999
  }
21000
+ function filterTargetHoldings(target, excludedMints) {
21001
+ if (!target.holdings?.length || excludedMints.size === 0) return target;
21002
+ return {
21003
+ ...target,
21004
+ holdings: target.holdings.filter(
21005
+ (holding) => !excludedMints.has(holding.mint.toString())
21006
+ )
21007
+ };
21008
+ }
19816
21009
 
19817
21010
  // src/services/consensusOracle/runLiveConsensusOracle.ts
19818
21011
  async function runLiveConsensusOracle(env, oracleSigner, opts = {}) {
@@ -19836,7 +21029,7 @@ async function runLiveConsensusOracle(env, oracleSigner, opts = {}) {
19836
21029
  }
19837
21030
 
19838
21031
  // src/services/consensusOracle/mockYieldTracker.ts
19839
- var SECONDS_PER_YEAR = 365 * 24 * 60 * 60;
21032
+ var SECONDS_PER_YEAR2 = 365 * 24 * 60 * 60;
19840
21033
  var MockYieldTracker = class {
19841
21034
  constructor(opts = {}) {
19842
21035
  this.accounts = /* @__PURE__ */ new Map();
@@ -19868,6 +21061,12 @@ var MockYieldTracker = class {
19868
21061
  }
19869
21062
  return state;
19870
21063
  }
21064
+ async getYieldPayments(accountName) {
21065
+ return this.require(accountName).yieldPayments.map((payment) => ({
21066
+ id: payment.paymentId,
21067
+ status: payment.status
21068
+ }));
21069
+ }
19871
21070
  async getYield(accountName, start, end) {
19872
21071
  const state = this.require(accountName);
19873
21072
  const windowStartMs = Math.max(
@@ -19885,12 +21084,12 @@ var MockYieldTracker = class {
19885
21084
  let segStart = windowStartMs;
19886
21085
  for (const cf of boundaries) {
19887
21086
  const dtSecs = (cf.ts - segStart) / 1e3;
19888
- totalYield += principal * apr * (dtSecs / SECONDS_PER_YEAR);
21087
+ totalYield += principal * apr * (dtSecs / SECONDS_PER_YEAR2);
19889
21088
  principal += cf.amount;
19890
21089
  segStart = cf.ts;
19891
21090
  }
19892
21091
  const tailSecs = Math.max(0, (windowEndMs - segStart) / 1e3);
19893
- totalYield += principal * apr * (tailSecs / SECONDS_PER_YEAR);
21092
+ totalYield += principal * apr * (tailSecs / SECONDS_PER_YEAR2);
19894
21093
  const paidYield = state.yieldPayments.reduce((sum, payment) => {
19895
21094
  return payment.status === "confirmed" && payment.effectiveAt > windowStartMs && payment.effectiveAt <= windowEndMs ? sum + payment.amount : sum;
19896
21095
  }, 0);
@@ -19910,22 +21109,22 @@ var MockYieldTracker = class {
19910
21109
  async getTotalYield(accountNames, start, end) {
19911
21110
  let total = 0;
19912
21111
  for (const name of accountNames) {
19913
- const snapshot = await this.getYield(name, start, end);
19914
- total += snapshot.totalYield;
21112
+ const snapshot2 = await this.getYield(name, start, end);
21113
+ total += snapshot2.totalYield;
19915
21114
  }
19916
21115
  return total;
19917
21116
  }
19918
21117
  async getTotalOutstandingYield(accountNames, start, end) {
19919
21118
  let total = 0;
19920
21119
  for (const name of accountNames) {
19921
- const snapshot = await this.getYield(name, start, end);
19922
- total += snapshot.outstandingYield;
21120
+ const snapshot2 = await this.getYield(name, start, end);
21121
+ total += snapshot2.outstandingYield;
19923
21122
  }
19924
21123
  return total;
19925
21124
  }
19926
21125
  async getBalance(accountName, atTime) {
19927
- const snapshot = await this.getYield(accountName, void 0, atTime);
19928
- return snapshot.principalAtEnd + snapshot.outstandingYield;
21126
+ const snapshot2 = await this.getYield(accountName, void 0, atTime);
21127
+ return snapshot2.principalAtEnd + snapshot2.outstandingYield;
19929
21128
  }
19930
21129
  async addCashflow(params) {
19931
21130
  const state = this.require(params.accountName);
@@ -19977,12 +21176,12 @@ var MockYieldTracker = class {
19977
21176
  let cumulativePaid = 0;
19978
21177
  for (const candidate of chronologicalPayments) {
19979
21178
  cumulativePaid += candidate.amount;
19980
- const snapshot = await this.getYield(
21179
+ const snapshot2 = await this.getYield(
19981
21180
  params.accountName,
19982
21181
  void 0,
19983
21182
  new Date(candidate.effectiveAt)
19984
21183
  );
19985
- if (cumulativePaid > snapshot.totalYield + 1e-9) {
21184
+ if (cumulativePaid > snapshot2.totalYield + 1e-9) {
19986
21185
  throw new Error("Confirmed payment exceeds accrued unpaid yield");
19987
21186
  }
19988
21187
  }
@@ -19992,8 +21191,8 @@ var MockYieldTracker = class {
19992
21191
  };
19993
21192
 
19994
21193
  // src/services/externalLiquidityIntegrityService.ts
19995
- var import_kit13 = require("@solana/kit");
19996
- var import_web326 = require("@solana/web3.js");
21194
+ var import_kit15 = require("@solana/kit");
21195
+ var import_web328 = require("@solana/web3.js");
19997
21196
  var import_common42 = __toESM(require_dist());
19998
21197
  var import_marginfi2 = __toESM(require_dist2());
19999
21198
  function parseActiveSlots(externalLiquidity) {
@@ -20006,7 +21205,7 @@ function parseActiveSlots(externalLiquidity) {
20006
21205
  if (discriminant === 0) continue;
20007
21206
  if (discriminant !== 1) continue;
20008
21207
  const pubkeyBytes = new Uint8Array(data.slice(8, 40));
20009
- const userAccount = (0, import_common42.toAddress)(new import_web326.PublicKey(pubkeyBytes));
21208
+ const userAccount = (0, import_common42.toAddress)(new import_web328.PublicKey(pubkeyBytes));
20010
21209
  results.push({ index: i, source: "marginfi", userAccount });
20011
21210
  }
20012
21211
  return results;
@@ -20072,7 +21271,7 @@ var ExternalLiquidityIntegrityService = class {
20072
21271
  return result;
20073
21272
  }
20074
21273
  const hwManagerAddress = (0, import_common42.fromWeb3Pk)(hwManager.publicKey);
20075
- const vaultPk = new import_web326.PublicKey(vault.toString());
21274
+ const vaultPk = new import_web328.PublicKey(vault.toString());
20076
21275
  const registeredHwManager = pubkeyStr(
20077
21276
  vaultState.roles.hwManager
20078
21277
  );
@@ -20099,7 +21298,7 @@ var ExternalLiquidityIntegrityService = class {
20099
21298
  continue;
20100
21299
  }
20101
21300
  for (const holding of holdings) {
20102
- const mintAddress = (0, import_kit13.address)(pubkeyStr(holding.mint));
21301
+ const mintAddress = (0, import_kit15.address)(pubkeyStr(holding.mint));
20103
21302
  const localAmount = toBigInt2(holding.localAmount);
20104
21303
  const marginfiAccounts = (0, import_marginfi2.marginfiAccountsForMint)(mintAddress);
20105
21304
  if (!marginfiAccounts) {
@@ -20215,11 +21414,17 @@ var ExternalLiquidityIntegrityService = class {
20215
21414
  JupiterPriceSource,
20216
21415
  JupiterSwapBuilder,
20217
21416
  KaminoPositionProvider,
21417
+ LOCAL_PROTOCOL_ADMIN,
21418
+ LivePriceSource,
20218
21419
  MAX_PRICE_STALENESS_THRESHOLD_SECS,
20219
21420
  ManagerRedepositAssetBuilder,
20220
21421
  ManagerWithdrawAssetBuilder,
20221
21422
  MarginfiPositionProvider,
20222
21423
  MockYieldTracker,
21424
+ NEST_API_BASE_URL,
21425
+ NEST_RWA_SHARE_MINT,
21426
+ NEST_VAULT_SLUG,
21427
+ NestPriceSource,
20223
21428
  OracleService,
20224
21429
  PROGRAM_FEE_EXEMPT_OWNER_WHITELIST,
20225
21430
  PROTOCOL_ADMIN,
@@ -20262,6 +21467,7 @@ var ExternalLiquidityIntegrityService = class {
20262
21467
  WithdrawalQueueService,
20263
21468
  addCashflowUpdate,
20264
21469
  address,
21470
+ applyEffectiveApy,
20265
21471
  confirmYieldPayment,
20266
21472
  createAccount,
20267
21473
  createLiveConsensusOracleDeps,
@@ -20273,6 +21479,9 @@ var ExternalLiquidityIntegrityService = class {
20273
21479
  dateToStr,
20274
21480
  defaultKeypairPath,
20275
21481
  deleteAccount,
21482
+ fetchNestTokenPrice,
21483
+ findSquadsWalletRoute,
21484
+ formatSettlementSimulation,
20276
21485
  fromUiAmount,
20277
21486
  getAccounts,
20278
21487
  getBalance,
@@ -20288,11 +21497,16 @@ var ExternalLiquidityIntegrityService = class {
20288
21497
  loadKeypair,
20289
21498
  makeProvider,
20290
21499
  mintTokensTo,
21500
+ prepareVaultTransaction,
20291
21501
  resolveKeypairPath,
21502
+ resolveSquadsWalletRoute,
20292
21503
  roundToNextUtcMidnight,
20293
21504
  runLiveConsensusOracle,
21505
+ simulateConsensusOracleSettlement,
20294
21506
  systemClock,
20295
21507
  toUiAmount,
20296
21508
  updateAccount,
20297
- updateDynamicApr
21509
+ updateDynamicApr,
21510
+ validateSquadsWalletRoutes,
21511
+ vaultAuthorityForWallet
20298
21512
  });