@perena/vault-sdk 1.0.48 → 1.0.49

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
@@ -1479,6 +1479,140 @@ var require_dist2 = __commonJS({
1479
1479
  }
1480
1480
  });
1481
1481
 
1482
+ // ../nest/dist/priceApi.js
1483
+ var require_priceApi = __commonJS({
1484
+ "../nest/dist/priceApi.js"(exports2) {
1485
+ "use strict";
1486
+ Object.defineProperty(exports2, "__esModule", { value: true });
1487
+ exports2.NEST_API_BASE_URL = void 0;
1488
+ exports2.fetchNestVaultSharePrice = fetchNestVaultSharePrice2;
1489
+ exports2.NEST_API_BASE_URL = "https://api.nest.credit/v1";
1490
+ async function fetchNestVaultSharePrice2(vaultSlug, opts = {}) {
1491
+ const baseUrl = (opts.baseUrl ?? exports2.NEST_API_BASE_URL).replace(/\/$/, "");
1492
+ const response = await (opts.fetchFn ?? fetch)(`${baseUrl}/vaults/${encodeURIComponent(vaultSlug)}/price`);
1493
+ if (!response.ok) {
1494
+ throw new Error(`Nest price API request failed: ${response.status} ${response.statusText}`);
1495
+ }
1496
+ const body = await response.json();
1497
+ const price = [body.data?.interpolatedPrice, body.data?.price].map(Number).find((candidate) => Number.isFinite(candidate) && candidate > 0);
1498
+ if (price === void 0) {
1499
+ throw new Error("Nest price API returned no positive share price");
1500
+ }
1501
+ return price;
1502
+ }
1503
+ }
1504
+ });
1505
+
1506
+ // ../nest/dist/redemptionApi.js
1507
+ var require_redemptionApi = __commonJS({
1508
+ "../nest/dist/redemptionApi.js"(exports2) {
1509
+ "use strict";
1510
+ Object.defineProperty(exports2, "__esModule", { value: true });
1511
+ exports2.NestApiError = void 0;
1512
+ exports2.assertNestShareAmount = assertNestShareAmount;
1513
+ exports2.fetchNestRedemptionTransaction = fetchNestRedemptionTransaction2;
1514
+ exports2.fetchNestRedemptionQuote = fetchNestRedemptionQuote2;
1515
+ exports2.fetchNestRedemptionStatus = fetchNestRedemptionStatus2;
1516
+ var priceApi_1 = require_priceApi();
1517
+ var NestApiError2 = class extends Error {
1518
+ constructor(status, message2) {
1519
+ super(`Nest API (${status}): ${message2}`);
1520
+ this.status = status;
1521
+ this.name = "NestApiError";
1522
+ }
1523
+ };
1524
+ exports2.NestApiError = NestApiError2;
1525
+ function assertNestShareAmount(amount) {
1526
+ if (typeof amount !== "bigint" || amount <= 0n || amount > 0xffffffffffffffffn) {
1527
+ throw new Error("Nest share amount must be a positive u64 bigint in base units");
1528
+ }
1529
+ }
1530
+ async function request(path2, options, body) {
1531
+ const response = await (options.fetchFn ?? fetch)(`${(options.baseUrl ?? priceApi_1.NEST_API_BASE_URL).replace(/\/$/, "")}${path2}`, {
1532
+ method: body ? "POST" : "GET",
1533
+ headers: body ? { "Content-Type": "application/json" } : void 0,
1534
+ body: body ? JSON.stringify(body) : void 0,
1535
+ signal: options.signal
1536
+ });
1537
+ const payload = await response.json().catch(() => null);
1538
+ if (!response.ok) {
1539
+ throw new NestApiError2(response.status, typeof payload?.error === "string" ? payload.error : response.statusText);
1540
+ }
1541
+ if (!payload || typeof payload !== "object" || !payload.data) {
1542
+ throw new Error("Nest API returned an invalid response");
1543
+ }
1544
+ return payload.data;
1545
+ }
1546
+ async function fetchNestRedemptionTransaction2(args, options = {}) {
1547
+ assertNestShareAmount(args.rawAmountNestToken);
1548
+ const data = await request("/solana/nest/async-redeem/request/build-tx", options, {
1549
+ ...args,
1550
+ rawAmountNestToken: args.rawAmountNestToken.toString(),
1551
+ // Squads must sign both the token authority and LayerZero fee payer at execution.
1552
+ feePayer: args.owner
1553
+ });
1554
+ if (typeof data.txBase64 !== "string" || !data.txBase64.length) {
1555
+ throw new Error("Nest API returned no transaction");
1556
+ }
1557
+ return data.txBase64;
1558
+ }
1559
+ async function fetchNestRedemptionQuote2(args, options = {}) {
1560
+ assertNestShareAmount(args.rawAmountNestToken);
1561
+ const data = await request("/solana/nest/async-redeem/quote", options, {
1562
+ ...args,
1563
+ rawAmountNestToken: args.rawAmountNestToken.toString()
1564
+ });
1565
+ if (data.nestVaultSlug !== args.nestVaultSlug || data.redemptionAsset !== "USDC" || data.shareAmount !== args.rawAmountNestToken.toString() || !Number.isInteger(data.shareDecimals) || data.shareDecimals < 0 || data.shareDecimals > 18 || data.redemptionDecimals !== 6 || typeof data.redemptionAmount !== "string" || typeof data.feeAmount !== "string" || !/^\d+$/.test(data.redemptionAmount) || !/^\d+$/.test(data.feeAmount)) {
1566
+ throw new Error("Nest API returned an invalid redemption quote");
1567
+ }
1568
+ return data;
1569
+ }
1570
+ async function fetchNestRedemptionStatus2(signature, options = {}) {
1571
+ if (!/^[1-9A-HJ-NP-Za-km-z]{64,88}$/.test(signature)) {
1572
+ throw new Error("Enter a Solana withdrawal execution signature");
1573
+ }
1574
+ let data;
1575
+ try {
1576
+ data = await request(`/solana/redeem-status/${encodeURIComponent(signature)}`, options);
1577
+ } catch (error) {
1578
+ if (error instanceof NestApiError2 && error.status === 404)
1579
+ return null;
1580
+ throw error;
1581
+ }
1582
+ if (data.solanaBurnSignature !== signature || typeof data.solanaWallet !== "string" || typeof data.overallStatus !== "string" || !["solanaBurn", "plumeProcessing", "cctpAttestation", "solanaClaim"].every((key) => typeof data.steps?.[key]?.status === "string")) {
1583
+ throw new Error("Nest API returned an invalid redemption status");
1584
+ }
1585
+ return data;
1586
+ }
1587
+ }
1588
+ });
1589
+
1590
+ // ../nest/dist/index.js
1591
+ var require_dist3 = __commonJS({
1592
+ "../nest/dist/index.js"(exports2) {
1593
+ "use strict";
1594
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
1595
+ if (k2 === void 0) k2 = k;
1596
+ var desc = Object.getOwnPropertyDescriptor(m, k);
1597
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
1598
+ desc = { enumerable: true, get: function() {
1599
+ return m[k];
1600
+ } };
1601
+ }
1602
+ Object.defineProperty(o, k2, desc);
1603
+ }) : (function(o, m, k, k2) {
1604
+ if (k2 === void 0) k2 = k;
1605
+ o[k2] = m[k];
1606
+ }));
1607
+ var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) {
1608
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
1609
+ };
1610
+ Object.defineProperty(exports2, "__esModule", { value: true });
1611
+ __exportStar(require_priceApi(), exports2);
1612
+ __exportStar(require_redemptionApi(), exports2);
1613
+ }
1614
+ });
1615
+
1482
1616
  // ../../node_modules/.pnpm/@jup-ag+api@6.0.48/node_modules/@jup-ag/api/dist/index.mjs
1483
1617
  var dist_exports = {};
1484
1618
  __export(dist_exports, {
@@ -2978,7 +3112,7 @@ var require_client = __commonJS({
2978
3112
  });
2979
3113
 
2980
3114
  // ../../node_modules/.pnpm/jupiter@file+typescript+jupiter_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0._929400004aea12c8b3c9bcc7c5a22ec9/node_modules/jupiter/dist/priceApi.js
2981
- var require_priceApi = __commonJS({
3115
+ var require_priceApi2 = __commonJS({
2982
3116
  "../../node_modules/.pnpm/jupiter@file+typescript+jupiter_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0._929400004aea12c8b3c9bcc7c5a22ec9/node_modules/jupiter/dist/priceApi.js"(exports2) {
2983
3117
  "use strict";
2984
3118
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -3109,7 +3243,7 @@ var require_types4 = __commonJS({
3109
3243
  });
3110
3244
 
3111
3245
  // ../../node_modules/.pnpm/jupiter@file+typescript+jupiter_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0._929400004aea12c8b3c9bcc7c5a22ec9/node_modules/jupiter/dist/index.js
3112
- var require_dist3 = __commonJS({
3246
+ var require_dist4 = __commonJS({
3113
3247
  "../../node_modules/.pnpm/jupiter@file+typescript+jupiter_bufferutil@4.1.0_fastestsmallesttextencoderdecoder@1.0._929400004aea12c8b3c9bcc7c5a22ec9/node_modules/jupiter/dist/index.js"(exports2) {
3114
3248
  "use strict";
3115
3249
  var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
@@ -3132,147 +3266,13 @@ var require_dist3 = __commonJS({
3132
3266
  __exportStar(require_api(), exports2);
3133
3267
  __exportStar(require_client(), exports2);
3134
3268
  __exportStar(require_constants4(), exports2);
3135
- __exportStar(require_priceApi(), exports2);
3269
+ __exportStar(require_priceApi2(), exports2);
3136
3270
  __exportStar(require_routePreInstructions(), exports2);
3137
3271
  __exportStar(require_sizeExactInForMinOutput(), exports2);
3138
3272
  __exportStar(require_types4(), exports2);
3139
3273
  }
3140
3274
  });
3141
3275
 
3142
- // ../nest/dist/priceApi.js
3143
- var require_priceApi2 = __commonJS({
3144
- "../nest/dist/priceApi.js"(exports2) {
3145
- "use strict";
3146
- Object.defineProperty(exports2, "__esModule", { value: true });
3147
- exports2.NEST_API_BASE_URL = void 0;
3148
- exports2.fetchNestVaultSharePrice = fetchNestVaultSharePrice2;
3149
- exports2.NEST_API_BASE_URL = "https://api.nest.credit/v1";
3150
- async function fetchNestVaultSharePrice2(vaultSlug, opts = {}) {
3151
- const baseUrl = (opts.baseUrl ?? exports2.NEST_API_BASE_URL).replace(/\/$/, "");
3152
- const response = await (opts.fetchFn ?? fetch)(`${baseUrl}/vaults/${encodeURIComponent(vaultSlug)}/price`);
3153
- if (!response.ok) {
3154
- throw new Error(`Nest price API request failed: ${response.status} ${response.statusText}`);
3155
- }
3156
- const body = await response.json();
3157
- const price = [body.data?.interpolatedPrice, body.data?.price].map(Number).find((candidate) => Number.isFinite(candidate) && candidate > 0);
3158
- if (price === void 0) {
3159
- throw new Error("Nest price API returned no positive share price");
3160
- }
3161
- return price;
3162
- }
3163
- }
3164
- });
3165
-
3166
- // ../nest/dist/redemptionApi.js
3167
- var require_redemptionApi = __commonJS({
3168
- "../nest/dist/redemptionApi.js"(exports2) {
3169
- "use strict";
3170
- Object.defineProperty(exports2, "__esModule", { value: true });
3171
- exports2.NestApiError = void 0;
3172
- exports2.assertNestShareAmount = assertNestShareAmount;
3173
- exports2.fetchNestRedemptionTransaction = fetchNestRedemptionTransaction2;
3174
- exports2.fetchNestRedemptionQuote = fetchNestRedemptionQuote2;
3175
- exports2.fetchNestRedemptionStatus = fetchNestRedemptionStatus2;
3176
- var priceApi_1 = require_priceApi2();
3177
- var NestApiError2 = class extends Error {
3178
- constructor(status, message2) {
3179
- super(`Nest API (${status}): ${message2}`);
3180
- this.status = status;
3181
- this.name = "NestApiError";
3182
- }
3183
- };
3184
- exports2.NestApiError = NestApiError2;
3185
- function assertNestShareAmount(amount) {
3186
- if (typeof amount !== "bigint" || amount <= 0n || amount > 0xffffffffffffffffn) {
3187
- throw new Error("Nest share amount must be a positive u64 bigint in base units");
3188
- }
3189
- }
3190
- async function request(path2, options, body) {
3191
- const response = await (options.fetchFn ?? fetch)(`${(options.baseUrl ?? priceApi_1.NEST_API_BASE_URL).replace(/\/$/, "")}${path2}`, {
3192
- method: body ? "POST" : "GET",
3193
- headers: body ? { "Content-Type": "application/json" } : void 0,
3194
- body: body ? JSON.stringify(body) : void 0,
3195
- signal: options.signal
3196
- });
3197
- const payload = await response.json().catch(() => null);
3198
- if (!response.ok) {
3199
- throw new NestApiError2(response.status, typeof payload?.error === "string" ? payload.error : response.statusText);
3200
- }
3201
- if (!payload || typeof payload !== "object" || !payload.data) {
3202
- throw new Error("Nest API returned an invalid response");
3203
- }
3204
- return payload.data;
3205
- }
3206
- async function fetchNestRedemptionTransaction2(args, options = {}) {
3207
- assertNestShareAmount(args.rawAmountNestToken);
3208
- const data = await request("/solana/nest/async-redeem/request/build-tx", options, {
3209
- ...args,
3210
- rawAmountNestToken: args.rawAmountNestToken.toString(),
3211
- // Squads must sign both the token authority and LayerZero fee payer at execution.
3212
- feePayer: args.owner
3213
- });
3214
- if (typeof data.txBase64 !== "string" || !data.txBase64.length) {
3215
- throw new Error("Nest API returned no transaction");
3216
- }
3217
- return data.txBase64;
3218
- }
3219
- async function fetchNestRedemptionQuote2(args, options = {}) {
3220
- assertNestShareAmount(args.rawAmountNestToken);
3221
- const data = await request("/solana/nest/async-redeem/quote", options, {
3222
- ...args,
3223
- rawAmountNestToken: args.rawAmountNestToken.toString()
3224
- });
3225
- if (data.nestVaultSlug !== args.nestVaultSlug || data.redemptionAsset !== "USDC" || data.shareAmount !== args.rawAmountNestToken.toString() || !Number.isInteger(data.shareDecimals) || data.shareDecimals < 0 || data.shareDecimals > 18 || data.redemptionDecimals !== 6 || typeof data.redemptionAmount !== "string" || typeof data.feeAmount !== "string" || !/^\d+$/.test(data.redemptionAmount) || !/^\d+$/.test(data.feeAmount)) {
3226
- throw new Error("Nest API returned an invalid redemption quote");
3227
- }
3228
- return data;
3229
- }
3230
- async function fetchNestRedemptionStatus2(signature, options = {}) {
3231
- if (!/^[1-9A-HJ-NP-Za-km-z]{64,88}$/.test(signature)) {
3232
- throw new Error("Enter a Solana withdrawal execution signature");
3233
- }
3234
- let data;
3235
- try {
3236
- data = await request(`/solana/redeem-status/${encodeURIComponent(signature)}`, options);
3237
- } catch (error) {
3238
- if (error instanceof NestApiError2 && error.status === 404)
3239
- return null;
3240
- throw error;
3241
- }
3242
- if (data.solanaBurnSignature !== signature || typeof data.solanaWallet !== "string" || typeof data.overallStatus !== "string" || !["solanaBurn", "plumeProcessing", "cctpAttestation", "solanaClaim"].every((key) => typeof data.steps?.[key]?.status === "string")) {
3243
- throw new Error("Nest API returned an invalid redemption status");
3244
- }
3245
- return data;
3246
- }
3247
- }
3248
- });
3249
-
3250
- // ../nest/dist/index.js
3251
- var require_dist4 = __commonJS({
3252
- "../nest/dist/index.js"(exports2) {
3253
- "use strict";
3254
- var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
3255
- if (k2 === void 0) k2 = k;
3256
- var desc = Object.getOwnPropertyDescriptor(m, k);
3257
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
3258
- desc = { enumerable: true, get: function() {
3259
- return m[k];
3260
- } };
3261
- }
3262
- Object.defineProperty(o, k2, desc);
3263
- }) : (function(o, m, k, k2) {
3264
- if (k2 === void 0) k2 = k;
3265
- o[k2] = m[k];
3266
- }));
3267
- var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) {
3268
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
3269
- };
3270
- Object.defineProperty(exports2, "__esModule", { value: true });
3271
- __exportStar(require_priceApi2(), exports2);
3272
- __exportStar(require_redemptionApi(), exports2);
3273
- }
3274
- });
3275
-
3276
3276
  // src/index.ts
3277
3277
  var index_exports = {};
3278
3278
  __export(index_exports, {
@@ -3302,7 +3302,7 @@ __export(index_exports, {
3302
3302
  DEFAULT_JUNIOR_WITHDRAWAL_LOCKUP_SECS: () => DEFAULT_JUNIOR_WITHDRAWAL_LOCKUP_SECS,
3303
3303
  DEFAULT_MAX_ACCEPTABLE_APY_BPS: () => DEFAULT_MAX_ACCEPTABLE_APY_BPS,
3304
3304
  DEFAULT_MAX_ACCOUNTS: () => DEFAULT_MAX_ACCOUNTS,
3305
- DEFAULT_MINTS: () => import_common60.DEFAULT_MINTS,
3305
+ DEFAULT_MINTS: () => import_common61.DEFAULT_MINTS,
3306
3306
  DEFAULT_MIN_AMOUNT_UI: () => DEFAULT_MIN_AMOUNT_UI,
3307
3307
  DEFAULT_ORACLE_STALENESS_THRESHOLD_SECS: () => DEFAULT_ORACLE_STALENESS_THRESHOLD_SECS,
3308
3308
  DEFAULT_PRICE_ORACLE_ACCOUNT: () => DEFAULT_PRICE_ORACLE_ACCOUNT,
@@ -3338,6 +3338,8 @@ __export(index_exports, {
3338
3338
  LOCAL_PROTOCOL_ADMIN: () => LOCAL_PROTOCOL_ADMIN,
3339
3339
  LargeBalanceChangeError: () => LargeBalanceChangeError,
3340
3340
  LivePriceSource: () => LivePriceSource,
3341
+ MANAGER_WALLET_NAV_DROP_TRIGGER_BPS: () => MANAGER_WALLET_NAV_DROP_TRIGGER_BPS,
3342
+ MANAGER_WALLET_NAV_TOLERANCE_BPS: () => MANAGER_WALLET_NAV_TOLERANCE_BPS,
3341
3343
  MAX_APY_ANCHOR_WINDOW_SECS: () => MAX_APY_ANCHOR_WINDOW_SECS,
3342
3344
  MAX_BALANCE_CHANGE_BPS: () => MAX_BALANCE_CHANGE_BPS,
3343
3345
  MAX_CONSENSUS_SIGNERS: () => MAX_CONSENSUS_SIGNERS,
@@ -3349,7 +3351,7 @@ __export(index_exports, {
3349
3351
  ManagerRedepositAssetBuilder: () => ManagerRedepositAssetBuilder,
3350
3352
  ManagerWithdrawAssetBuilder: () => ManagerWithdrawAssetBuilder,
3351
3353
  MarginfiPositionProvider: () => MarginfiPositionProvider,
3352
- MintRegistry: () => import_common60.MintRegistry,
3354
+ MintRegistry: () => import_common61.MintRegistry,
3353
3355
  MockYieldTracker: () => MockYieldTracker,
3354
3356
  NEST_API_BASE_URL: () => import_nest2.NEST_API_BASE_URL,
3355
3357
  NEST_RWA_SHARE_MINT: () => NEST_RWA_SHARE_MINT,
@@ -3370,6 +3372,7 @@ __export(index_exports, {
3370
3372
  RemoveAssetHoldingBuilder: () => RemoveAssetHoldingBuilder,
3371
3373
  ReportIncentiveV3Builder: () => ReportIncentiveV3Builder,
3372
3374
  RequestJuniorTrancheWithdrawBuilder: () => RequestJuniorTrancheWithdrawBuilder,
3375
+ RpcManagerWalletBalanceSource: () => RpcManagerWalletBalanceSource,
3373
3376
  SHARE_DECIMALS: () => SHARE_DECIMALS,
3374
3377
  SYSTEM_PROGRAM: () => SYSTEM_PROGRAM,
3375
3378
  SetAssetPriceOracleBuilder: () => SetAssetPriceOracleBuilder,
@@ -3420,6 +3423,7 @@ __export(index_exports, {
3420
3423
  buildMarginfiWithdrawInteraction: () => buildMarginfiWithdrawInteraction,
3421
3424
  buildNestWithdrawalRequest: () => buildNestWithdrawalRequest,
3422
3425
  buildUpdates: () => buildUpdates,
3426
+ candidateGrossNav: () => candidateGrossNav,
3423
3427
  coerceBool: () => coerceBool3,
3424
3428
  collectSamples: () => collectSamples,
3425
3429
  confirmYieldPayment: () => confirmYieldPayment,
@@ -3478,16 +3482,19 @@ __export(index_exports, {
3478
3482
  loadKeypair: () => loadKeypair,
3479
3483
  logProspectiveApy: () => logProspectiveApy,
3480
3484
  makeProvider: () => makeProvider,
3485
+ managerReconciliationStateKey: () => managerReconciliationStateKey,
3481
3486
  mintTokensTo: () => mintTokensTo,
3482
- mints: () => import_common60.mints,
3487
+ mints: () => import_common61.mints,
3483
3488
  mostFrequent: () => mostFrequent,
3484
3489
  parseExternalLiquidityRefs: () => parseExternalLiquidityRefs,
3485
3490
  planRebalance: () => planRebalance,
3486
3491
  prepareSquadsProposalUpload: () => prepareSquadsProposalUpload,
3487
3492
  prepareVaultTransaction: () => prepareVaultTransaction,
3493
+ previousPhysicalNav: () => previousPhysicalNav,
3488
3494
  priceInAccountingUnit: () => priceInAccountingUnit,
3489
3495
  readI64LE: () => readI64LE,
3490
3496
  readSplMintSupply: () => readSplMintSupply,
3497
+ reconcileManagerWalletBalances: () => reconcileManagerWalletBalances,
3491
3498
  refreshLiveOraclePrices: () => refreshLiveOraclePrices,
3492
3499
  resolveExternalWithdraw: () => resolveExternalWithdraw,
3493
3500
  resolveKeypairPath: () => resolveKeypairPath,
@@ -20498,15 +20505,199 @@ async function refreshLiveOraclePrices({
20498
20505
  return results.some((result) => Boolean(result.signature));
20499
20506
  }
20500
20507
 
20501
- // src/services/consensusOracle/pipeline/pricingInputs.ts
20508
+ // src/services/consensusOracle/pipeline/managerWalletReconciliation.ts
20502
20509
  var import_common51 = __toESM(require_dist());
20510
+
20511
+ // src/services/consensusOracle/sources/nestPriceSource.ts
20512
+ var import_kit13 = require("@solana/kit");
20513
+ var import_nest = __toESM(require_dist3());
20514
+ var import_nest2 = __toESM(require_dist3());
20515
+ var NEST_VAULT_SLUG = "nest-perena-vault";
20516
+ var NEST_RWA_SHARE_MINT = (0, import_kit13.address)(
20517
+ "VyXKJnVhkSkB6KAozSZCiLQbuB1k1r6Nu4etNYVo5LJ"
20518
+ );
20519
+ async function fetchNestTokenPrice(nestVaultSlug = NEST_VAULT_SLUG, opts = {}) {
20520
+ return (0, import_nest.fetchNestVaultSharePrice)(nestVaultSlug, opts);
20521
+ }
20522
+ var NestPriceSource = class {
20523
+ constructor(opts = {}) {
20524
+ this.shareMint = opts.shareMint ?? NEST_RWA_SHARE_MINT;
20525
+ this.nestVaultSlug = opts.nestVaultSlug ?? NEST_VAULT_SLUG;
20526
+ this.options = { baseUrl: opts.baseUrl, fetchFn: opts.fetchFn };
20527
+ }
20528
+ async fetchUsdPrices(mints2) {
20529
+ if (!mints2.some((mint) => mint.toString() === this.shareMint.toString())) {
20530
+ return {};
20531
+ }
20532
+ return {
20533
+ [this.shareMint.toString()]: await (0, import_nest.fetchNestVaultSharePrice)(
20534
+ this.nestVaultSlug,
20535
+ this.options
20536
+ )
20537
+ };
20538
+ }
20539
+ };
20540
+
20541
+ // src/services/consensusOracle/pipeline/managerWalletReconciliation.ts
20542
+ var MANAGER_WALLET_NAV_DROP_TRIGGER_BPS = 10n;
20543
+ var MANAGER_WALLET_NAV_TOLERANCE_BPS = 5n;
20544
+ var BPS = 10000n;
20545
+ var U64_MAX = 0xffffffffffffffffn;
20546
+ function previousPhysicalNav(state) {
20547
+ const banked = toBigInt2(state.config.apy?.accruedApyBalance);
20548
+ return toBigInt2(state.accounting?.tvl) + (banked > 0n ? banked : 0n);
20549
+ }
20550
+ function candidateGrossNav(state, updates) {
20551
+ const byIndex = /* @__PURE__ */ new Map();
20552
+ for (const update of updates) {
20553
+ const holding = state.holdings[update.holdingIndex];
20554
+ if (!holding || (0, import_common51.fromWeb3Pk)(holding.mint) !== update.mint || holding.decimals !== update.decimals || byIndex.has(update.holdingIndex)) {
20555
+ throw new Error(`Invalid NAV update for holding #${update.holdingIndex}`);
20556
+ }
20557
+ byIndex.set(update.holdingIndex, update);
20558
+ }
20559
+ return state.holdings.reduce((nav, holding, index) => {
20560
+ if ((0, import_common51.fromWeb3Pk)(holding.mint) === SYSTEM_PROGRAM) return nav;
20561
+ const update = byIndex.get(index);
20562
+ const local = toBigInt2(holding.localAmount);
20563
+ const external = update?.externalAmount ?? toBigInt2(holding.externalAmount);
20564
+ if (local < 0n || external < 0n || local + external > U64_MAX) {
20565
+ throw new Error(`Invalid NAV amount for holding #${index}`);
20566
+ }
20567
+ if (local + external === 0n) return nav;
20568
+ const price = update && variantName2(holding.priceOracleType).toLowerCase() === CONSENSUS_ORACLE_VARIANT ? update.price : toBigInt2(holding.price);
20569
+ if (price <= 0n || !Number.isInteger(holding.decimals) || holding.decimals < 0 || holding.decimals > 18) {
20570
+ throw new Error(
20571
+ `Cannot value holding #${index} for manager reconciliation`
20572
+ );
20573
+ }
20574
+ const nextNav = nav + (local + external) * price / 10n ** BigInt(holding.decimals);
20575
+ if (nextNav > U64_MAX) throw new Error("Candidate NAV exceeds u64");
20576
+ return nextNav;
20577
+ }, 0n);
20578
+ }
20579
+ function retainPendingNestShares(state, updates) {
20580
+ return updates.map((update) => {
20581
+ if (update.mint !== NEST_RWA_SHARE_MINT) return update;
20582
+ const recorded = toBigInt2(
20583
+ state.holdings[update.holdingIndex]?.externalAmount
20584
+ );
20585
+ if (recorded <= update.externalAmount) return update;
20586
+ return {
20587
+ ...update,
20588
+ pendingNestAmount: recorded - update.externalAmount,
20589
+ externalAmount: recorded
20590
+ };
20591
+ });
20592
+ }
20593
+ async function reconcileManagerWalletBalances({
20594
+ vault,
20595
+ vaultState,
20596
+ updates,
20597
+ source,
20598
+ log = () => {
20599
+ }
20600
+ }) {
20601
+ const previousNav = previousPhysicalNav(vaultState);
20602
+ if (updates.some(
20603
+ (update) => (update.managerWalletAmount ?? 0n) !== 0n || (update.pendingNestAmount ?? 0n) !== 0n
20604
+ )) {
20605
+ throw new Error("Manager reconciliation requires fresh source amounts");
20606
+ }
20607
+ const pendingUpdates = retainPendingNestShares(vaultState, updates);
20608
+ if (!source || previousNav <= 0n) {
20609
+ return {
20610
+ accepted: false,
20611
+ updates: pendingUpdates,
20612
+ previousNav,
20613
+ candidateNav: 0n
20614
+ };
20615
+ }
20616
+ const candidateNav = candidateGrossNav(vaultState, updates);
20617
+ const result = {
20618
+ accepted: false,
20619
+ updates: pendingUpdates,
20620
+ previousNav,
20621
+ candidateNav
20622
+ };
20623
+ if ((previousNav - candidateNav) * BPS < previousNav * MANAGER_WALLET_NAV_DROP_TRIGGER_BPS) {
20624
+ return result;
20625
+ }
20626
+ const baseUpdates = updates.filter(
20627
+ (update) => coerceBool3(vaultState.holdings[update.holdingIndex].isBase)
20628
+ );
20629
+ const mints2 = baseUpdates.map((update) => update.mint);
20630
+ if (mints2.length === 0) return result;
20631
+ if (new Set(mints2).size !== mints2.length) {
20632
+ throw new Error("Duplicate base mint in manager reconciliation");
20633
+ }
20634
+ if (vaultState.holdings.some(
20635
+ (holding) => coerceBool3(holding.isBase) && !mints2.includes((0, import_common51.fromWeb3Pk)(holding.mint))
20636
+ )) {
20637
+ throw new Error(
20638
+ "Cannot reconcile all vault base assets with oracle reports"
20639
+ );
20640
+ }
20641
+ const manager = (0, import_common51.fromWeb3Pk)(vaultState.roles.manager);
20642
+ if (manager === SYSTEM_PROGRAM || manager === vault) {
20643
+ throw new Error("Invalid manager wallet for NAV reconciliation");
20644
+ }
20645
+ log(
20646
+ `vault ${vault}: NAV ${candidateNav} is at least 0.1% below ${previousNav}; checking manager ${manager}`
20647
+ );
20648
+ const amounts = await source.fetchBalances(manager, mints2);
20649
+ const adjusted = updates.map((update) => {
20650
+ if (!mints2.includes(update.mint)) return update;
20651
+ const amount = amounts.get(update.mint) ?? 0n;
20652
+ if (typeof amount !== "bigint" || amount < 0n || amount > U64_MAX) {
20653
+ throw new Error(`Invalid manager base-asset balance for ${update.mint}`);
20654
+ }
20655
+ return {
20656
+ ...update,
20657
+ managerWalletAmount: amount,
20658
+ externalAmount: update.externalAmount + amount
20659
+ };
20660
+ });
20661
+ const adjustedNav = candidateGrossNav(vaultState, adjusted);
20662
+ const delta = adjustedNav - previousNav;
20663
+ const absoluteDelta = delta < 0n ? -delta : delta;
20664
+ const accepted = adjustedNav > candidateNav && absoluteDelta * BPS <= previousNav * MANAGER_WALLET_NAV_TOLERANCE_BPS;
20665
+ log(
20666
+ `vault ${vault}: manager wallet ${accepted ? "accepted" : "rejected"}; adjusted NAV ${adjustedNav}, previous NAV ${previousNav}, allowed difference \xB10.05%`
20667
+ );
20668
+ return {
20669
+ accepted,
20670
+ updates: accepted ? adjusted : pendingUpdates,
20671
+ previousNav,
20672
+ candidateNav,
20673
+ adjustedNav
20674
+ };
20675
+ }
20676
+ function managerReconciliationStateKey(state) {
20677
+ return JSON.stringify({
20678
+ manager: (0, import_common51.fromWeb3Pk)(state.roles.manager),
20679
+ previousNav: previousPhysicalNav(state).toString(),
20680
+ holdings: state.holdings.map((holding) => [
20681
+ (0, import_common51.fromWeb3Pk)(holding.mint),
20682
+ holding.decimals,
20683
+ variantName2(holding.priceOracleType),
20684
+ coerceBool3(holding.isBase),
20685
+ toBigInt2(holding.localAmount).toString(),
20686
+ toBigInt2(holding.externalAmount).toString(),
20687
+ toBigInt2(holding.price).toString()
20688
+ ])
20689
+ });
20690
+ }
20691
+
20692
+ // src/services/consensusOracle/pipeline/pricingInputs.ts
20693
+ var import_common52 = __toESM(require_dist());
20503
20694
  async function gatherPricingInputs(deps, target, vaultState, reportableHoldings, log = () => {
20504
20695
  }) {
20505
20696
  const consensusMints = reportableHoldings.filter(
20506
20697
  ({ holding }) => variantName2(holding.priceOracleType).toLowerCase() === CONSENSUS_ORACLE_VARIANT
20507
- ).map(({ holding }) => (0, import_common51.fromWeb3Pk)(holding.mint));
20698
+ ).map(({ holding }) => (0, import_common52.fromWeb3Pk)(holding.mint));
20508
20699
  const baseHolding = vaultState.holdings.find((h) => coerceBool3(h.isBase));
20509
- const baseMint = baseHolding ? (0, import_common51.fromWeb3Pk)(baseHolding.mint) : consensusMints[0];
20700
+ const baseMint = baseHolding ? (0, import_common52.fromWeb3Pk)(baseHolding.mint) : consensusMints[0];
20510
20701
  if (!baseMint) {
20511
20702
  throw new Error(`vault has no holdings \u2014 cannot determine base asset`);
20512
20703
  }
@@ -20590,11 +20781,11 @@ function reconcilePositionSnapshots(snapshots, vault, log) {
20590
20781
  }
20591
20782
 
20592
20783
  // src/services/consensusOracle/pipeline/receiptMints.ts
20593
- var import_common52 = __toESM(require_dist());
20784
+ var import_common53 = __toESM(require_dist());
20594
20785
  async function fetchReceiptMints(client, vault, vaultState) {
20595
20786
  const receiptMints = /* @__PURE__ */ new Set();
20596
20787
  if (vaultState.mint) {
20597
- receiptMints.add((0, import_common52.fromWeb3Pk)(vaultState.mint).toString());
20788
+ receiptMints.add((0, import_common53.fromWeb3Pk)(vaultState.mint).toString());
20598
20789
  }
20599
20790
  if (!coerceBool3(vaultState.tranchingEnabled)) return receiptMints;
20600
20791
  const trancheState = await client.account.fetchVaultTrancheStateForVault(
@@ -20602,19 +20793,19 @@ async function fetchReceiptMints(client, vault, vaultState) {
20602
20793
  { fresh: true }
20603
20794
  );
20604
20795
  receiptMints.add(
20605
- (0, import_common52.fromWeb3Pk)(trancheState.config.juniorMint).toString()
20796
+ (0, import_common53.fromWeb3Pk)(trancheState.config.juniorMint).toString()
20606
20797
  );
20607
20798
  receiptMints.add(
20608
- (0, import_common52.fromWeb3Pk)(trancheState.config.seniorMint).toString()
20799
+ (0, import_common53.fromWeb3Pk)(trancheState.config.seniorMint).toString()
20609
20800
  );
20610
20801
  return receiptMints;
20611
20802
  }
20612
20803
 
20613
20804
  // src/services/consensusOracle/pipeline/settlement.ts
20614
- var import_common54 = __toESM(require_dist());
20805
+ var import_common55 = __toESM(require_dist());
20615
20806
 
20616
20807
  // src/services/consensusOracle/pipeline/yieldAccounts.ts
20617
- var import_common53 = __toESM(require_dist());
20808
+ var import_common54 = __toESM(require_dist());
20618
20809
  async function assertNoUnconfirmedYieldPayments(yieldTracker, target) {
20619
20810
  const accountNames = [
20620
20811
  ...new Set(
@@ -20656,7 +20847,7 @@ async function withDiscoveredYieldAccounts(yieldTracker, target, vaultState, exc
20656
20847
  );
20657
20848
  if (namesToAttach.length === 0) return target;
20658
20849
  const baseHolding = vaultState.holdings.find((holding) => {
20659
- const mint = (0, import_common53.fromWeb3Pk)(holding.mint).toString();
20850
+ const mint = (0, import_common54.fromWeb3Pk)(holding.mint).toString();
20660
20851
  return coerceBool3(holding.isBase) && !excludedMints.has(mint);
20661
20852
  });
20662
20853
  if (!baseHolding) {
@@ -20664,7 +20855,7 @@ async function withDiscoveredYieldAccounts(yieldTracker, target, vaultState, exc
20664
20855
  `vault ${target.vault}: tagged yield accounts found but no base holding is available`
20665
20856
  );
20666
20857
  }
20667
- const baseMint = (0, import_common53.fromWeb3Pk)(baseHolding.mint);
20858
+ const baseMint = (0, import_common54.fromWeb3Pk)(baseHolding.mint);
20668
20859
  const holdings = [...target.holdings ?? []];
20669
20860
  const existingIndex = holdings.findIndex(
20670
20861
  (holding) => holding.mint.toString() === baseMint.toString()
@@ -20697,13 +20888,14 @@ async function settleVault2({
20697
20888
  updates,
20698
20889
  vaultState,
20699
20890
  nowSecs,
20700
- log
20891
+ log,
20892
+ beforeSubmit
20701
20893
  }) {
20702
20894
  const vault = target.vault;
20703
20895
  log(`vault ${vault}: submitting ${updates.length} consensus asset update(s)`);
20704
20896
  for (const update of updates) {
20705
20897
  log(
20706
- ` holding #${update.holdingIndex} ${update.mint}: price=${update.price} external_amount=${update.externalAmount} [lp=${update.lpAmount} tracked=${update.trackedValueAmount} principal=${update.trackedPrincipalAmount} yield=${update.yieldAmount}]`
20898
+ ` holding #${update.holdingIndex} ${update.mint}: price=${update.price} external_amount=${update.externalAmount} [pendingNest=${update.pendingNestAmount ?? 0n} managerWallet=${update.managerWalletAmount ?? 0n} lp=${update.lpAmount} tracked=${update.trackedValueAmount} principal=${update.trackedPrincipalAmount} yield=${update.yieldAmount}]`
20707
20899
  );
20708
20900
  }
20709
20901
  try {
@@ -20725,6 +20917,7 @@ async function settleVault2({
20725
20917
  );
20726
20918
  }
20727
20919
  await assertNoUnconfirmedYieldPayments(yieldTracker, target);
20920
+ await beforeSubmit?.();
20728
20921
  const updateSignature = await oracle.updateAssetConsensusPrice(
20729
20922
  signer,
20730
20923
  {
@@ -20765,7 +20958,7 @@ async function logProspectiveApy({
20765
20958
  );
20766
20959
  const prospectiveNav = vaultState.holdings.reduce(
20767
20960
  (sum, holding, holdingIndex) => {
20768
- const mint = (0, import_common54.fromWeb3Pk)(holding.mint).toString();
20961
+ const mint = (0, import_common55.fromWeb3Pk)(holding.mint).toString();
20769
20962
  if (mint === SYSTEM_PROGRAM) return sum;
20770
20963
  const update = updatesByIndex.get(holdingIndex);
20771
20964
  const localAmount = toBigInt2(holding.localAmount);
@@ -20821,7 +21014,7 @@ async function discoverVaultsForSigner(client, signer, opts = {}) {
20821
21014
  }
20822
21015
 
20823
21016
  // src/services/consensusOracle/sources/jupiterPriceSource.ts
20824
- var import_jupiter = __toESM(require_dist3());
21017
+ var import_jupiter = __toESM(require_dist4());
20825
21018
  var JupiterPriceSource = class {
20826
21019
  constructor(opts = {}) {
20827
21020
  this.opts = opts;
@@ -20831,36 +21024,6 @@ var JupiterPriceSource = class {
20831
21024
  }
20832
21025
  };
20833
21026
 
20834
- // src/services/consensusOracle/sources/nestPriceSource.ts
20835
- var import_kit13 = require("@solana/kit");
20836
- var import_nest = __toESM(require_dist4());
20837
- var import_nest2 = __toESM(require_dist4());
20838
- var NEST_VAULT_SLUG = "nest-perena-vault";
20839
- var NEST_RWA_SHARE_MINT = (0, import_kit13.address)(
20840
- "VyXKJnVhkSkB6KAozSZCiLQbuB1k1r6Nu4etNYVo5LJ"
20841
- );
20842
- async function fetchNestTokenPrice(nestVaultSlug = NEST_VAULT_SLUG, opts = {}) {
20843
- return (0, import_nest.fetchNestVaultSharePrice)(nestVaultSlug, opts);
20844
- }
20845
- var NestPriceSource = class {
20846
- constructor(opts = {}) {
20847
- this.shareMint = opts.shareMint ?? NEST_RWA_SHARE_MINT;
20848
- this.nestVaultSlug = opts.nestVaultSlug ?? NEST_VAULT_SLUG;
20849
- this.options = { baseUrl: opts.baseUrl, fetchFn: opts.fetchFn };
20850
- }
20851
- async fetchUsdPrices(mints2) {
20852
- if (!mints2.some((mint) => mint.toString() === this.shareMint.toString())) {
20853
- return {};
20854
- }
20855
- return {
20856
- [this.shareMint.toString()]: await (0, import_nest.fetchNestVaultSharePrice)(
20857
- this.nestVaultSlug,
20858
- this.options
20859
- )
20860
- };
20861
- }
20862
- };
20863
-
20864
21027
  // src/services/consensusOracle/sources/livePriceSource.ts
20865
21028
  var LivePriceSource = class {
20866
21029
  constructor(opts = {}) {
@@ -20882,6 +21045,59 @@ var LivePriceSource = class {
20882
21045
  }
20883
21046
  };
20884
21047
 
21048
+ // src/services/consensusOracle/sources/managerWalletBalanceSource.ts
21049
+ var import_web330 = require("@solana/web3.js");
21050
+ var import_spl_token20 = require("@solana/spl-token");
21051
+ var RpcManagerWalletBalanceSource = class {
21052
+ constructor(connection) {
21053
+ this.connection = connection;
21054
+ }
21055
+ async fetchBalances(manager, mints2) {
21056
+ const wanted = new Set(mints2);
21057
+ if (wanted.size === 0) return /* @__PURE__ */ new Map();
21058
+ const owner = new import_web330.PublicKey(manager);
21059
+ const programs = [import_spl_token20.TOKEN_PROGRAM_ID, import_spl_token20.TOKEN_2022_PROGRAM_ID];
21060
+ const responses = await Promise.all(
21061
+ programs.map(
21062
+ (programId) => this.connection.getParsedTokenAccountsByOwner(
21063
+ owner,
21064
+ { programId },
21065
+ "confirmed"
21066
+ )
21067
+ )
21068
+ );
21069
+ const amounts = /* @__PURE__ */ new Map();
21070
+ const seen = /* @__PURE__ */ new Set();
21071
+ for (let index = 0; index < responses.length; index += 1) {
21072
+ for (const { pubkey: pubkey2, account } of responses[index].value) {
21073
+ const data = account.data;
21074
+ if (!("parsed" in data) || data.parsed?.type !== "account") {
21075
+ throw new Error(`Unparsed manager token account ${pubkey2}`);
21076
+ }
21077
+ const info = data.parsed.info;
21078
+ if (!account.owner.equals(programs[index]) || info?.owner !== manager) {
21079
+ throw new Error(`Invalid manager token account owner ${pubkey2}`);
21080
+ }
21081
+ if (!wanted.has(info.mint)) continue;
21082
+ const key = pubkey2.toBase58();
21083
+ if (seen.has(key))
21084
+ throw new Error(`Duplicate manager token account ${key}`);
21085
+ seen.add(key);
21086
+ const raw = info.tokenAmount?.amount;
21087
+ if (typeof raw !== "string" || !/^\d+$/.test(raw)) {
21088
+ throw new Error(`Invalid manager token balance ${key}`);
21089
+ }
21090
+ const amount = BigInt(raw);
21091
+ if (amount > 0xffffffffffffffffn) {
21092
+ throw new Error(`Manager token balance exceeds u64: ${key}`);
21093
+ }
21094
+ amounts.set(info.mint, (amounts.get(info.mint) ?? 0n) + amount);
21095
+ }
21096
+ }
21097
+ return amounts;
21098
+ }
21099
+ };
21100
+
20885
21101
  // src/services/consensusOracle/positions/externalPositions.ts
20886
21102
  var ExternalPositionRegistry = class {
20887
21103
  constructor(providers = [], log = () => {
@@ -20918,7 +21134,7 @@ var StaticPositionProvider = class {
20918
21134
 
20919
21135
  // src/services/consensusOracle/positions/kaminoPositionProvider.ts
20920
21136
  var import_kit14 = require("@solana/kit");
20921
- var import_web330 = require("@solana/web3.js");
21137
+ var import_web331 = require("@solana/web3.js");
20922
21138
  var import_klend_sdk = require("@kamino-finance/klend-sdk");
20923
21139
  async function readKaminoBalance(manager, vault, sharesHolder) {
20924
21140
  const userShares = await manager.getUserSharesBalanceSingleVault(
@@ -20955,7 +21171,7 @@ var KaminoPositionProvider = class {
20955
21171
  const amount = await readKaminoBalance(
20956
21172
  manager,
20957
21173
  kVault,
20958
- new import_web330.PublicKey(sharesHolder)
21174
+ new import_web331.PublicKey(sharesHolder)
20959
21175
  );
20960
21176
  out.push({ mint: ref.mint, amount });
20961
21177
  }
@@ -20964,7 +21180,7 @@ var KaminoPositionProvider = class {
20964
21180
  };
20965
21181
 
20966
21182
  // src/services/consensusOracle/positions/marginfiPositionProvider.ts
20967
- var import_web331 = require("@solana/web3.js");
21183
+ var import_web332 = require("@solana/web3.js");
20968
21184
  var import_marginfi2 = __toESM(require_dist2());
20969
21185
  var MarginfiPositionProvider = class {
20970
21186
  constructor(connection, log = () => {
@@ -20975,8 +21191,8 @@ var MarginfiPositionProvider = class {
20975
21191
  async positionsFor(ctx) {
20976
21192
  const refs = ctx.refs.filter((r) => r.kind === "marginfi");
20977
21193
  if (refs.length === 0) return [];
20978
- const explicitBanks = refs.map((r) => r.marginfiBank).filter(Boolean).map((bank) => new import_web331.PublicKey(bank));
20979
- const autoAccountPks = refs.filter((r) => !r.marginfiBank).map((r) => r.marginfiAccount).filter(Boolean).map((account) => new import_web331.PublicKey(account));
21194
+ const explicitBanks = refs.map((r) => r.marginfiBank).filter(Boolean).map((bank) => new import_web332.PublicKey(bank));
21195
+ const autoAccountPks = refs.filter((r) => !r.marginfiBank).map((r) => r.marginfiAccount).filter(Boolean).map((account) => new import_web332.PublicKey(account));
20980
21196
  const autoBanks = [];
20981
21197
  for (const accountPk of autoAccountPks) {
20982
21198
  try {
@@ -21005,14 +21221,14 @@ var MarginfiPositionProvider = class {
21005
21221
  if (bank) {
21006
21222
  const amount = await (0, import_marginfi2.readMarginfiBankBalance)(
21007
21223
  client,
21008
- new import_web331.PublicKey(account),
21009
- new import_web331.PublicKey(bank)
21224
+ new import_web332.PublicKey(account),
21225
+ new import_web332.PublicKey(bank)
21010
21226
  );
21011
21227
  out.push({ mint: ref.mint, amount });
21012
21228
  } else {
21013
21229
  const balances = await (0, import_marginfi2.readAllMarginfiBalances)(
21014
21230
  client,
21015
- new import_web331.PublicKey(account)
21231
+ new import_web332.PublicKey(account)
21016
21232
  );
21017
21233
  for (const { mint, amount } of balances) {
21018
21234
  out.push({ mint: mint.toBase58(), amount });
@@ -21219,6 +21435,7 @@ function createLiveConsensusOracleDeps(connection, opts = {}) {
21219
21435
  });
21220
21436
  const deps = {
21221
21437
  priceSource: new LivePriceSource(),
21438
+ managerWalletBalances: new RpcManagerWalletBalanceSource(connection),
21222
21439
  yieldTracker: {
21223
21440
  async getAccountNamesForVault(vault) {
21224
21441
  const accounts2 = await getAccounts();
@@ -21252,7 +21469,7 @@ function createLiveConsensusOracleDeps(connection, opts = {}) {
21252
21469
  }
21253
21470
 
21254
21471
  // src/services/consensusOracle/consensusOracleService.ts
21255
- var import_common55 = __toESM(require_dist());
21472
+ var import_common56 = __toESM(require_dist());
21256
21473
  var ConsensusOracleService = class {
21257
21474
  constructor(client, deps) {
21258
21475
  this.client = client;
@@ -21288,7 +21505,7 @@ var ConsensusOracleService = class {
21288
21505
  receiptMints
21289
21506
  );
21290
21507
  const filteredCount = vaultState.holdings.filter(
21291
- (holding) => receiptMints.has((0, import_common55.fromWeb3Pk)(holding.mint).toString())
21508
+ (holding) => receiptMints.has((0, import_common56.fromWeb3Pk)(holding.mint).toString())
21292
21509
  ).length;
21293
21510
  if (filteredCount > 0) {
21294
21511
  log(
@@ -21318,18 +21535,35 @@ var ConsensusOracleService = class {
21318
21535
  reportableHoldings,
21319
21536
  log
21320
21537
  );
21321
- const updates = await buildUpdates(
21538
+ const sourcedUpdates = await buildUpdates(
21322
21539
  this.deps.yieldTracker,
21323
21540
  reportableHoldings,
21324
21541
  inputs
21325
21542
  );
21326
- assertNoLargeBalanceChanges(
21327
- target.vault,
21543
+ const reconciliation = await reconcileManagerWalletBalances({
21544
+ vault: target.vault,
21328
21545
  vaultState,
21329
- updates,
21330
- this.nowSecs(),
21546
+ updates: sourcedUpdates,
21547
+ source: this.deps.managerWalletBalances,
21331
21548
  log
21332
- );
21549
+ });
21550
+ const updates = reconciliation.updates;
21551
+ const needsRevalidation = reconciliation.accepted || // A new withdrawal can be queued after the first vault read, too.
21552
+ updates.some((update) => update.mint === NEST_RWA_SHARE_MINT);
21553
+ const reconciliationStateKey = needsRevalidation ? managerReconciliationStateKey(vaultState) : void 0;
21554
+ if (!reconciliation.accepted) {
21555
+ assertNoLargeBalanceChanges(
21556
+ target.vault,
21557
+ vaultState,
21558
+ updates,
21559
+ this.nowSecs(),
21560
+ log
21561
+ );
21562
+ } else {
21563
+ log(
21564
+ `vault ${target.vault}: manager NAV reconciliation passed; allowing cross-asset external balance changes`
21565
+ );
21566
+ }
21333
21567
  if (dryRun) {
21334
21568
  log(`vault ${target.vault}: dry run, ${updates.length} holding(s)`);
21335
21569
  try {
@@ -21369,7 +21603,29 @@ var ConsensusOracleService = class {
21369
21603
  updates,
21370
21604
  vaultState,
21371
21605
  nowSecs: this.nowSecs(),
21372
- log
21606
+ log,
21607
+ beforeSubmit: needsRevalidation ? async () => {
21608
+ const freshState = await this.fetchDecodedVault(target.vault);
21609
+ if (managerReconciliationStateKey(freshState) !== reconciliationStateKey) {
21610
+ throw new Error(
21611
+ "Vault changed during manager-wallet reconciliation; retry with fresh inputs"
21612
+ );
21613
+ }
21614
+ if (!reconciliation.accepted) return;
21615
+ const fresh = await reconcileManagerWalletBalances({
21616
+ vault: target.vault,
21617
+ vaultState: freshState,
21618
+ updates: sourcedUpdates,
21619
+ source: this.deps.managerWalletBalances
21620
+ });
21621
+ if (!fresh.accepted || fresh.updates.some(
21622
+ (update, index) => update.externalAmount !== updates[index].externalAmount
21623
+ )) {
21624
+ throw new Error(
21625
+ "Manager wallet changed during reconciliation; retry with fresh inputs"
21626
+ );
21627
+ }
21628
+ } : void 0
21373
21629
  });
21374
21630
  return {
21375
21631
  vault: target.vault,
@@ -21469,8 +21725,8 @@ async function runLiveConsensusOracle(env, oracleSigner, opts = {}) {
21469
21725
 
21470
21726
  // src/services/externalLiquidityIntegrityService.ts
21471
21727
  var import_kit15 = require("@solana/kit");
21472
- var import_web332 = require("@solana/web3.js");
21473
- var import_common56 = __toESM(require_dist());
21728
+ var import_web333 = require("@solana/web3.js");
21729
+ var import_common57 = __toESM(require_dist());
21474
21730
  var import_marginfi3 = __toESM(require_dist2());
21475
21731
  var DEFAULT_MIN_AMOUNT_UI = 1;
21476
21732
  var DEFAULT_TARGET_LOCAL_BPS = 50;
@@ -21492,7 +21748,7 @@ function parseActiveSlots(externalLiquidity) {
21492
21748
  if (discriminant === 0) continue;
21493
21749
  if (discriminant !== 1) continue;
21494
21750
  const pubkeyBytes = new Uint8Array(data.slice(8, 40));
21495
- const userAccount = (0, import_common56.toAddress)(new import_web332.PublicKey(pubkeyBytes));
21751
+ const userAccount = (0, import_common57.toAddress)(new import_web333.PublicKey(pubkeyBytes));
21496
21752
  results.push({ index: i, source: "marginfi", userAccount });
21497
21753
  }
21498
21754
  return results;
@@ -21608,8 +21864,8 @@ var ExternalLiquidityIntegrityService = class {
21608
21864
  result.skipped++;
21609
21865
  return result;
21610
21866
  }
21611
- const hwManagerAddress = (0, import_common56.fromWeb3Pk)(hwManager.publicKey);
21612
- const vaultPk = new import_web332.PublicKey(vault.toString());
21867
+ const hwManagerAddress = (0, import_common57.fromWeb3Pk)(hwManager.publicKey);
21868
+ const vaultPk = new import_web333.PublicKey(vault.toString());
21613
21869
  const registeredHwManager = pubkeyStr(
21614
21870
  vaultState.roles.hwManager
21615
21871
  );
@@ -21736,7 +21992,7 @@ var ExternalLiquidityIntegrityService = class {
21736
21992
  marginfiAccounts.tokenProgram,
21737
21993
  true
21738
21994
  );
21739
- const cpiRefs = (0, import_common56.createCpiRefs)([
21995
+ const cpiRefs = (0, import_common57.createCpiRefs)([
21740
21996
  direction === "deposit" ? marginfiClient.deposit_cpi({
21741
21997
  marginfiAccount: slot.userAccount,
21742
21998
  authority: vault,
@@ -21788,11 +22044,11 @@ var ExternalLiquidityIntegrityService = class {
21788
22044
 
21789
22045
  // src/services/idleLiquidityService.ts
21790
22046
  var import_kit16 = require("@solana/kit");
21791
- var import_spl_token20 = require("@solana/spl-token");
22047
+ var import_spl_token21 = require("@solana/spl-token");
21792
22048
  var import_marginfi_client_v2 = require("@mrgnlabs/marginfi-client-v2");
21793
- var import_web333 = require("@solana/web3.js");
21794
- var import_common57 = __toESM(require_dist());
21795
- var import_jupiter2 = __toESM(require_dist3());
22049
+ var import_web334 = require("@solana/web3.js");
22050
+ var import_common58 = __toESM(require_dist());
22051
+ var import_jupiter2 = __toESM(require_dist4());
21796
22052
  var import_marginfi4 = __toESM(require_dist2());
21797
22053
  var IDLE_RESERVE_FLOOR_BPS = 400;
21798
22054
  var IDLE_RESERVE_TARGET_BPS = 500;
@@ -21890,8 +22146,8 @@ var IdleLiquidityService = class {
21890
22146
  let quote;
21891
22147
  try {
21892
22148
  quote = await jupiter.getQuote({
21893
- inputMint: import_common57.PST_MINT,
21894
- outputMint: import_common57.USDC_MINT,
22149
+ inputMint: import_common58.PST_MINT,
22150
+ outputMint: import_common58.USDC_MINT,
21895
22151
  amount: pstInput,
21896
22152
  slippageBps: opts.slippageBps ?? DEFAULT_SLIPPAGE_BPS,
21897
22153
  maxAccounts: DEFAULT_MAX_ACCOUNTS
@@ -21937,13 +22193,13 @@ var IdleLiquidityService = class {
21937
22193
  /** Read only the two locations that constitute the idle USDC reserve. */
21938
22194
  async fetchIdleUsdc(vault, vaultState) {
21939
22195
  const connection = this.client.provider.connection;
21940
- const vaultPk = new import_web333.PublicKey(vault);
21941
- const usdcMint = new import_web333.PublicKey(import_common57.USDC_MINT);
21942
- const ata = (0, import_spl_token20.getAssociatedTokenAddressSync)(usdcMint, vaultPk, true);
22196
+ const vaultPk = new import_web334.PublicKey(vault);
22197
+ const usdcMint = new import_web334.PublicKey(import_common58.USDC_MINT);
22198
+ const ata = (0, import_spl_token21.getAssociatedTokenAddressSync)(usdcMint, vaultPk, true);
21943
22199
  const tokenInfo = await connection.getAccountInfo(ata, "confirmed");
21944
22200
  let localAmount = 0n;
21945
22201
  if (tokenInfo) {
21946
- const tokenAccount = (0, import_spl_token20.unpackAccount)(ata, tokenInfo, import_spl_token20.TOKEN_PROGRAM_ID);
22202
+ const tokenAccount = (0, import_spl_token21.unpackAccount)(ata, tokenInfo, import_spl_token21.TOKEN_PROGRAM_ID);
21947
22203
  if (!tokenAccount.mint.equals(usdcMint) || !tokenAccount.owner.equals(vaultPk) || !tokenAccount.isInitialized) {
21948
22204
  throw new Error(`Invalid vault USDC token account: ${ata.toBase58()}`);
21949
22205
  }
@@ -21957,12 +22213,12 @@ var IdleLiquidityService = class {
21957
22213
  if (data[0] !== 1) {
21958
22214
  throw new Error("External-liquidity slot 0 is not Marginfi");
21959
22215
  }
21960
- const positionPk = new import_web333.PublicKey(new Uint8Array(data.slice(8, 40)));
22216
+ const positionPk = new import_web334.PublicKey(new Uint8Array(data.slice(8, 40)));
21961
22217
  const positionInfo = await connection.getAccountInfo(
21962
22218
  positionPk,
21963
22219
  "confirmed"
21964
22220
  );
21965
- if (!positionInfo || !positionInfo.owner.equals(new import_web333.PublicKey(import_marginfi4.MARGINFI_PROGRAM_ID))) {
22221
+ if (!positionInfo || !positionInfo.owner.equals(new import_web334.PublicKey(import_marginfi4.MARGINFI_PROGRAM_ID))) {
21966
22222
  throw new Error(
21967
22223
  `Invalid Marginfi slot-0 account: ${positionPk.toBase58()}`
21968
22224
  );
@@ -22012,8 +22268,8 @@ var IdleLiquidityService = class {
22012
22268
  log(`Vault ${vault}: ${reason} \u2014 skipping`);
22013
22269
  return { result: { ...empty, status: "no-tvl", reason } };
22014
22270
  }
22015
- const usdc = findHolding2(vaultState, import_common57.USDC_MINT);
22016
- const pst = findHolding2(vaultState, import_common57.PST_MINT);
22271
+ const usdc = findHolding2(vaultState, import_common58.USDC_MINT);
22272
+ const pst = findHolding2(vaultState, import_common58.PST_MINT);
22017
22273
  if (!usdc || !pst) {
22018
22274
  const reason = `vault has no ${usdc ? "PST" : "USDC"} holding`;
22019
22275
  log(`Vault ${vault}: ${reason} \u2014 skipping`);
@@ -22141,16 +22397,16 @@ var IdleLiquidityService = class {
22141
22397
  */
22142
22398
  async mintTokenProgram(mint) {
22143
22399
  const account = await this.client.provider.connection.getAccountInfo(
22144
- new import_web333.PublicKey(mint),
22400
+ new import_web334.PublicKey(mint),
22145
22401
  "confirmed"
22146
22402
  );
22147
22403
  if (!account) throw new Error(`Mint account not found: ${mint}`);
22148
- if (!account.owner.equals(import_spl_token20.TOKEN_PROGRAM_ID) && !account.owner.equals(import_spl_token20.TOKEN_2022_PROGRAM_ID)) {
22404
+ if (!account.owner.equals(import_spl_token21.TOKEN_PROGRAM_ID) && !account.owner.equals(import_spl_token21.TOKEN_2022_PROGRAM_ID)) {
22149
22405
  throw new Error(
22150
22406
  `Unsupported token program ${account.owner.toBase58()} for mint ${mint}`
22151
22407
  );
22152
22408
  }
22153
- return (0, import_common57.fromWeb3Pk)(account.owner);
22409
+ return (0, import_common58.fromWeb3Pk)(account.owner);
22154
22410
  }
22155
22411
  /**
22156
22412
  * Build, simulate, and (unless `dryRun`) submit the `jupiter_swap`.
@@ -22170,23 +22426,23 @@ var IdleLiquidityService = class {
22170
22426
  dryRun,
22171
22427
  log
22172
22428
  } = params;
22173
- const signer = (0, import_common57.fromWeb3Pk)(hwManager.publicKey);
22429
+ const signer = (0, import_common58.fromWeb3Pk)(hwManager.publicKey);
22174
22430
  const [sourceTokenProgram, destinationTokenProgram] = await Promise.all([
22175
- this.mintTokenProgram(import_common57.PST_MINT),
22176
- this.mintTokenProgram(import_common57.USDC_MINT)
22431
+ this.mintTokenProgram(import_common58.PST_MINT),
22432
+ this.mintTokenProgram(import_common58.USDC_MINT)
22177
22433
  ]);
22178
22434
  const jupiterCpi = await jupiter.getSwapCpiData(quote, vault, {
22179
22435
  payer: signer
22180
22436
  });
22181
- const { accounts: accounts2, refs, lookupTables } = (0, import_common57.createCpiRefs)([jupiterCpi]);
22437
+ const { accounts: accounts2, refs, lookupTables } = (0, import_common58.createCpiRefs)([jupiterCpi]);
22182
22438
  const vaultTrancheState = coerceBool4(
22183
22439
  vaultState.tranchingEnabled
22184
22440
  ) ? (await this.client.pda.deriveVaultTrancheStatePda(vault))[0] : void 0;
22185
22441
  const plan = await this.client.tx.jupiterSwap.getTx({
22186
22442
  hwManager: signer,
22187
22443
  vault,
22188
- sourceMint: import_common57.PST_MINT,
22189
- destinationMint: import_common57.USDC_MINT,
22444
+ sourceMint: import_common58.PST_MINT,
22445
+ destinationMint: import_common58.USDC_MINT,
22190
22446
  refs,
22191
22447
  accounts: accounts2,
22192
22448
  sourceTokenProgram,
@@ -22196,26 +22452,26 @@ var IdleLiquidityService = class {
22196
22452
  });
22197
22453
  const connection = this.client.provider.connection;
22198
22454
  const instructions2 = [
22199
- import_web333.ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNIT_LIMIT }),
22455
+ import_web334.ComputeBudgetProgram.setComputeUnitLimit({ units: COMPUTE_UNIT_LIMIT }),
22200
22456
  ...cuPriceMicroLamports > 0 ? [
22201
- import_web333.ComputeBudgetProgram.setComputeUnitPrice({
22457
+ import_web334.ComputeBudgetProgram.setComputeUnitPrice({
22202
22458
  microLamports: cuPriceMicroLamports
22203
22459
  })
22204
22460
  ] : [],
22205
- ...(jupiterCpi.preInstructions ?? []).map(import_common57.fromKitInstruction),
22206
- ...plan.instructions.map(import_common57.fromKitInstruction)
22461
+ ...(jupiterCpi.preInstructions ?? []).map(import_common58.fromKitInstruction),
22462
+ ...plan.instructions.map(import_common58.fromKitInstruction)
22207
22463
  ];
22208
22464
  const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
22209
- const lookupTableAccounts = await (0, import_common57.fetchLookupTables)(
22465
+ const lookupTableAccounts = await (0, import_common58.fetchLookupTables)(
22210
22466
  connection,
22211
22467
  plan.lookupTables ?? []
22212
22468
  );
22213
- const message2 = new import_web333.TransactionMessage({
22469
+ const message2 = new import_web334.TransactionMessage({
22214
22470
  payerKey: hwManager.publicKey,
22215
22471
  recentBlockhash: blockhash,
22216
22472
  instructions: instructions2
22217
22473
  }).compileToV0Message(lookupTableAccounts);
22218
- const transaction = new import_web333.VersionedTransaction(message2);
22474
+ const transaction = new import_web334.VersionedTransaction(message2);
22219
22475
  transaction.sign([hwManager]);
22220
22476
  if (!this.client.skipSimulation) {
22221
22477
  const simulation = await connection.simulateTransaction(transaction, {
@@ -22261,9 +22517,9 @@ var IdleLiquidityService = class {
22261
22517
 
22262
22518
  // src/services/timelockSettlementService.ts
22263
22519
  var import_kit17 = require("@solana/kit");
22264
- var import_web334 = require("@solana/web3.js");
22265
- var import_common58 = __toESM(require_dist());
22266
- var ZERO_PUBKEY = import_web334.PublicKey.default.toBase58();
22520
+ var import_web335 = require("@solana/web3.js");
22521
+ var import_common59 = __toESM(require_dist());
22522
+ var ZERO_PUBKEY = import_web335.PublicKey.default.toBase58();
22267
22523
  var CONSENSUS_SIGNER_CAPACITY = 4;
22268
22524
  var CONSENSUS_ENTRY_OFFSET = 40;
22269
22525
  var CONSENSUS_ENTRY_SIZE = 272;
@@ -22303,7 +22559,7 @@ function decodePendingConsensusSigners(data) {
22303
22559
  const signers = [];
22304
22560
  for (let i = 0; i < count; i += 1) {
22305
22561
  const start = CONSENSUS_PENDING_OFFSET + i * 32;
22306
- const signer = new import_web334.PublicKey(bytes.slice(start, start + 32)).toBase58();
22562
+ const signer = new import_web335.PublicKey(bytes.slice(start, start + 32)).toBase58();
22307
22563
  if (signer === ZERO_PUBKEY) {
22308
22564
  throw new Error(`pending consensus signer ${i} is unset`);
22309
22565
  }
@@ -22359,7 +22615,7 @@ var TimelockSettlementService = class {
22359
22615
  });
22360
22616
  const dryRun = opts.dryRun ?? false;
22361
22617
  const now = opts.now ?? await this.chainTime();
22362
- const fulfillerAddress = (0, import_common58.fromWeb3Pk)(fulfiller.publicKey);
22618
+ const fulfillerAddress = (0, import_common59.fromWeb3Pk)(fulfiller.publicKey);
22363
22619
  const allVaults = opts.vault ? [
22364
22620
  {
22365
22621
  publicKey: opts.vault,
@@ -22502,18 +22758,18 @@ var TimelockSettlementService = class {
22502
22758
 
22503
22759
  // src/services/nestWithdrawalService.ts
22504
22760
  var import_kit18 = require("@solana/kit");
22505
- var import_spl_token21 = require("@solana/spl-token");
22506
- var import_web335 = require("@solana/web3.js");
22507
- var import_common59 = __toESM(require_dist());
22508
- var import_nest3 = __toESM(require_dist4());
22509
- var import_nest4 = __toESM(require_dist4());
22510
- var NestOftProgram = new import_web335.PublicKey(
22761
+ var import_spl_token22 = require("@solana/spl-token");
22762
+ var import_web336 = require("@solana/web3.js");
22763
+ var import_common60 = __toESM(require_dist());
22764
+ var import_nest3 = __toESM(require_dist3());
22765
+ var import_nest4 = __toESM(require_dist3());
22766
+ var NestOftProgram = new import_web336.PublicKey(
22511
22767
  "ChEfPd3RzLeYiRwp1K9evimmaFSd6DV1S4Mv5q5Aj1th"
22512
22768
  );
22513
- var NestOftStore = new import_web335.PublicKey(
22769
+ var NestOftStore = new import_web336.PublicKey(
22514
22770
  "k8mJj8Gyw2gFAqut21AFVUUZhxb4RVDMnb4PrSYiDhV"
22515
22771
  );
22516
- var UsdcMint = new import_web335.PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
22772
+ var UsdcMint = new import_web336.PublicKey("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v");
22517
22773
  var NestPerenaComposer = Buffer.from(
22518
22774
  "000000000000000000000000908dcb5531691c2124c54e30bb645cf11647090d",
22519
22775
  "hex"
@@ -22530,7 +22786,7 @@ async function buildNestWithdrawalRequest(args) {
22530
22786
  return decodeNestWithdrawalRequest({ ...args, txBase64 });
22531
22787
  }
22532
22788
  async function decodeNestWithdrawalRequest(args) {
22533
- const transaction = import_web335.VersionedTransaction.deserialize(
22789
+ const transaction = import_web336.VersionedTransaction.deserialize(
22534
22790
  Buffer.from(args.txBase64, "base64")
22535
22791
  );
22536
22792
  const message2 = transaction.message;
@@ -22551,19 +22807,19 @@ async function decodeNestWithdrawalRequest(args) {
22551
22807
  return value;
22552
22808
  })
22553
22809
  );
22554
- const decoded = import_web335.TransactionMessage.decompile(message2, {
22810
+ const decoded = import_web336.TransactionMessage.decompile(message2, {
22555
22811
  addressLookupTableAccounts: tables
22556
22812
  });
22557
- const nestMint = new import_web335.PublicKey(NEST_RWA_SHARE_MINT);
22558
- const sourceAta = (0, import_spl_token21.getAssociatedTokenAddressSync)(nestMint, args.owner, true);
22559
- const usdcAta = (0, import_spl_token21.getAssociatedTokenAddressSync)(UsdcMint, args.owner, true);
22813
+ const nestMint = new import_web336.PublicKey(NEST_RWA_SHARE_MINT);
22814
+ const sourceAta = (0, import_spl_token22.getAssociatedTokenAddressSync)(nestMint, args.owner, true);
22815
+ const usdcAta = (0, import_spl_token22.getAssociatedTokenAddressSync)(UsdcMint, args.owner, true);
22560
22816
  const instructions2 = decoded.instructions.filter(
22561
- (ix) => !ix.programId.equals(import_web335.ComputeBudgetProgram.programId)
22817
+ (ix) => !ix.programId.equals(import_web336.ComputeBudgetProgram.programId)
22562
22818
  );
22563
22819
  let sends = 0;
22564
22820
  for (const ix of instructions2) {
22565
- if (ix.programId.equals(import_spl_token21.ASSOCIATED_TOKEN_PROGRAM_ID)) {
22566
- if (ix.data.length !== 1 || ix.data[0] !== 1 || !ix.keys[0]?.pubkey.equals(args.owner) || !ix.keys[1]?.pubkey.equals(usdcAta) || !ix.keys[2]?.pubkey.equals(args.owner) || !ix.keys[3]?.pubkey.equals(UsdcMint) || !ix.keys[5]?.pubkey.equals(import_spl_token21.TOKEN_PROGRAM_ID)) {
22821
+ if (ix.programId.equals(import_spl_token22.ASSOCIATED_TOKEN_PROGRAM_ID)) {
22822
+ if (ix.data.length !== 1 || ix.data[0] !== 1 || !ix.keys[0]?.pubkey.equals(args.owner) || !ix.keys[1]?.pubkey.equals(usdcAta) || !ix.keys[2]?.pubkey.equals(args.owner) || !ix.keys[3]?.pubkey.equals(UsdcMint) || !ix.keys[5]?.pubkey.equals(import_spl_token22.TOKEN_PROGRAM_ID)) {
22567
22823
  throw new Error("Unexpected token account creation in Nest withdrawal");
22568
22824
  }
22569
22825
  continue;
@@ -22580,13 +22836,13 @@ async function decodeNestWithdrawalRequest(args) {
22580
22836
  if (sends !== 1)
22581
22837
  throw new Error("Nest withdrawal must contain exactly one OFT send");
22582
22838
  return {
22583
- instructions: instructions2.map(import_common59.toKitInstruction),
22839
+ instructions: instructions2.map(import_common60.toKitInstruction),
22584
22840
  lookupTables: tables.map((table) => (0, import_kit18.address)(table.key.toBase58()))
22585
22841
  };
22586
22842
  }
22587
22843
 
22588
22844
  // src/index.ts
22589
- var import_common60 = __toESM(require_dist());
22845
+ var import_common61 = __toESM(require_dist());
22590
22846
  // Annotate the CommonJS export names for ESM import in node:
22591
22847
  0 && (module.exports = {
22592
22848
  ASSET_DECIMALS,
@@ -22651,6 +22907,8 @@ var import_common60 = __toESM(require_dist());
22651
22907
  LOCAL_PROTOCOL_ADMIN,
22652
22908
  LargeBalanceChangeError,
22653
22909
  LivePriceSource,
22910
+ MANAGER_WALLET_NAV_DROP_TRIGGER_BPS,
22911
+ MANAGER_WALLET_NAV_TOLERANCE_BPS,
22654
22912
  MAX_APY_ANCHOR_WINDOW_SECS,
22655
22913
  MAX_BALANCE_CHANGE_BPS,
22656
22914
  MAX_CONSENSUS_SIGNERS,
@@ -22683,6 +22941,7 @@ var import_common60 = __toESM(require_dist());
22683
22941
  RemoveAssetHoldingBuilder,
22684
22942
  ReportIncentiveV3Builder,
22685
22943
  RequestJuniorTrancheWithdrawBuilder,
22944
+ RpcManagerWalletBalanceSource,
22686
22945
  SHARE_DECIMALS,
22687
22946
  SYSTEM_PROGRAM,
22688
22947
  SetAssetPriceOracleBuilder,
@@ -22733,6 +22992,7 @@ var import_common60 = __toESM(require_dist());
22733
22992
  buildMarginfiWithdrawInteraction,
22734
22993
  buildNestWithdrawalRequest,
22735
22994
  buildUpdates,
22995
+ candidateGrossNav,
22736
22996
  coerceBool,
22737
22997
  collectSamples,
22738
22998
  confirmYieldPayment,
@@ -22791,6 +23051,7 @@ var import_common60 = __toESM(require_dist());
22791
23051
  loadKeypair,
22792
23052
  logProspectiveApy,
22793
23053
  makeProvider,
23054
+ managerReconciliationStateKey,
22794
23055
  mintTokensTo,
22795
23056
  mints,
22796
23057
  mostFrequent,
@@ -22798,9 +23059,11 @@ var import_common60 = __toESM(require_dist());
22798
23059
  planRebalance,
22799
23060
  prepareSquadsProposalUpload,
22800
23061
  prepareVaultTransaction,
23062
+ previousPhysicalNav,
22801
23063
  priceInAccountingUnit,
22802
23064
  readI64LE,
22803
23065
  readSplMintSupply,
23066
+ reconcileManagerWalletBalances,
22804
23067
  refreshLiveOraclePrices,
22805
23068
  resolveExternalWithdraw,
22806
23069
  resolveKeypairPath,