@perena/vault-sdk 1.0.19 → 1.0.23

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
  }));
@@ -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,27 +594,27 @@ 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
614
  const message = new web3_js_1.TransactionMessage({
615
615
  payerKey: payer.publicKey,
616
616
  recentBlockhash: blockhash,
617
- instructions
617
+ instructions: instructions2
618
618
  }).compileToV0Message(lookupTableAccounts);
619
619
  const tx = new web3_js_1.VersionedTransaction(message);
620
620
  tx.sign([payer]);
@@ -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,7 +1283,7 @@ 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
@@ -1296,7 +1296,7 @@ var require_cpiClient = __commonJS({
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
  ],
@@ -1461,35 +1461,44 @@ __export(index_exports, {
1461
1461
  WithdrawalQueueService: () => WithdrawalQueueService,
1462
1462
  addCashflowUpdate: () => addCashflowUpdate,
1463
1463
  address: () => import_kit10.address,
1464
+ confirmYieldPayment: () => confirmYieldPayment,
1464
1465
  createAccount: () => createAccount,
1465
1466
  createLiveConsensusOracleDeps: () => createLiveConsensusOracleDeps,
1466
1467
  createRpcFromConnection: () => createRpcFromConnection,
1467
1468
  createTokenMint: () => createTokenMint,
1468
1469
  createTokenMintIxs: () => createTokenMintIxs,
1469
1470
  createVaultClient: () => createVaultClient,
1471
+ createYieldPayment: () => createYieldPayment,
1470
1472
  dateToStr: () => dateToStr,
1471
1473
  defaultKeypairPath: () => defaultKeypairPath,
1472
1474
  deleteAccount: () => deleteAccount,
1475
+ findSquadsWalletRoute: () => findSquadsWalletRoute,
1473
1476
  fromUiAmount: () => fromUiAmount,
1474
1477
  getAccounts: () => getAccounts,
1475
1478
  getBalance: () => getBalance,
1476
1479
  getCashflows: () => getCashflows,
1477
1480
  getRpcUrl: () => getRpcUrl,
1481
+ getTotalOutstandingYield: () => getTotalOutstandingYield,
1478
1482
  getTotalYield: () => getTotalYield,
1479
1483
  getVaultProgramId: () => getVaultProgramId,
1480
1484
  getYield: () => getYield,
1485
+ getYieldPayments: () => getYieldPayments,
1481
1486
  isVaultEnv: () => isVaultEnv,
1482
1487
  keypairAddress: () => keypairAddress,
1483
1488
  loadKeypair: () => loadKeypair,
1484
1489
  makeProvider: () => makeProvider,
1485
1490
  mintTokensTo: () => mintTokensTo,
1491
+ prepareVaultTransaction: () => prepareVaultTransaction,
1486
1492
  resolveKeypairPath: () => resolveKeypairPath,
1493
+ resolveSquadsWalletRoute: () => resolveSquadsWalletRoute,
1487
1494
  roundToNextUtcMidnight: () => roundToNextUtcMidnight,
1488
1495
  runLiveConsensusOracle: () => runLiveConsensusOracle,
1489
1496
  systemClock: () => systemClock,
1490
1497
  toUiAmount: () => toUiAmount,
1491
1498
  updateAccount: () => updateAccount,
1492
- updateDynamicApr: () => updateDynamicApr
1499
+ updateDynamicApr: () => updateDynamicApr,
1500
+ validateSquadsWalletRoutes: () => validateSquadsWalletRoutes,
1501
+ vaultAuthorityForWallet: () => vaultAuthorityForWallet
1493
1502
  });
1494
1503
  module.exports = __toCommonJS(index_exports);
1495
1504
 
@@ -11025,219 +11034,239 @@ var IDL = {
11025
11034
  ],
11026
11035
  "errors": [
11027
11036
  {
11028
- "code": 6e3,
11029
- "name": "MintSupplyNonZero",
11030
- "msg": "Supplied share mint already has non-zero supply"
11037
+ "code": 14001,
11038
+ "name": "Unauthorized",
11039
+ "msg": "You are not authorized to perform this action."
11031
11040
  },
11032
11041
  {
11033
- "code": 6001,
11034
- "name": "InvalidAssetMint",
11035
- "msg": "Supplied mint is not accepted by this vault"
11042
+ "code": 14002,
11043
+ "name": "InvalidBankMint",
11044
+ "msg": "Invalid mint"
11036
11045
  },
11037
11046
  {
11038
- "code": 6002,
11039
- "name": "ZeroDepositAmount",
11040
- "msg": "Deposit amount must be greater than zero"
11047
+ "code": 14003,
11048
+ "name": "AccountingIssue",
11049
+ "msg": "Accounting issue"
11041
11050
  },
11042
11051
  {
11043
- "code": 6003,
11044
- "name": "ExceedsTvlLimit",
11045
- "msg": "Deposit would exceed the vault's TVL limit"
11052
+ "code": 14004,
11053
+ "name": "VaultAccountingIssue",
11054
+ "msg": "Vault accounting issue"
11046
11055
  },
11047
11056
  {
11048
- "code": 6004,
11049
- "name": "ZeroBurnAmount",
11050
- "msg": "Burn amount must be greater than zero"
11057
+ "code": 14005,
11058
+ "name": "BankAccountingIssue",
11059
+ "msg": "Bank accounting issue"
11051
11060
  },
11052
11061
  {
11053
- "code": 6005,
11054
- "name": "ZeroAssetAmount",
11055
- "msg": "Asset amount must be greater than zero"
11062
+ "code": 14006,
11063
+ "name": "OnchainAccountingIssue",
11064
+ "msg": "Onchain accounting issue"
11056
11065
  },
11057
11066
  {
11058
- "code": 6006,
11059
- "name": "InsufficientVaultLiquidity",
11060
- "msg": "Insufficient vault liquidity to satisfy withdrawal"
11067
+ "code": 14007,
11068
+ "name": "ExternalAccountingIssue",
11069
+ "msg": "External accounting issue"
11061
11070
  },
11062
11071
  {
11063
- "code": 6007,
11064
- "name": "MintAuthorityNotCurator",
11065
- "msg": "Mint authority is not the curator"
11072
+ "code": 14008,
11073
+ "name": "MintSlippage",
11074
+ "msg": "Minting failed due to slippage."
11066
11075
  },
11067
11076
  {
11068
- "code": 6008,
11069
- "name": "ZeroTotalSupply",
11070
- "msg": "Vault total supply is zero"
11077
+ "code": 14009,
11078
+ "name": "BurningSlippage",
11079
+ "msg": "Burning failed due to slippage."
11071
11080
  },
11072
11081
  {
11073
- "code": 6009,
11082
+ "code": 14010,
11083
+ "name": "TeamAccountAlreadyExists",
11084
+ "msg": "Team account already exists"
11085
+ },
11086
+ {
11087
+ "code": 14011,
11088
+ "name": "OracleAccountAlreadyExists",
11089
+ "msg": "Oracle account already exists"
11090
+ },
11091
+ {
11092
+ "code": 14012,
11074
11093
  "name": "StaleOracle",
11075
- "msg": "Vault oracle is stale"
11094
+ "msg": "Stale oracle"
11076
11095
  },
11077
11096
  {
11078
- "code": 6010,
11079
- "name": "InvalidOracleUpdate",
11080
- "msg": "Invalid oracle update"
11097
+ "code": 14013,
11098
+ "name": "LocalSignificantPriceChange",
11099
+ "msg": "Price change is too large locally"
11081
11100
  },
11082
11101
  {
11083
- "code": 6011,
11084
- "name": "InvalidInitialMintSharePrice",
11085
- "msg": "Initial mint share price must be greater than zero"
11102
+ "code": 14014,
11103
+ "name": "SignificantPriceChange",
11104
+ "msg": "Price change is too large"
11086
11105
  },
11087
11106
  {
11088
- "code": 6012,
11089
- "name": "MaxApyExceeded",
11090
- "msg": "Oracle NAV update exceeds the vault's maximum acceptable APY"
11107
+ "code": 14015,
11108
+ "name": "RoundingImpact",
11109
+ "msg": "Rounding impacts the protocol"
11091
11110
  },
11092
11111
  {
11093
- "code": 6013,
11094
- "name": "InvalidApyConfig",
11095
- "msg": "Invalid APY configuration"
11112
+ "code": 14016,
11113
+ "name": "BankIsHalted",
11114
+ "msg": "Bank is halted"
11096
11115
  },
11097
11116
  {
11098
- "code": 6014,
11099
- "name": "InvalidFeeConfig",
11100
- "msg": "Invalid fee configuration"
11117
+ "code": 14017,
11118
+ "name": "VaultIsHalted",
11119
+ "msg": "Vault is halted"
11101
11120
  },
11102
11121
  {
11103
- "code": 6015,
11104
- "name": "VaultHasLiveAssets",
11105
- "msg": "Vault has live supply, TVL, or holdings"
11122
+ "code": 14018,
11123
+ "name": "ConversionOverflow",
11124
+ "msg": "Conversion Overflow"
11106
11125
  },
11107
11126
  {
11108
- "code": 6016,
11109
- "name": "DepositMintsZeroShares",
11110
- "msg": "Deposit would mint zero shares"
11127
+ "code": 14019,
11128
+ "name": "_Reserved8019",
11129
+ "msg": "Reserved"
11111
11130
  },
11112
11131
  {
11113
- "code": 6017,
11114
- "name": "InsufficientAccruedApyBalance",
11115
- "msg": "Insufficient accrued APY balance"
11132
+ "code": 14020,
11133
+ "name": "InvalidArgument",
11134
+ "msg": "Invalid argument"
11116
11135
  },
11117
11136
  {
11118
- "code": 6018,
11119
- "name": "InvalidRole",
11120
- "msg": "Invalid role configuration"
11137
+ "code": 14021,
11138
+ "name": "UserSanityCheck",
11139
+ "msg": "User Sanity Check"
11121
11140
  },
11122
11141
  {
11123
- "code": 6019,
11124
- "name": "InvalidProtocolInteraction",
11125
- "msg": "Invalid protocol interaction CPI"
11142
+ "code": 14022,
11143
+ "name": "MathOverflow",
11144
+ "msg": "Math overflow"
11126
11145
  },
11127
11146
  {
11128
- "code": 6020,
11129
- "name": "_Reserved7020",
11130
- "msg": "Reserved"
11147
+ "code": 14023,
11148
+ "name": "InvalidMarginFiAccount",
11149
+ "msg": "Invalid MarginFi account - must be correct PDA for this vault"
11131
11150
  },
11132
11151
  {
11133
- "code": 6021,
11134
- "name": "InvalidExternalLiquidity",
11135
- "msg": "Invalid external liquidity configuration"
11152
+ "code": 14024,
11153
+ "name": "InvalidStartMarker",
11154
+ "msg": "Invalid start marker"
11136
11155
  },
11137
11156
  {
11138
- "code": 6022,
11139
- "name": "SwapBalanceUnchanged",
11140
- "msg": "Swap did not change both source and destination balances"
11157
+ "code": 14025,
11158
+ "name": "OracleUpdateOnEmptyReserve",
11159
+ "msg": "Unable to push oracle update on an empty vault reserve"
11141
11160
  },
11142
11161
  {
11143
- "code": 6023,
11144
- "name": "ProtocolBalanceUnchanged",
11145
- "msg": "Protocol interaction did not change the affected token balance"
11162
+ "code": 14026,
11163
+ "name": "InvalidRemainingAccountsLength",
11164
+ "msg": "Invalid remaining accounts length"
11146
11165
  },
11147
11166
  {
11148
- "code": 6024,
11149
- "name": "ExcessiveSwapSlippage",
11150
- "msg": "Swap TVL loss exceeds the allowed slippage"
11167
+ "code": 14027,
11168
+ "name": "WithdrawalExceedsBalance",
11169
+ "msg": "Specified withdrawal exceeds available balance"
11151
11170
  },
11152
11171
  {
11153
- "code": 6025,
11154
- "name": "TranchingNotEnabled",
11155
- "msg": "Vault tranching is not enabled"
11172
+ "code": 14028,
11173
+ "name": "InsufficientPendingYield",
11174
+ "msg": "Insufficient pending yield"
11156
11175
  },
11157
11176
  {
11158
- "code": 6026,
11159
- "name": "TranchingAlreadyEnabled",
11160
- "msg": "Vault tranching is already enabled"
11177
+ "code": 14029,
11178
+ "name": "NotSupported",
11179
+ "msg": "Not supported"
11161
11180
  },
11162
11181
  {
11163
- "code": 6027,
11164
- "name": "TrancheStateRequired",
11165
- "msg": "Tranche state account is required"
11182
+ "code": 14030,
11183
+ "name": "ExceedsMaxYieldingTvl",
11184
+ "msg": "Exceeds maximum yielding TVL"
11166
11185
  },
11167
11186
  {
11168
- "code": 6028,
11169
- "name": "InvalidTrancheConfig",
11170
- "msg": "Invalid tranche configuration"
11187
+ "code": 14031,
11188
+ "name": "TranchingNotEnabled",
11189
+ "msg": "Tranching is not enabled for this bank"
11171
11190
  },
11172
11191
  {
11173
- "code": 6029,
11174
- "name": "InvalidTrancheMint",
11175
- "msg": "Invalid tranche mint"
11192
+ "code": 14032,
11193
+ "name": "InvalidLeverageFactor",
11194
+ "msg": "Invalid leverage factor - must be at least 10000 (1x)"
11176
11195
  },
11177
11196
  {
11178
- "code": 6030,
11179
- "name": "LossesDisabled",
11180
- "msg": "Vault losses are not enabled"
11197
+ "code": 14033,
11198
+ "name": "InsufficientStakedAmount",
11199
+ "msg": "Insufficient staked amount"
11181
11200
  },
11182
11201
  {
11183
- "code": 6031,
11202
+ "code": 14034,
11203
+ "name": "JuniorTrancheEmpty",
11204
+ "msg": "Junior tranche has no value"
11205
+ },
11206
+ {
11207
+ "code": 14035,
11208
+ "name": "InvalidTrancheConfig",
11209
+ "msg": "Invalid tranche config parameter"
11210
+ },
11211
+ {
11212
+ "code": 14036,
11184
11213
  "name": "WithdrawalQueueNotExpired",
11185
- "msg": "Withdrawal queue is not yet expired"
11214
+ "msg": "Withdrawal queue lockup period has not expired"
11186
11215
  },
11187
11216
  {
11188
- "code": 6032,
11217
+ "code": 14037,
11189
11218
  "name": "InvalidWithdrawalQueue",
11190
- "msg": "Invalid withdrawal queue"
11219
+ "msg": "Withdrawal queue entry is not in a valid state"
11191
11220
  },
11192
11221
  {
11193
- "code": 6033,
11194
- "name": "AssetPriceNotSet",
11195
- "msg": "Destination asset has no price set; a consensus oracle price is required before swapping"
11222
+ "code": 14038,
11223
+ "name": "InvalidAccount",
11224
+ "msg": "Account does not belong to the expected parent"
11196
11225
  },
11197
11226
  {
11198
- "code": 6034,
11199
- "name": "AssetHoldingNotEmpty",
11200
- "msg": "Asset holding still has a balance and cannot be removed"
11227
+ "code": 14039,
11228
+ "name": "MissingAccount",
11229
+ "msg": "Required optional account is missing"
11201
11230
  },
11202
11231
  {
11203
- "code": 6035,
11204
- "name": "CannotRemoveBaseHolding",
11205
- "msg": "The base asset holding cannot be removed"
11232
+ "code": 14040,
11233
+ "name": "TrancheWipedOut",
11234
+ "msg": "Junior tranche is wiped out and cannot accept new stakes"
11206
11235
  },
11207
11236
  {
11208
- "code": 6036,
11209
- "name": "UnauthorizedPriceUpdater",
11210
- "msg": "Caller is not authorized to trigger an asset price update"
11237
+ "code": 14041,
11238
+ "name": "VaultLossNotAccepted",
11239
+ "msg": "Vault does not accept losses \u2014 enable losses_accepted before retrying"
11211
11240
  },
11212
11241
  {
11213
- "code": 6037,
11214
- "name": "InvalidStalenessConfig",
11215
- "msg": "Invalid asset-price staleness threshold"
11242
+ "code": 14042,
11243
+ "name": "CapitalLossExceedsReserve",
11244
+ "msg": "Capital loss exceeds available yielding reserve"
11216
11245
  },
11217
11246
  {
11218
- "code": 6038,
11219
- "name": "AssetRebalanceRateLimitExceeded",
11220
- "msg": "Asset was rebalanced too recently"
11247
+ "code": 14043,
11248
+ "name": "RollingWithdrawalLimitExceeded",
11249
+ "msg": "Rolling withdrawal limit exceeded"
11221
11250
  },
11222
11251
  {
11223
- "code": 6039,
11224
- "name": "InvalidShareTokenProgram",
11225
- "msg": "Share token program does not match the vault/tranche mint configuration"
11252
+ "code": 14044,
11253
+ "name": "VaultAlreadyMigrated",
11254
+ "msg": "Legacy vault has already been migrated"
11226
11255
  },
11227
11256
  {
11228
- "code": 6040,
11229
- "name": "UnauthorizedVaultCreator",
11230
- "msg": "Caller is not on the vault-creator whitelist"
11257
+ "code": 14045,
11258
+ "name": "InvalidMigrationState",
11259
+ "msg": "Legacy vault migration is incomplete or invalid"
11231
11260
  },
11232
11261
  {
11233
- "code": 6041,
11234
- "name": "InvalidShareMintDecimals",
11235
- "msg": "Share mint decimals must match the deposit asset mint decimals"
11262
+ "code": 14046,
11263
+ "name": "InvalidMigrationMintAuthority",
11264
+ "msg": "Mint authority does not match the expected migration source"
11236
11265
  },
11237
11266
  {
11238
- "code": 6042,
11239
- "name": "InvalidFeeExemption",
11240
- "msg": "Invalid fee-exemption PDA signer or seeds"
11267
+ "code": 14047,
11268
+ "name": "BankMigrationIncomplete",
11269
+ "msg": "Legacy bank or tranche migration is incomplete \u2014 source accounting and escrow must be fully drained before mint authority transfer"
11241
11270
  }
11242
11271
  ],
11243
11272
  "types": [
@@ -13622,6 +13651,13 @@ var IDL = {
13622
13651
  "name": "target_lockup_duration_secs",
13623
13652
  "type": "i64"
13624
13653
  },
13654
+ {
13655
+ "name": "junior_deposit_cap",
13656
+ "docs": [
13657
+ "Maximum junior tranche value in accounting units. Zero means uncapped."
13658
+ ],
13659
+ "type": "u64"
13660
+ },
13625
13661
  {
13626
13662
  "name": "for_migration",
13627
13663
  "docs": [
@@ -14419,12 +14455,21 @@ var IDL = {
14419
14455
  "name": "target_lockup_duration_secs",
14420
14456
  "type": "i64"
14421
14457
  },
14458
+ {
14459
+ "name": "junior_deposit_cap",
14460
+ "docs": [
14461
+ "Maximum junior tranche value in vault accounting units. Zero disables",
14462
+ "the cap. Yield may carry the tranche above this value, but further",
14463
+ "junior deposits remain blocked until its value falls below the cap."
14464
+ ],
14465
+ "type": "u64"
14466
+ },
14422
14467
  {
14423
14468
  "name": "_padding2",
14424
14469
  "type": {
14425
14470
  "array": [
14426
14471
  "u64",
14427
- 14
14472
+ 13
14428
14473
  ]
14429
14474
  }
14430
14475
  }
@@ -14542,6 +14587,15 @@ var IDL = {
14542
14587
  "type": {
14543
14588
  "option": "i64"
14544
14589
  }
14590
+ },
14591
+ {
14592
+ "name": "junior_deposit_cap",
14593
+ "docs": [
14594
+ "Maximum junior tranche value in accounting units. Zero means uncapped."
14595
+ ],
14596
+ "type": {
14597
+ "option": "u64"
14598
+ }
14545
14599
  }
14546
14600
  ]
14547
14601
  }
@@ -15931,6 +15985,7 @@ var CreateTrancheStateBuilder = class extends VaultBuilderBase {
15931
15985
  earlyUnstakeFeeBps: args.earlyUnstakeFeeBps,
15932
15986
  standardUnstakeFeeBps: args.standardUnstakeFeeBps,
15933
15987
  targetLockupDurationSecs: args.targetLockupDurationSecs,
15988
+ juniorDepositCap: args.juniorDepositCap,
15934
15989
  forMigration: args.forMigration
15935
15990
  }).accountsPartial({
15936
15991
  curator: (0, import_common8.toWeb3Pk)(args.curator),
@@ -15975,6 +16030,7 @@ var CreateTrancheStateBuilder = class extends VaultBuilderBase {
15975
16030
  targetLockupDurationSecs: new import_core.BN(
15976
16031
  (txArgs.targetLockupDurationSecs ?? DEFAULT_JUNIOR_WITHDRAWAL_LOCKUP_SECS).toString()
15977
16032
  ),
16033
+ juniorDepositCap: new import_core.BN((txArgs.juniorDepositCap ?? 0n).toString()),
15978
16034
  forMigration,
15979
16035
  tokenProgram: txArgs.tokenProgram ?? TOKEN_PROGRAM_ID
15980
16036
  };
@@ -17608,7 +17664,8 @@ var UpdateTrancheConfigBuilder = class extends VaultBuilderBase {
17608
17664
  seniorFixedApyBps: args.seniorFixedApyBps,
17609
17665
  earlyUnstakeFeeBps: args.earlyUnstakeFeeBps,
17610
17666
  standardUnstakeFeeBps: args.standardUnstakeFeeBps,
17611
- targetLockupDurationSecs: args.targetLockupDurationSecs
17667
+ targetLockupDurationSecs: args.targetLockupDurationSecs,
17668
+ juniorDepositCap: args.juniorDepositCap
17612
17669
  }).accountsPartial({
17613
17670
  curator: (0, import_common29.toWeb3Pk)(args.curator),
17614
17671
  vault: (0, import_common29.toWeb3Pk)(args.vault),
@@ -17629,7 +17686,8 @@ var UpdateTrancheConfigBuilder = class extends VaultBuilderBase {
17629
17686
  seniorFixedApyBps: txArgs.seniorFixedApyBps ?? null,
17630
17687
  earlyUnstakeFeeBps: txArgs.earlyUnstakeFeeBps ?? null,
17631
17688
  standardUnstakeFeeBps: txArgs.standardUnstakeFeeBps ?? null,
17632
- targetLockupDurationSecs: txArgs.targetLockupDurationSecs === void 0 ? null : new import_core11.BN(txArgs.targetLockupDurationSecs.toString())
17689
+ targetLockupDurationSecs: txArgs.targetLockupDurationSecs === void 0 ? null : new import_core11.BN(txArgs.targetLockupDurationSecs.toString()),
17690
+ juniorDepositCap: txArgs.juniorDepositCap === void 0 ? null : new import_core11.BN(txArgs.juniorDepositCap.toString())
17633
17691
  };
17634
17692
  }
17635
17693
  async buildPlanExtras(args) {
@@ -18120,7 +18178,7 @@ var VaultReallocationBuilder = class extends VaultBuilderBase {
18120
18178
  }
18121
18179
  async buildPreambleInstructions(args) {
18122
18180
  const payer = (0, import_common34.toWeb3Pk)(args.manager);
18123
- const instructions = [
18181
+ const instructions2 = [
18124
18182
  (0, import_spl_token17.createAssociatedTokenAccountIdempotentInstruction)(
18125
18183
  payer,
18126
18184
  (0, import_common34.toWeb3Pk)(args.allocationMintAta),
@@ -18155,7 +18213,7 @@ var VaultReallocationBuilder = class extends VaultBuilderBase {
18155
18213
  )
18156
18214
  ];
18157
18215
  if (args.sourceVault && args.sourceShareMint && args.sourceVaultMintAta && args.allocationSourceShareAta) {
18158
- instructions.push(
18216
+ instructions2.push(
18159
18217
  (0, import_spl_token17.createAssociatedTokenAccountIdempotentInstruction)(
18160
18218
  payer,
18161
18219
  (0, import_common34.toWeb3Pk)(args.sourceVaultMintAta),
@@ -18174,7 +18232,7 @@ var VaultReallocationBuilder = class extends VaultBuilderBase {
18174
18232
  )
18175
18233
  );
18176
18234
  }
18177
- return instructions.map(import_common34.toKitInstruction);
18235
+ return instructions2.map(import_common34.toKitInstruction);
18178
18236
  }
18179
18237
  async buildPlanExtras(args) {
18180
18238
  return {
@@ -18409,15 +18467,129 @@ function makeProvider(connection, payer) {
18409
18467
  });
18410
18468
  }
18411
18469
 
18470
+ // src/utils/squads.ts
18471
+ var squads = __toESM(require("@sqds/multisig"));
18472
+ var import_web321 = require("@solana/web3.js");
18473
+ function validateVaultIndex(vaultIndex) {
18474
+ if (!Number.isSafeInteger(vaultIndex) || vaultIndex < 0) {
18475
+ throw new Error("Squads vaultIndex must be a non-negative safe integer");
18476
+ }
18477
+ }
18478
+ function resolveSquadsWalletRoute(route) {
18479
+ validateVaultIndex(route.vaultIndex);
18480
+ const wallet = new import_web321.PublicKey(route.wallet);
18481
+ const multisigPda = new import_web321.PublicKey(route.multisigPda);
18482
+ const [vaultPda] = squads.getVaultPda({
18483
+ multisigPda,
18484
+ index: route.vaultIndex
18485
+ });
18486
+ return { ...route, wallet, multisigPda, vaultPda };
18487
+ }
18488
+ function findSquadsWalletRoute(wallet, routes) {
18489
+ const walletKey = typeof wallet === "string" ? new import_web321.PublicKey(wallet) : wallet;
18490
+ const route = routes.find(
18491
+ (candidate) => candidate.wallet === walletKey.toBase58()
18492
+ );
18493
+ return route ? resolveSquadsWalletRoute(route) : void 0;
18494
+ }
18495
+ function validateSquadsWalletRoutes(routes) {
18496
+ const wallets = /* @__PURE__ */ new Set();
18497
+ for (const route of routes) {
18498
+ const resolved = resolveSquadsWalletRoute(route);
18499
+ const wallet = resolved.wallet.toBase58();
18500
+ if (wallets.has(wallet)) {
18501
+ throw new Error(`Duplicate Squads route for wallet ${wallet}`);
18502
+ }
18503
+ wallets.add(wallet);
18504
+ }
18505
+ }
18506
+ function vaultAuthorityForWallet(wallet, routes) {
18507
+ const walletKey = typeof wallet === "string" ? new import_web321.PublicKey(wallet) : wallet;
18508
+ return findSquadsWalletRoute(walletKey, routes)?.vaultPda ?? walletKey;
18509
+ }
18510
+ async function prepareVaultTransaction(args) {
18511
+ const { connection, proposer, instructions: instructions2 } = args;
18512
+ const route = findSquadsWalletRoute(proposer, args.squadsRoutes ?? []);
18513
+ if (!route) {
18514
+ return {
18515
+ kind: "direct",
18516
+ transaction: new import_web321.Transaction().add(...instructions2),
18517
+ authority: proposer
18518
+ };
18519
+ }
18520
+ const multisig = await squads.accounts.Multisig.fromAccountAddress(
18521
+ connection,
18522
+ route.multisigPda
18523
+ );
18524
+ const member = multisig.members.find(
18525
+ (candidate) => candidate.key.equals(proposer)
18526
+ );
18527
+ if (!member) {
18528
+ throw new Error(
18529
+ `Wallet ${proposer.toBase58()} is not a member of Squads multisig ${route.multisigPda.toBase58()}`
18530
+ );
18531
+ }
18532
+ if (!squads.types.Permissions.has(
18533
+ member.permissions,
18534
+ squads.types.Permission.Initiate
18535
+ )) {
18536
+ throw new Error(
18537
+ `Wallet ${proposer.toBase58()} cannot initiate proposals for Squads multisig ${route.multisigPda.toBase58()}`
18538
+ );
18539
+ }
18540
+ const transactionIndex = BigInt(multisig.transactionIndex.toString()) + 1n;
18541
+ const { blockhash } = await connection.getLatestBlockhash("confirmed");
18542
+ const transactionMessage = new import_web321.TransactionMessage({
18543
+ payerKey: route.vaultPda,
18544
+ recentBlockhash: blockhash,
18545
+ instructions: [...instructions2]
18546
+ });
18547
+ const createVaultTransactionIx = squads.instructions.vaultTransactionCreate({
18548
+ multisigPda: route.multisigPda,
18549
+ transactionIndex,
18550
+ creator: proposer,
18551
+ vaultIndex: route.vaultIndex,
18552
+ ephemeralSigners: 0,
18553
+ transactionMessage,
18554
+ memo: route.memo
18555
+ });
18556
+ const createProposalIx = squads.instructions.proposalCreate({
18557
+ multisigPda: route.multisigPda,
18558
+ transactionIndex,
18559
+ creator: proposer
18560
+ });
18561
+ const [proposalPda] = squads.getProposalPda({
18562
+ multisigPda: route.multisigPda,
18563
+ transactionIndex
18564
+ });
18565
+ const [vaultTransactionPda] = squads.getTransactionPda({
18566
+ multisigPda: route.multisigPda,
18567
+ index: transactionIndex
18568
+ });
18569
+ return {
18570
+ kind: "squads",
18571
+ transaction: new import_web321.Transaction().add(
18572
+ createVaultTransactionIx,
18573
+ createProposalIx
18574
+ ),
18575
+ authority: route.vaultPda,
18576
+ multisigPda: route.multisigPda,
18577
+ vaultIndex: route.vaultIndex,
18578
+ transactionIndex,
18579
+ proposalPda,
18580
+ vaultTransactionPda
18581
+ };
18582
+ }
18583
+
18412
18584
  // src/utils/token.ts
18413
18585
  var import_spl_token18 = require("@solana/spl-token");
18414
- var import_web321 = require("@solana/web3.js");
18586
+ var import_web322 = require("@solana/web3.js");
18415
18587
  var import_common37 = __toESM(require_dist());
18416
18588
  async function createTokenMintIxs(connection, payer, authority, decimals, tokenProgram = import_spl_token18.TOKEN_2022_PROGRAM_ID) {
18417
- const mint = import_web321.Keypair.generate();
18589
+ const mint = import_web322.Keypair.generate();
18418
18590
  const lamports = await (0, import_spl_token18.getMinimumBalanceForRentExemptMint)(connection);
18419
18591
  const ixs = [
18420
- import_web321.SystemProgram.createAccount({
18592
+ import_web322.SystemProgram.createAccount({
18421
18593
  fromPubkey: payer,
18422
18594
  newAccountPubkey: mint.publicKey,
18423
18595
  space: import_spl_token18.MINT_SIZE,
@@ -18443,7 +18615,7 @@ async function createTokenMint(connection, payer, decimals, tokenProgram = impor
18443
18615
  tokenProgram
18444
18616
  );
18445
18617
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
18446
- const tx = new import_web321.Transaction().add(...ixs);
18618
+ const tx = new import_web322.Transaction().add(...ixs);
18447
18619
  tx.feePayer = payer.publicKey;
18448
18620
  tx.recentBlockhash = blockhash;
18449
18621
  tx.sign(payer, mint);
@@ -18482,7 +18654,7 @@ async function mintTokensTo(connection, payer, mint, destination, amount, tokenP
18482
18654
  tokenProgramPk
18483
18655
  )
18484
18656
  ];
18485
- const tx = new import_web321.Transaction().add(...ixs);
18657
+ const tx = new import_web322.Transaction().add(...ixs);
18486
18658
  await connection.sendTransaction(tx, [payer]);
18487
18659
  }
18488
18660
 
@@ -18677,6 +18849,40 @@ async function getBalance(accountName, atTime) {
18677
18849
  "GET"
18678
18850
  )).data;
18679
18851
  }
18852
+ async function createYieldPayment(params) {
18853
+ return unwrapData(
18854
+ await yieldApiReq(
18855
+ accountEndpoint(params.accountName, "yield-payments"),
18856
+ "POST",
18857
+ {
18858
+ amount: params.amount,
18859
+ effective_at: dateToStr(params.effectiveAt),
18860
+ idempotency_key: params.idempotencyKey,
18861
+ password: params.password
18862
+ }
18863
+ )
18864
+ );
18865
+ }
18866
+ async function confirmYieldPayment(params) {
18867
+ return unwrapData(
18868
+ await yieldApiReq(
18869
+ accountEndpoint(
18870
+ params.accountName,
18871
+ `yield-payments/${encodeURIComponent(params.paymentId)}/confirm`
18872
+ ),
18873
+ "POST",
18874
+ {
18875
+ transaction_signature: params.transactionSignature,
18876
+ password: params.password
18877
+ }
18878
+ )
18879
+ );
18880
+ }
18881
+ async function getYieldPayments(accountName) {
18882
+ return unwrapData(
18883
+ await yieldApiReq(accountEndpoint(accountName, "yield-payments"), "GET")
18884
+ );
18885
+ }
18680
18886
  async function getYield(accountName, start, end) {
18681
18887
  return (await yieldApiReq(
18682
18888
  accountEndpoint(accountName, "yield") + (start ? `?start=${dateToStr(start)}` : "") + (start && end ? `&end=${dateToStr(end)}` : end ? `?end=${dateToStr(end)}` : ""),
@@ -18692,6 +18898,14 @@ async function getTotalYield(accountNames, start, end) {
18692
18898
  }
18693
18899
  return totalYield;
18694
18900
  }
18901
+ async function getTotalOutstandingYield(accountNames, start, end) {
18902
+ let total = 0;
18903
+ for (const accountName of accountNames) {
18904
+ const response = await getYield(accountName, start, end);
18905
+ total += response.outstanding_yield;
18906
+ }
18907
+ return total;
18908
+ }
18695
18909
 
18696
18910
  // src/services/withdrawalQueueService.ts
18697
18911
  var import_common38 = __toESM(require_dist());
@@ -18713,8 +18927,8 @@ var WithdrawalQueueService = class {
18713
18927
  /** All withdrawal-queue accounts owned by the vault program. */
18714
18928
  async fetchAllQueues() {
18715
18929
  const program = this.client.program.account;
18716
- const accounts = await program.vaultWithdrawalQueue.all();
18717
- return accounts.map(
18930
+ const accounts2 = await program.vaultWithdrawalQueue.all();
18931
+ return accounts2.map(
18718
18932
  (entry) => this.toSnapshot((0, import_common38.fromWeb3Pk)(entry.publicKey), entry.account)
18719
18933
  );
18720
18934
  }
@@ -19074,7 +19288,7 @@ var JupiterPriceSource = class {
19074
19288
  };
19075
19289
 
19076
19290
  // src/services/consensusOracle/jupiterBalanceSource.ts
19077
- var import_web322 = require("@solana/web3.js");
19291
+ var import_web323 = require("@solana/web3.js");
19078
19292
  var import_spl_token19 = require("@solana/spl-token");
19079
19293
  var import_common40 = __toESM(require_dist());
19080
19294
  var DEFAULT_BASE_URL2 = "https://lite-api.jup.ag/ultra/v1/balances";
@@ -19131,7 +19345,7 @@ var JupiterBalanceSource = class {
19131
19345
  for (const programId of [import_spl_token19.TOKEN_PROGRAM_ID, import_spl_token19.TOKEN_2022_PROGRAM_ID]) {
19132
19346
  const { value } = await this.connection.getParsedTokenAccountsByOwner(
19133
19347
  ownerPk,
19134
- { programId: new import_web322.PublicKey(programId) }
19348
+ { programId: new import_web323.PublicKey(programId) }
19135
19349
  );
19136
19350
  for (const { account } of value) {
19137
19351
  const info = account.data.parsed?.info;
@@ -19182,7 +19396,7 @@ var StaticPositionProvider = class {
19182
19396
 
19183
19397
  // src/services/consensusOracle/kaminoPositionProvider.ts
19184
19398
  var import_kit12 = require("@solana/kit");
19185
- var import_web323 = require("@solana/web3.js");
19399
+ var import_web324 = require("@solana/web3.js");
19186
19400
  var import_klend_sdk = require("@kamino-finance/klend-sdk");
19187
19401
  async function readKaminoBalance(manager, vault, sharesHolder) {
19188
19402
  const userShares = await manager.getUserSharesBalanceSingleVault(
@@ -19219,7 +19433,7 @@ var KaminoPositionProvider = class {
19219
19433
  const amount = await readKaminoBalance(
19220
19434
  manager,
19221
19435
  kVault,
19222
- new import_web323.PublicKey(sharesHolder)
19436
+ new import_web324.PublicKey(sharesHolder)
19223
19437
  );
19224
19438
  out.push({ mint: ref.mint, amount });
19225
19439
  }
@@ -19228,7 +19442,7 @@ var KaminoPositionProvider = class {
19228
19442
  };
19229
19443
 
19230
19444
  // src/services/consensusOracle/marginfiPositionProvider.ts
19231
- var import_web324 = require("@solana/web3.js");
19445
+ var import_web325 = require("@solana/web3.js");
19232
19446
  var import_marginfi_client_v2 = require("@mrgnlabs/marginfi-client-v2");
19233
19447
  function parseBankPksFromMarginfiAccount(data) {
19234
19448
  const DISCRIMINATOR = 8;
@@ -19241,7 +19455,7 @@ function parseBankPksFromMarginfiAccount(data) {
19241
19455
  if (base + BALANCE_SIZE > data.length) break;
19242
19456
  const active = data[base];
19243
19457
  if (!active) continue;
19244
- out.push(new import_web324.PublicKey(data.subarray(base + 1, base + 33)));
19458
+ out.push(new import_web325.PublicKey(data.subarray(base + 1, base + 33)));
19245
19459
  }
19246
19460
  return out;
19247
19461
  }
@@ -19279,8 +19493,8 @@ var MarginfiPositionProvider = class {
19279
19493
  async positionsFor(ctx) {
19280
19494
  const refs = ctx.refs.filter((r) => r.kind === "marginfi");
19281
19495
  if (refs.length === 0) return [];
19282
- const explicitBanks = refs.map((r) => r.marginfiBank).filter(Boolean).map((bank) => new import_web324.PublicKey(bank));
19283
- const autoAccountPks = refs.filter((r) => !r.marginfiBank).map((r) => r.marginfiAccount).filter(Boolean).map((account) => new import_web324.PublicKey(account));
19496
+ const explicitBanks = refs.map((r) => r.marginfiBank).filter(Boolean).map((bank) => new import_web325.PublicKey(bank));
19497
+ const autoAccountPks = refs.filter((r) => !r.marginfiBank).map((r) => r.marginfiAccount).filter(Boolean).map((account) => new import_web325.PublicKey(account));
19284
19498
  const autoBanks = [];
19285
19499
  for (const accountPk of autoAccountPks) {
19286
19500
  try {
@@ -19311,14 +19525,14 @@ var MarginfiPositionProvider = class {
19311
19525
  if (bank) {
19312
19526
  const amount = await readMarginfiBalance(
19313
19527
  client,
19314
- new import_web324.PublicKey(account),
19315
- new import_web324.PublicKey(bank)
19528
+ new import_web325.PublicKey(account),
19529
+ new import_web325.PublicKey(bank)
19316
19530
  );
19317
19531
  out.push({ mint: ref.mint, amount });
19318
19532
  } else {
19319
19533
  const balances = await readAllMarginfiBalances(
19320
19534
  client,
19321
- new import_web324.PublicKey(account)
19535
+ new import_web325.PublicKey(account)
19322
19536
  );
19323
19537
  for (const { mint, amount } of balances) {
19324
19538
  out.push({ mint: mint.toBase58(), amount });
@@ -19338,7 +19552,11 @@ function createLiveConsensusOracleDeps(connection, opts = {}) {
19338
19552
  balanceSource: new JupiterBalanceSource(connection, {
19339
19553
  rpcOnly: opts.rpcOnly ?? false,
19340
19554
  log
19341
- })
19555
+ }),
19556
+ yieldTracker: {
19557
+ getTotalOutstandingYield,
19558
+ getYieldPayments
19559
+ }
19342
19560
  };
19343
19561
  if (opts.includeExternalPositions ?? true) {
19344
19562
  deps.externalPositions = new ExternalPositionRegistry(
@@ -19353,7 +19571,7 @@ function createLiveConsensusOracleDeps(connection, opts = {}) {
19353
19571
  }
19354
19572
 
19355
19573
  // src/services/consensusOracle/consensusOracleService.ts
19356
- var import_web325 = require("@solana/web3.js");
19574
+ var import_web326 = require("@solana/web3.js");
19357
19575
  var import_common41 = __toESM(require_dist());
19358
19576
  var SYSTEM_PROGRAM2 = "11111111111111111111111111111111";
19359
19577
  var CONSENSUS_ORACLE_VARIANT = "consensusoracle";
@@ -19387,7 +19605,7 @@ function parseExternalLiquidityRefs(vaultState) {
19387
19605
  if (!data || data.length < 40) continue;
19388
19606
  if (data[0] !== 1) continue;
19389
19607
  const pubkeyBytes = new Uint8Array(data.slice(8, 40));
19390
- const userAccount = new import_web325.PublicKey(pubkeyBytes).toBase58();
19608
+ const userAccount = new import_web326.PublicKey(pubkeyBytes).toBase58();
19391
19609
  refs.push({
19392
19610
  kind: "marginfi",
19393
19611
  mint: "",
@@ -19417,6 +19635,7 @@ var ConsensusOracleService = class {
19417
19635
  log(`vault ${target.vault}: no consensus holdings, skipping`);
19418
19636
  return { vault: target.vault, updates: [], dryRun };
19419
19637
  }
19638
+ await this.assertNoUnconfirmedYieldPayments(target);
19420
19639
  const inputs = await this.gatherPricingInputs(
19421
19640
  target,
19422
19641
  vaultState,
@@ -19427,7 +19646,7 @@ var ConsensusOracleService = class {
19427
19646
  log(`vault ${target.vault}: dry run, ${updates.length} holding(s)`);
19428
19647
  return { vault: target.vault, updates, dryRun: true };
19429
19648
  }
19430
- const { updateSignature, crankSignature, crankSkippedReason } = await this.settleVault(signer, target.vault, updates, vaultState, log);
19649
+ const { updateSignature, crankSignature, crankSkippedReason } = await this.settleVault(signer, target, updates, vaultState, log);
19431
19650
  return {
19432
19651
  vault: target.vault,
19433
19652
  updates,
@@ -19437,6 +19656,39 @@ var ConsensusOracleService = class {
19437
19656
  crankSkippedReason
19438
19657
  };
19439
19658
  }
19659
+ /**
19660
+ * Fail closed while any configured yield account has an unsettled payment.
19661
+ * The payout must be confirmed only after it is visible in the same wallet
19662
+ * balance source used by this service. Until then, no oracle update is safe.
19663
+ */
19664
+ async assertNoUnconfirmedYieldPayments(target) {
19665
+ const accountNames = [
19666
+ ...new Set(
19667
+ (target.holdings ?? []).flatMap(
19668
+ (holding) => holding.yieldAccountNames ?? []
19669
+ )
19670
+ )
19671
+ ];
19672
+ if (accountNames.length === 0) return;
19673
+ if (!this.deps.yieldTracker) {
19674
+ throw new Error(
19675
+ `vault ${target.vault}: yield accounts are configured but no yield tracker is available`
19676
+ );
19677
+ }
19678
+ for (const accountName of accountNames) {
19679
+ const payments = await this.deps.yieldTracker.getYieldPayments(
19680
+ accountName
19681
+ );
19682
+ const unconfirmed = payments.filter(
19683
+ (payment) => payment.status !== "confirmed"
19684
+ );
19685
+ if (unconfirmed.length > 0) {
19686
+ throw new Error(
19687
+ `vault ${target.vault}: oracle update blocked because yield account "${accountName}" has ${unconfirmed.length} unconfirmed payment(s): ` + unconfirmed.map((payment) => payment.id).join(", ")
19688
+ );
19689
+ }
19690
+ }
19691
+ }
19440
19692
  /**
19441
19693
  * Drive several vaults in sequence. Non-fatal: a failure on one vault is
19442
19694
  * recorded and the rest still run (mirrors the oracle-updater daemon).
@@ -19588,7 +19840,7 @@ var ConsensusOracleService = class {
19588
19840
  /** Accrued yield (base units) attributed to a holding via its configured accounts. */
19589
19841
  async resolveYieldAmount(cfg, decimals) {
19590
19842
  if (!this.deps.yieldTracker || !cfg?.yieldAccountNames?.length) return 0n;
19591
- const totalYieldUi = await this.deps.yieldTracker.getTotalYield(
19843
+ const totalYieldUi = await this.deps.yieldTracker.getTotalOutstandingYield(
19592
19844
  cfg.yieldAccountNames
19593
19845
  );
19594
19846
  return totalYieldUi > 0 ? (0, import_common41.fromUiAmount)(totalYieldUi, decimals) : 0n;
@@ -19634,7 +19886,8 @@ var ConsensusOracleService = class {
19634
19886
  }
19635
19887
  // ── Settlement ───────────────────────────────────────────────────────────────
19636
19888
  /** Push the consensus report for all holdings, then settle NAV. */
19637
- async settleVault(signer, vault, updates, vaultState, log) {
19889
+ async settleVault(signer, target, updates, vaultState, log) {
19890
+ const vault = target.vault;
19638
19891
  log(
19639
19892
  `vault ${vault}: submitting ${updates.length} consensus asset update(s)`
19640
19893
  );
@@ -19644,6 +19897,7 @@ var ConsensusOracleService = class {
19644
19897
  );
19645
19898
  }
19646
19899
  await this.logProspectiveApy(vault, updates, vaultState, log);
19900
+ await this.assertNoUnconfirmedYieldPayments(target);
19647
19901
  const updateSignature = await this.oracle.updateAssetConsensusPrice(
19648
19902
  signer,
19649
19903
  {
@@ -19766,7 +20020,8 @@ var MockYieldTracker = class {
19766
20020
  aprBps: cfg.aprBps,
19767
20021
  initialPrincipal: cfg.principal ?? 0,
19768
20022
  startTs: cfg.startTs ?? this.clock.now(),
19769
- cashflows: []
20023
+ cashflows: [],
20024
+ yieldPayments: []
19770
20025
  });
19771
20026
  }
19772
20027
  }
@@ -19776,7 +20031,8 @@ var MockYieldTracker = class {
19776
20031
  aprBps: cfg.aprBps,
19777
20032
  initialPrincipal: cfg.principal ?? 0,
19778
20033
  startTs: cfg.startTs ?? this.clock.now(),
19779
- cashflows: []
20034
+ cashflows: [],
20035
+ yieldPayments: []
19780
20036
  });
19781
20037
  }
19782
20038
  require(name) {
@@ -19786,6 +20042,12 @@ var MockYieldTracker = class {
19786
20042
  }
19787
20043
  return state;
19788
20044
  }
20045
+ async getYieldPayments(accountName) {
20046
+ return this.require(accountName).yieldPayments.map((payment) => ({
20047
+ id: payment.paymentId,
20048
+ status: payment.status
20049
+ }));
20050
+ }
19789
20051
  async getYield(accountName, start, end) {
19790
20052
  const state = this.require(accountName);
19791
20053
  const windowStartMs = Math.max(
@@ -19809,9 +20071,16 @@ var MockYieldTracker = class {
19809
20071
  }
19810
20072
  const tailSecs = Math.max(0, (windowEndMs - segStart) / 1e3);
19811
20073
  totalYield += principal * apr * (tailSecs / SECONDS_PER_YEAR);
20074
+ const paidYield = state.yieldPayments.reduce((sum, payment) => {
20075
+ return payment.status === "confirmed" && payment.effectiveAt > windowStartMs && payment.effectiveAt <= windowEndMs ? sum + payment.amount : sum;
20076
+ }, 0);
20077
+ const outstandingYield = Math.max(0, totalYield - paidYield);
19812
20078
  return {
19813
20079
  account: accountName,
19814
20080
  totalYield,
20081
+ grossYield: totalYield,
20082
+ paidYield,
20083
+ outstandingYield,
19815
20084
  principalAtEnd: principal,
19816
20085
  aprUsed: apr,
19817
20086
  accrualStart: new Date(windowStartMs),
@@ -19826,9 +20095,17 @@ var MockYieldTracker = class {
19826
20095
  }
19827
20096
  return total;
19828
20097
  }
20098
+ async getTotalOutstandingYield(accountNames, start, end) {
20099
+ let total = 0;
20100
+ for (const name of accountNames) {
20101
+ const snapshot = await this.getYield(name, start, end);
20102
+ total += snapshot.outstandingYield;
20103
+ }
20104
+ return total;
20105
+ }
19829
20106
  async getBalance(accountName, atTime) {
19830
20107
  const snapshot = await this.getYield(accountName, void 0, atTime);
19831
- return snapshot.principalAtEnd + snapshot.totalYield;
20108
+ return snapshot.principalAtEnd + snapshot.outstandingYield;
19832
20109
  }
19833
20110
  async addCashflow(params) {
19834
20111
  const state = this.require(params.accountName);
@@ -19838,11 +20115,65 @@ var MockYieldTracker = class {
19838
20115
  amount: signed
19839
20116
  });
19840
20117
  }
20118
+ async createYieldPayment(params) {
20119
+ const state = this.require(params.accountName);
20120
+ if (!(params.amount > 0)) throw new Error("Yield payment must be positive");
20121
+ const existing = state.yieldPayments.find(
20122
+ (payment) => payment.paymentId === params.paymentId
20123
+ );
20124
+ if (existing) {
20125
+ if (existing.amount !== params.amount || existing.effectiveAt !== params.effectiveAt.getTime()) {
20126
+ throw new Error(
20127
+ `Yield payment "${params.paymentId}" already exists with different details`
20128
+ );
20129
+ }
20130
+ return;
20131
+ }
20132
+ state.yieldPayments.push({
20133
+ paymentId: params.paymentId,
20134
+ amount: params.amount,
20135
+ effectiveAt: params.effectiveAt.getTime(),
20136
+ status: "pending"
20137
+ });
20138
+ }
20139
+ async confirmYieldPayment(params) {
20140
+ const state = this.require(params.accountName);
20141
+ const payment = state.yieldPayments.find(
20142
+ (candidate) => candidate.paymentId === params.paymentId
20143
+ );
20144
+ if (!payment)
20145
+ throw new Error(`Unknown yield payment "${params.paymentId}"`);
20146
+ if (payment.status === "confirmed") {
20147
+ if (payment.transactionSignature !== params.transactionSignature) {
20148
+ throw new Error(
20149
+ "Yield payment already confirmed with another signature"
20150
+ );
20151
+ }
20152
+ return;
20153
+ }
20154
+ const chronologicalPayments = state.yieldPayments.filter(
20155
+ (candidate) => candidate.status === "confirmed" || candidate === payment
20156
+ ).sort((a, b) => a.effectiveAt - b.effectiveAt);
20157
+ let cumulativePaid = 0;
20158
+ for (const candidate of chronologicalPayments) {
20159
+ cumulativePaid += candidate.amount;
20160
+ const snapshot = await this.getYield(
20161
+ params.accountName,
20162
+ void 0,
20163
+ new Date(candidate.effectiveAt)
20164
+ );
20165
+ if (cumulativePaid > snapshot.totalYield + 1e-9) {
20166
+ throw new Error("Confirmed payment exceeds accrued unpaid yield");
20167
+ }
20168
+ }
20169
+ payment.status = "confirmed";
20170
+ payment.transactionSignature = params.transactionSignature;
20171
+ }
19841
20172
  };
19842
20173
 
19843
20174
  // src/services/externalLiquidityIntegrityService.ts
19844
20175
  var import_kit13 = require("@solana/kit");
19845
- var import_web326 = require("@solana/web3.js");
20176
+ var import_web327 = require("@solana/web3.js");
19846
20177
  var import_common42 = __toESM(require_dist());
19847
20178
  var import_marginfi2 = __toESM(require_dist2());
19848
20179
  function parseActiveSlots(externalLiquidity) {
@@ -19855,7 +20186,7 @@ function parseActiveSlots(externalLiquidity) {
19855
20186
  if (discriminant === 0) continue;
19856
20187
  if (discriminant !== 1) continue;
19857
20188
  const pubkeyBytes = new Uint8Array(data.slice(8, 40));
19858
- const userAccount = (0, import_common42.toAddress)(new import_web326.PublicKey(pubkeyBytes));
20189
+ const userAccount = (0, import_common42.toAddress)(new import_web327.PublicKey(pubkeyBytes));
19859
20190
  results.push({ index: i, source: "marginfi", userAccount });
19860
20191
  }
19861
20192
  return results;
@@ -19921,7 +20252,7 @@ var ExternalLiquidityIntegrityService = class {
19921
20252
  return result;
19922
20253
  }
19923
20254
  const hwManagerAddress = (0, import_common42.fromWeb3Pk)(hwManager.publicKey);
19924
- const vaultPk = new import_web326.PublicKey(vault.toString());
20255
+ const vaultPk = new import_web327.PublicKey(vault.toString());
19925
20256
  const registeredHwManager = pubkeyStr(
19926
20257
  vaultState.roles.hwManager
19927
20258
  );
@@ -20111,33 +20442,42 @@ var ExternalLiquidityIntegrityService = class {
20111
20442
  WithdrawalQueueService,
20112
20443
  addCashflowUpdate,
20113
20444
  address,
20445
+ confirmYieldPayment,
20114
20446
  createAccount,
20115
20447
  createLiveConsensusOracleDeps,
20116
20448
  createRpcFromConnection,
20117
20449
  createTokenMint,
20118
20450
  createTokenMintIxs,
20119
20451
  createVaultClient,
20452
+ createYieldPayment,
20120
20453
  dateToStr,
20121
20454
  defaultKeypairPath,
20122
20455
  deleteAccount,
20456
+ findSquadsWalletRoute,
20123
20457
  fromUiAmount,
20124
20458
  getAccounts,
20125
20459
  getBalance,
20126
20460
  getCashflows,
20127
20461
  getRpcUrl,
20462
+ getTotalOutstandingYield,
20128
20463
  getTotalYield,
20129
20464
  getVaultProgramId,
20130
20465
  getYield,
20466
+ getYieldPayments,
20131
20467
  isVaultEnv,
20132
20468
  keypairAddress,
20133
20469
  loadKeypair,
20134
20470
  makeProvider,
20135
20471
  mintTokensTo,
20472
+ prepareVaultTransaction,
20136
20473
  resolveKeypairPath,
20474
+ resolveSquadsWalletRoute,
20137
20475
  roundToNextUtcMidnight,
20138
20476
  runLiveConsensusOracle,
20139
20477
  systemClock,
20140
20478
  toUiAmount,
20141
20479
  updateAccount,
20142
- updateDynamicApr
20480
+ updateDynamicApr,
20481
+ validateSquadsWalletRoutes,
20482
+ vaultAuthorityForWallet
20143
20483
  });