perena-vault-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +396 -0
- package/dist/client/account.d.ts +59 -0
- package/dist/client/account.d.ts.map +1 -0
- package/dist/client/account.js +94 -0
- package/dist/client/account.js.map +1 -0
- package/dist/client/builders/activateCircuitBreaker.d.ts +12 -0
- package/dist/client/builders/activateCircuitBreaker.d.ts.map +1 -0
- package/dist/client/builders/activateCircuitBreaker.js +27 -0
- package/dist/client/builders/activateCircuitBreaker.js.map +1 -0
- package/dist/client/builders/anchorArgs.d.ts +59 -0
- package/dist/client/builders/anchorArgs.d.ts.map +1 -0
- package/dist/client/builders/anchorArgs.js +43 -0
- package/dist/client/builders/anchorArgs.js.map +1 -0
- package/dist/client/builders/args.d.ts +754 -0
- package/dist/client/builders/args.d.ts.map +1 -0
- package/dist/client/builders/args.js +3 -0
- package/dist/client/builders/args.js.map +1 -0
- package/dist/client/builders/base.d.ts +10 -0
- package/dist/client/builders/base.d.ts.map +1 -0
- package/dist/client/builders/base.js +20 -0
- package/dist/client/builders/base.js.map +1 -0
- package/dist/client/builders/cancelJuniorTrancheWithdraw.d.ts +13 -0
- package/dist/client/builders/cancelJuniorTrancheWithdraw.d.ts.map +1 -0
- package/dist/client/builders/cancelJuniorTrancheWithdraw.js +57 -0
- package/dist/client/builders/cancelJuniorTrancheWithdraw.js.map +1 -0
- package/dist/client/builders/crankNav.d.ts +29 -0
- package/dist/client/builders/crankNav.d.ts.map +1 -0
- package/dist/client/builders/crankNav.js +88 -0
- package/dist/client/builders/crankNav.js.map +1 -0
- package/dist/client/builders/crankPerformanceFees.d.ts +19 -0
- package/dist/client/builders/crankPerformanceFees.d.ts.map +1 -0
- package/dist/client/builders/crankPerformanceFees.js +80 -0
- package/dist/client/builders/crankPerformanceFees.js.map +1 -0
- package/dist/client/builders/createAssetHolding.d.ts +13 -0
- package/dist/client/builders/createAssetHolding.d.ts.map +1 -0
- package/dist/client/builders/createAssetHolding.js +47 -0
- package/dist/client/builders/createAssetHolding.js.map +1 -0
- package/dist/client/builders/createTrancheState.d.ts +13 -0
- package/dist/client/builders/createTrancheState.d.ts.map +1 -0
- package/dist/client/builders/createTrancheState.js +57 -0
- package/dist/client/builders/createTrancheState.js.map +1 -0
- package/dist/client/builders/createVault.d.ts +9 -0
- package/dist/client/builders/createVault.d.ts.map +1 -0
- package/dist/client/builders/createVault.js +75 -0
- package/dist/client/builders/createVault.js.map +1 -0
- package/dist/client/builders/disableCircuitBreaker.d.ts +12 -0
- package/dist/client/builders/disableCircuitBreaker.d.ts.map +1 -0
- package/dist/client/builders/disableCircuitBreaker.js +27 -0
- package/dist/client/builders/disableCircuitBreaker.js.map +1 -0
- package/dist/client/builders/executeDeposit.d.ts +15 -0
- package/dist/client/builders/executeDeposit.d.ts.map +1 -0
- package/dist/client/builders/executeDeposit.js +86 -0
- package/dist/client/builders/executeDeposit.js.map +1 -0
- package/dist/client/builders/executeTrancheDeposit.d.ts +16 -0
- package/dist/client/builders/executeTrancheDeposit.d.ts.map +1 -0
- package/dist/client/builders/executeTrancheDeposit.js +84 -0
- package/dist/client/builders/executeTrancheDeposit.js.map +1 -0
- package/dist/client/builders/executeTrancheWithdraw.d.ts +16 -0
- package/dist/client/builders/executeTrancheWithdraw.d.ts.map +1 -0
- package/dist/client/builders/executeTrancheWithdraw.js +83 -0
- package/dist/client/builders/executeTrancheWithdraw.js.map +1 -0
- package/dist/client/builders/executeWithdraw.d.ts +14 -0
- package/dist/client/builders/executeWithdraw.d.ts.map +1 -0
- package/dist/client/builders/executeWithdraw.js +86 -0
- package/dist/client/builders/executeWithdraw.js.map +1 -0
- package/dist/client/builders/feeCollector.d.ts +17 -0
- package/dist/client/builders/feeCollector.d.ts.map +1 -0
- package/dist/client/builders/feeCollector.js +66 -0
- package/dist/client/builders/feeCollector.js.map +1 -0
- package/dist/client/builders/fulfillJuniorTrancheWithdraw.d.ts +14 -0
- package/dist/client/builders/fulfillJuniorTrancheWithdraw.d.ts.map +1 -0
- package/dist/client/builders/fulfillJuniorTrancheWithdraw.js +82 -0
- package/dist/client/builders/fulfillJuniorTrancheWithdraw.js.map +1 -0
- package/dist/client/builders/index.d.ts +31 -0
- package/dist/client/builders/index.d.ts.map +1 -0
- package/dist/client/builders/index.js +47 -0
- package/dist/client/builders/index.js.map +1 -0
- package/dist/client/builders/initializeVaultRoles.d.ts +12 -0
- package/dist/client/builders/initializeVaultRoles.d.ts.map +1 -0
- package/dist/client/builders/initializeVaultRoles.js +37 -0
- package/dist/client/builders/initializeVaultRoles.js.map +1 -0
- package/dist/client/builders/managerRedepositAsset.d.ts +12 -0
- package/dist/client/builders/managerRedepositAsset.d.ts.map +1 -0
- package/dist/client/builders/managerRedepositAsset.js +52 -0
- package/dist/client/builders/managerRedepositAsset.js.map +1 -0
- package/dist/client/builders/managerWithdrawAsset.d.ts +12 -0
- package/dist/client/builders/managerWithdrawAsset.d.ts.map +1 -0
- package/dist/client/builders/managerWithdrawAsset.js +47 -0
- package/dist/client/builders/managerWithdrawAsset.js.map +1 -0
- package/dist/client/builders/protocolInteraction.d.ts +22 -0
- package/dist/client/builders/protocolInteraction.d.ts.map +1 -0
- package/dist/client/builders/protocolInteraction.js +157 -0
- package/dist/client/builders/protocolInteraction.js.map +1 -0
- package/dist/client/builders/removeAssetHolding.d.ts +13 -0
- package/dist/client/builders/removeAssetHolding.d.ts.map +1 -0
- package/dist/client/builders/removeAssetHolding.js +37 -0
- package/dist/client/builders/removeAssetHolding.js.map +1 -0
- package/dist/client/builders/requestJuniorTrancheWithdraw.d.ts +14 -0
- package/dist/client/builders/requestJuniorTrancheWithdraw.d.ts.map +1 -0
- package/dist/client/builders/requestJuniorTrancheWithdraw.js +72 -0
- package/dist/client/builders/requestJuniorTrancheWithdraw.js.map +1 -0
- package/dist/client/builders/setAssetPriceOracle.d.ts +12 -0
- package/dist/client/builders/setAssetPriceOracle.d.ts.map +1 -0
- package/dist/client/builders/setAssetPriceOracle.js +40 -0
- package/dist/client/builders/setAssetPriceOracle.js.map +1 -0
- package/dist/client/builders/setExternalLiquidity.d.ts +12 -0
- package/dist/client/builders/setExternalLiquidity.d.ts.map +1 -0
- package/dist/client/builders/setExternalLiquidity.js +49 -0
- package/dist/client/builders/setExternalLiquidity.js.map +1 -0
- package/dist/client/builders/setProtocolFee.d.ts +12 -0
- package/dist/client/builders/setProtocolFee.d.ts.map +1 -0
- package/dist/client/builders/setProtocolFee.js +37 -0
- package/dist/client/builders/setProtocolFee.js.map +1 -0
- package/dist/client/builders/setVaultConfig.d.ts +12 -0
- package/dist/client/builders/setVaultConfig.d.ts.map +1 -0
- package/dist/client/builders/setVaultConfig.js +54 -0
- package/dist/client/builders/setVaultConfig.js.map +1 -0
- package/dist/client/builders/trancheState.d.ts +28 -0
- package/dist/client/builders/trancheState.d.ts.map +1 -0
- package/dist/client/builders/trancheState.js +75 -0
- package/dist/client/builders/trancheState.js.map +1 -0
- package/dist/client/builders/updateAssetPrice.d.ts +18 -0
- package/dist/client/builders/updateAssetPrice.d.ts.map +1 -0
- package/dist/client/builders/updateAssetPrice.js +50 -0
- package/dist/client/builders/updateAssetPrice.js.map +1 -0
- package/dist/client/builders/updateConsensusOracle.d.ts +20 -0
- package/dist/client/builders/updateConsensusOracle.d.ts.map +1 -0
- package/dist/client/builders/updateConsensusOracle.js +64 -0
- package/dist/client/builders/updateConsensusOracle.js.map +1 -0
- package/dist/client/builders/updateConsensusSigners.d.ts +13 -0
- package/dist/client/builders/updateConsensusSigners.d.ts.map +1 -0
- package/dist/client/builders/updateConsensusSigners.js +38 -0
- package/dist/client/builders/updateConsensusSigners.js.map +1 -0
- package/dist/client/builders/updateTrancheConfig.d.ts +13 -0
- package/dist/client/builders/updateTrancheConfig.d.ts.map +1 -0
- package/dist/client/builders/updateTrancheConfig.js +50 -0
- package/dist/client/builders/updateTrancheConfig.js.map +1 -0
- package/dist/client/builders/vaultReallocation.d.ts +15 -0
- package/dist/client/builders/vaultReallocation.d.ts.map +1 -0
- package/dist/client/builders/vaultReallocation.js +148 -0
- package/dist/client/builders/vaultReallocation.js.map +1 -0
- package/dist/client/client.d.ts +34 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +75 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/index.d.ts +8 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +24 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/pda.d.ts +42 -0
- package/dist/client/pda.d.ts.map +1 -0
- package/dist/client/pda.js +88 -0
- package/dist/client/pda.js.map +1 -0
- package/dist/client/transaction.d.ts +36 -0
- package/dist/client/transaction.d.ts.map +1 -0
- package/dist/client/transaction.js +39 -0
- package/dist/client/transaction.js.map +1 -0
- package/dist/client/types/builders.d.ts +12 -0
- package/dist/client/types/builders.d.ts.map +1 -0
- package/dist/client/types/builders.js +3 -0
- package/dist/client/types/builders.js.map +1 -0
- package/dist/client/types/tx.d.ts +13 -0
- package/dist/client/types/tx.d.ts.map +1 -0
- package/dist/client/types/tx.js +3 -0
- package/dist/client/types/tx.js.map +1 -0
- package/dist/constants.d.ts +45 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +49 -0
- package/dist/constants.js.map +1 -0
- package/dist/env.d.ts +70 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +117 -0
- package/dist/env.js.map +1 -0
- package/dist/idl/index.d.ts +3 -0
- package/dist/idl/index.d.ts.map +1 -0
- package/dist/idl/index.js +6 -0
- package/dist/idl/index.js.map +1 -0
- package/dist/idl/vault.d.ts +9617 -0
- package/dist/idl/vault.d.ts.map +1 -0
- package/dist/idl/vault.js +7917 -0
- package/dist/idl/vault.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/services/consensusOracle/consensusOracleService.d.ts +38 -0
- package/dist/services/consensusOracle/consensusOracleService.d.ts.map +1 -0
- package/dist/services/consensusOracle/consensusOracleService.js +270 -0
- package/dist/services/consensusOracle/consensusOracleService.js.map +1 -0
- package/dist/services/consensusOracle/externalPositions.d.ts +26 -0
- package/dist/services/consensusOracle/externalPositions.d.ts.map +1 -0
- package/dist/services/consensusOracle/externalPositions.js +37 -0
- package/dist/services/consensusOracle/externalPositions.js.map +1 -0
- package/dist/services/consensusOracle/index.d.ts +7 -0
- package/dist/services/consensusOracle/index.d.ts.map +1 -0
- package/dist/services/consensusOracle/index.js +23 -0
- package/dist/services/consensusOracle/index.js.map +1 -0
- package/dist/services/consensusOracle/jupiterBalanceSource.d.ts +34 -0
- package/dist/services/consensusOracle/jupiterBalanceSource.d.ts.map +1 -0
- package/dist/services/consensusOracle/jupiterBalanceSource.js +80 -0
- package/dist/services/consensusOracle/jupiterBalanceSource.js.map +1 -0
- package/dist/services/consensusOracle/jupiterPriceSource.d.ts +25 -0
- package/dist/services/consensusOracle/jupiterPriceSource.d.ts.map +1 -0
- package/dist/services/consensusOracle/jupiterPriceSource.js +63 -0
- package/dist/services/consensusOracle/jupiterPriceSource.js.map +1 -0
- package/dist/services/consensusOracle/mockYieldTracker.d.ts +44 -0
- package/dist/services/consensusOracle/mockYieldTracker.d.ts.map +1 -0
- package/dist/services/consensusOracle/mockYieldTracker.js +107 -0
- package/dist/services/consensusOracle/mockYieldTracker.js.map +1 -0
- package/dist/services/consensusOracle/types.d.ts +180 -0
- package/dist/services/consensusOracle/types.d.ts.map +1 -0
- package/dist/services/consensusOracle/types.js +5 -0
- package/dist/services/consensusOracle/types.js.map +1 -0
- package/dist/services/index.d.ts +4 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +20 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/oracleService.d.ts +72 -0
- package/dist/services/oracleService.d.ts.map +1 -0
- package/dist/services/oracleService.js +93 -0
- package/dist/services/oracleService.js.map +1 -0
- package/dist/services/withdrawalQueueService.d.ts +76 -0
- package/dist/services/withdrawalQueueService.d.ts.map +1 -0
- package/dist/services/withdrawalQueueService.js +138 -0
- package/dist/services/withdrawalQueueService.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +20 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/provider.d.ts +4 -0
- package/dist/utils/provider.d.ts.map +1 -0
- package/dist/utils/provider.js +10 -0
- package/dist/utils/provider.js.map +1 -0
- package/dist/utils/rpc.d.ts +4 -0
- package/dist/utils/rpc.d.ts.map +1 -0
- package/dist/utils/rpc.js +8 -0
- package/dist/utils/rpc.js.map +1 -0
- package/dist/utils/token.d.ts +6 -0
- package/dist/utils/token.d.ts.map +1 -0
- package/dist/utils/token.js +32 -0
- package/dist/utils/token.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConsensusOracleService = void 0;
|
|
4
|
+
const common_1 = require("common");
|
|
5
|
+
const oracleService_1 = require("../oracleService");
|
|
6
|
+
const types_1 = require("./types");
|
|
7
|
+
const SYSTEM_PROGRAM = "11111111111111111111111111111111";
|
|
8
|
+
const CONSENSUS_ORACLE_VARIANT = "consensusoracle";
|
|
9
|
+
// ── Pure helpers ───────────────────────────────────────────────────────────
|
|
10
|
+
/** Name of an Anchor enum variant, e.g. `{ consensusOracle: {} }` → "consensusOracle". */
|
|
11
|
+
function variantName(value) {
|
|
12
|
+
if (value && typeof value === "object")
|
|
13
|
+
return Object.keys(value)[0] ?? "";
|
|
14
|
+
return String(value ?? "");
|
|
15
|
+
}
|
|
16
|
+
/** Decode a PodBool (which arrives in a few shapes depending on the codec). */
|
|
17
|
+
function coerceBool(value) {
|
|
18
|
+
if (typeof value === "boolean")
|
|
19
|
+
return value;
|
|
20
|
+
if (typeof value === "number")
|
|
21
|
+
return value !== 0;
|
|
22
|
+
const record = value;
|
|
23
|
+
return Boolean(record?.value ?? record?.[0]);
|
|
24
|
+
}
|
|
25
|
+
/** Re-denominate a USD price into the vault's accounting unit, fixed-point. */
|
|
26
|
+
function priceInAccountingUnit(usd, baseUsd, assetDecimals) {
|
|
27
|
+
return BigInt(Math.round((usd / baseUsd) * 10 ** assetDecimals));
|
|
28
|
+
}
|
|
29
|
+
/** Sum external positions by mint (base58 → base units). */
|
|
30
|
+
function sumPositionsByMint(positions) {
|
|
31
|
+
const byMint = new Map();
|
|
32
|
+
for (const pos of positions) {
|
|
33
|
+
const key = pos.mint.toString();
|
|
34
|
+
byMint.set(key, (byMint.get(key) ?? 0n) + pos.amount);
|
|
35
|
+
}
|
|
36
|
+
return byMint;
|
|
37
|
+
}
|
|
38
|
+
/** Index per-holding config by mint (base58). */
|
|
39
|
+
function indexConfigByMint(holdings = []) {
|
|
40
|
+
return new Map(holdings.map((cfg) => [cfg.mint.toString(), cfg]));
|
|
41
|
+
}
|
|
42
|
+
class ConsensusOracleService {
|
|
43
|
+
constructor(client, deps) {
|
|
44
|
+
this.client = client;
|
|
45
|
+
this.deps = deps;
|
|
46
|
+
this.oracle = new oracleService_1.OracleService(client);
|
|
47
|
+
this.clock = deps.clock ?? types_1.systemClock;
|
|
48
|
+
}
|
|
49
|
+
/** Drive one vault: source prices/balances, push consensus update, crank NAV. */
|
|
50
|
+
async runOnce(signer, target, opts = {}) {
|
|
51
|
+
const log = opts.log ?? (() => { });
|
|
52
|
+
const dryRun = opts.dryRun ?? false;
|
|
53
|
+
const vaultState = await this.fetchDecodedVault(target.vault);
|
|
54
|
+
const consensusHoldings = selectConsensusHoldings(vaultState.holdings);
|
|
55
|
+
if (consensusHoldings.length === 0) {
|
|
56
|
+
log(`vault ${target.vault}: no consensus holdings, skipping`);
|
|
57
|
+
return { vault: target.vault, updates: [], dryRun };
|
|
58
|
+
}
|
|
59
|
+
const inputs = await this.gatherPricingInputs(target, vaultState, consensusHoldings);
|
|
60
|
+
const updates = await this.buildUpdates(consensusHoldings, inputs);
|
|
61
|
+
if (dryRun) {
|
|
62
|
+
log(`vault ${target.vault}: dry run, ${updates.length} holding(s)`);
|
|
63
|
+
return { vault: target.vault, updates, dryRun: true };
|
|
64
|
+
}
|
|
65
|
+
const { updateSignature, crankSignature } = await this.settleVault(signer, target.vault, updates, log);
|
|
66
|
+
return {
|
|
67
|
+
vault: target.vault,
|
|
68
|
+
updates,
|
|
69
|
+
dryRun: false,
|
|
70
|
+
updateSignature,
|
|
71
|
+
crankSignature,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Drive several vaults in sequence. Non-fatal: a failure on one vault is
|
|
76
|
+
* recorded and the rest still run (mirrors the oracle-updater daemon).
|
|
77
|
+
*/
|
|
78
|
+
async run(signer, targets, opts = {}) {
|
|
79
|
+
const log = opts.log ?? (() => { });
|
|
80
|
+
const results = [];
|
|
81
|
+
const failures = [];
|
|
82
|
+
for (const target of targets) {
|
|
83
|
+
try {
|
|
84
|
+
results.push(await this.runOnce(signer, target, opts));
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
88
|
+
log(`FAILED vault ${target.vault}: ${error}`);
|
|
89
|
+
failures.push({ vault: target.vault, error });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
total: targets.length,
|
|
94
|
+
failed: failures.length,
|
|
95
|
+
results,
|
|
96
|
+
failures,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Discover all on-chain vaults for which `signer` is a registered consensus
|
|
101
|
+
* oracle signer. Fetches every vault and its oracle account, then filters by
|
|
102
|
+
* signer membership. Returns minimal `ConsensusOracleTarget` entries (no
|
|
103
|
+
* per-holding config); callers can overlay config from `targets.ts` if needed.
|
|
104
|
+
*/
|
|
105
|
+
async discoverVaultsForSigner(signer, opts = {}) {
|
|
106
|
+
const log = opts.log ?? (() => { });
|
|
107
|
+
const signerBytes = signer.publicKey.toBytes();
|
|
108
|
+
const allVaults = await this.client.account.fetchAllVaults({ fresh: true });
|
|
109
|
+
log(`Discovered ${allVaults.length} vault(s) on-chain, checking oracle membership…`);
|
|
110
|
+
const results = [];
|
|
111
|
+
await Promise.all(allVaults.map(async ({ publicKey: vault }) => {
|
|
112
|
+
try {
|
|
113
|
+
const oracle = await this.client.account.fetchVaultOracleForVault(vault);
|
|
114
|
+
const data = oracle.data;
|
|
115
|
+
if (signerInOracleData(data, signerBytes)) {
|
|
116
|
+
log(` ${vault}: signer is registered oracle`);
|
|
117
|
+
results.push({ vault });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Vault oracle may not exist yet; skip silently.
|
|
122
|
+
}
|
|
123
|
+
}));
|
|
124
|
+
return results;
|
|
125
|
+
}
|
|
126
|
+
// ── Sourcing ───────────────────────────────────────────────────────────────
|
|
127
|
+
async fetchDecodedVault(vault) {
|
|
128
|
+
return (await this.client.account.fetchVault(vault, {
|
|
129
|
+
fresh: true,
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
/** Fetch every external input the per-holding updates draw on, in parallel-ish. */
|
|
133
|
+
async gatherPricingInputs(target, vaultState, consensusHoldings) {
|
|
134
|
+
const manager = (0, common_1.fromWeb3Pk)(vaultState.roles.manager);
|
|
135
|
+
const holdingMints = consensusHoldings.map(({ holding }) => (0, common_1.fromWeb3Pk)(holding.mint));
|
|
136
|
+
// Derive the base mint from the holding flagged isBase — the strictAssetMint
|
|
137
|
+
// field on VaultConfig is reserved/deprecated.
|
|
138
|
+
const baseHolding = vaultState.holdings.find((h) => coerceBool(h.isBase));
|
|
139
|
+
const baseMint = baseHolding
|
|
140
|
+
? (0, common_1.fromWeb3Pk)(baseHolding.mint)
|
|
141
|
+
: holdingMints[0];
|
|
142
|
+
if (!baseMint) {
|
|
143
|
+
throw new Error(`vault has no holdings — cannot determine base asset`);
|
|
144
|
+
}
|
|
145
|
+
const mintsToPrice = holdingMints.includes(baseMint)
|
|
146
|
+
? holdingMints
|
|
147
|
+
: [...holdingMints, baseMint];
|
|
148
|
+
const usdPrices = await this.deps.priceSource.fetchUsdPrices(mintsToPrice);
|
|
149
|
+
const baseUsd = usdPrices[baseMint.toString()];
|
|
150
|
+
if (!baseUsd) {
|
|
151
|
+
throw new Error(`no USD price for base asset ${baseMint} (cannot denominate prices)`);
|
|
152
|
+
}
|
|
153
|
+
const walletBalances = await this.deps.balanceSource.fetchBalances(manager);
|
|
154
|
+
const lpByMint = await this.fetchExternalPositions(target, manager);
|
|
155
|
+
return {
|
|
156
|
+
assetDecimals: vaultState.config.assetDecimals,
|
|
157
|
+
baseUsd,
|
|
158
|
+
usdPrices,
|
|
159
|
+
walletBalances,
|
|
160
|
+
lpByMint,
|
|
161
|
+
configByMint: indexConfigByMint(target.holdings),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/** Live-LP balances for the target, summed by mint (empty if no provider). */
|
|
165
|
+
async fetchExternalPositions(target, manager) {
|
|
166
|
+
if (!this.deps.externalPositions)
|
|
167
|
+
return new Map();
|
|
168
|
+
const refs = (target.holdings ?? []).flatMap((cfg) => cfg.externalPositions ?? []);
|
|
169
|
+
const positions = await this.deps.externalPositions.positionsFor({
|
|
170
|
+
vault: target.vault,
|
|
171
|
+
manager,
|
|
172
|
+
refs,
|
|
173
|
+
});
|
|
174
|
+
return sumPositionsByMint(positions);
|
|
175
|
+
}
|
|
176
|
+
/** Accrued yield (base units) attributed to a holding via its configured accounts. */
|
|
177
|
+
async resolveYieldAmount(cfg, decimals) {
|
|
178
|
+
if (!this.deps.yieldTracker || !cfg?.yieldAccountNames?.length)
|
|
179
|
+
return 0n;
|
|
180
|
+
const totalYieldUi = await this.deps.yieldTracker.getTotalYield(cfg.yieldAccountNames);
|
|
181
|
+
return totalYieldUi > 0 ? (0, common_1.fromUiAmount)(totalYieldUi, decimals) : 0n;
|
|
182
|
+
}
|
|
183
|
+
// ── Aggregation ──────────────────────────────────────────────────────────────
|
|
184
|
+
async buildUpdates(consensusHoldings, inputs) {
|
|
185
|
+
const updates = [];
|
|
186
|
+
for (const entry of consensusHoldings) {
|
|
187
|
+
updates.push(await this.buildHoldingUpdate(entry, inputs));
|
|
188
|
+
}
|
|
189
|
+
return updates;
|
|
190
|
+
}
|
|
191
|
+
async buildHoldingUpdate(entry, inputs) {
|
|
192
|
+
const { holding, holdingIndex } = entry;
|
|
193
|
+
const mint = (0, common_1.fromWeb3Pk)(holding.mint);
|
|
194
|
+
const mintKey = mint.toString();
|
|
195
|
+
const usd = coerceBool(holding.isBase)
|
|
196
|
+
? inputs.baseUsd
|
|
197
|
+
: inputs.usdPrices[mintKey];
|
|
198
|
+
if (!usd) {
|
|
199
|
+
throw new Error(`no USD price for holding ${mint}`);
|
|
200
|
+
}
|
|
201
|
+
const price = priceInAccountingUnit(usd, inputs.baseUsd, inputs.assetDecimals);
|
|
202
|
+
const walletAmount = inputs.walletBalances[mintKey] ?? 0n;
|
|
203
|
+
const lpAmount = inputs.lpByMint.get(mintKey) ?? 0n;
|
|
204
|
+
const yieldAmount = await this.resolveYieldAmount(inputs.configByMint.get(mintKey), holding.decimals);
|
|
205
|
+
return {
|
|
206
|
+
holdingIndex,
|
|
207
|
+
mint,
|
|
208
|
+
decimals: holding.decimals,
|
|
209
|
+
usdPrice: usd,
|
|
210
|
+
price,
|
|
211
|
+
walletAmount,
|
|
212
|
+
lpAmount,
|
|
213
|
+
yieldAmount,
|
|
214
|
+
externalAmount: walletAmount + lpAmount + yieldAmount,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
// ── Settlement ───────────────────────────────────────────────────────────────
|
|
218
|
+
/** Push the consensus report for all holdings, then settle NAV. */
|
|
219
|
+
async settleVault(signer, vault, updates, log) {
|
|
220
|
+
const updateSignature = await this.oracle.updateAssetConsensusPrice(signer, {
|
|
221
|
+
vault,
|
|
222
|
+
updates: updates.map((u) => ({
|
|
223
|
+
holdingIndex: u.holdingIndex,
|
|
224
|
+
price: u.price,
|
|
225
|
+
externalAmount: u.externalAmount,
|
|
226
|
+
})),
|
|
227
|
+
}, log);
|
|
228
|
+
const crankSignature = await this.oracle.crankNav(signer, { vault }, log);
|
|
229
|
+
return { updateSignature, crankSignature };
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
exports.ConsensusOracleService = ConsensusOracleService;
|
|
233
|
+
// ConsensusOracleData byte layout (C repr, bytemuck, within VaultOracle.data):
|
|
234
|
+
// [0..8) settled_nav
|
|
235
|
+
// [8..16) settled_nav_ts
|
|
236
|
+
// [16..24) previous_settled_nav
|
|
237
|
+
// [24..32) previous_settled_nav_ts
|
|
238
|
+
// [32..40) staleness_threshold_secs
|
|
239
|
+
// [40..) entries[0..4]: each entry is 272 bytes (signer:32 + ts:8 + prices:96 + externals:96 + pad:40)
|
|
240
|
+
const ENTRY_SIZE = 272;
|
|
241
|
+
const ENTRIES_OFFSET = 40;
|
|
242
|
+
const MAX_CONSENSUS_SIGNERS = 4;
|
|
243
|
+
function signerInOracleData(data, signerBytes) {
|
|
244
|
+
const ZERO_PUBKEY = new Uint8Array(32);
|
|
245
|
+
for (let i = 0; i < MAX_CONSENSUS_SIGNERS; i++) {
|
|
246
|
+
const off = ENTRIES_OFFSET + i * ENTRY_SIZE;
|
|
247
|
+
const slice = data.slice(off, off + 32);
|
|
248
|
+
if (slice.length < 32)
|
|
249
|
+
break;
|
|
250
|
+
const bytes = new Uint8Array(slice);
|
|
251
|
+
if (bytes.every((b) => b === 0) ||
|
|
252
|
+
ZERO_PUBKEY.every((_, j) => bytes[j] === ZERO_PUBKEY[j]))
|
|
253
|
+
continue;
|
|
254
|
+
if (signerBytes.every((b, j) => b === bytes[j]))
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
/** Consensus-priced, non-empty holdings, paired with their on-chain slot index. */
|
|
260
|
+
function selectConsensusHoldings(holdings) {
|
|
261
|
+
return holdings
|
|
262
|
+
.map((holding, holdingIndex) => ({ holding, holdingIndex }))
|
|
263
|
+
.filter(({ holding }) => {
|
|
264
|
+
const mint = (0, common_1.fromWeb3Pk)(holding.mint);
|
|
265
|
+
return (mint !== SYSTEM_PROGRAM &&
|
|
266
|
+
variantName(holding.priceOracleType).toLowerCase() ===
|
|
267
|
+
CONSENSUS_ORACLE_VARIANT);
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=consensusOracleService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consensusOracleService.js","sourceRoot":"","sources":["../../../src/services/consensusOracle/consensusOracleService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aggregation of {@link ExternalPositionProvider}s plus a trivial static
|
|
3
|
+
* provider. Concrete live-LP providers (Kamino, Marginfi) wrap protocol SDKs and
|
|
4
|
+
* live in the scripts layer to keep `vault_sdk`'s runtime dependencies lean; the
|
|
5
|
+
* service only ever sees the {@link ExternalPositionProvider} interface.
|
|
6
|
+
*/
|
|
7
|
+
import type { ExternalPosition, ExternalPositionContext, ExternalPositionProvider } from "./types";
|
|
8
|
+
/**
|
|
9
|
+
* Fans a context out to every registered provider and concatenates the results.
|
|
10
|
+
* A provider that throws is logged and contributes no positions, so one bad
|
|
11
|
+
* protocol read never blocks the rest.
|
|
12
|
+
*/
|
|
13
|
+
export declare class ExternalPositionRegistry implements ExternalPositionProvider {
|
|
14
|
+
private readonly log;
|
|
15
|
+
private readonly providers;
|
|
16
|
+
constructor(providers?: ExternalPositionProvider[], log?: (msg: string) => void);
|
|
17
|
+
add(provider: ExternalPositionProvider): this;
|
|
18
|
+
positionsFor(ctx: ExternalPositionContext): Promise<ExternalPosition[]>;
|
|
19
|
+
}
|
|
20
|
+
/** Returns a fixed list of positions; handy for tests and dry runs. */
|
|
21
|
+
export declare class StaticPositionProvider implements ExternalPositionProvider {
|
|
22
|
+
private readonly positions;
|
|
23
|
+
constructor(positions: ExternalPosition[]);
|
|
24
|
+
positionsFor(): Promise<ExternalPosition[]>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=externalPositions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"externalPositions.d.ts","sourceRoot":"","sources":["../../../src/services/consensusOracle/externalPositions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,qBAAa,wBAAyB,YAAW,wBAAwB;IAKrE,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;gBAGrD,SAAS,GAAE,wBAAwB,EAAO,EACzB,GAAG,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAe;IAKxD,GAAG,CAAC,QAAQ,EAAE,wBAAwB,GAAG,IAAI;IAKvC,YAAY,CAChB,GAAG,EAAE,uBAAuB,GAC3B,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAe/B;AAED,uEAAuE;AACvE,qBAAa,sBAAuB,YAAW,wBAAwB;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,gBAAgB,EAAE;IAEpD,YAAY,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAGlD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StaticPositionProvider = exports.ExternalPositionRegistry = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Fans a context out to every registered provider and concatenates the results.
|
|
6
|
+
* A provider that throws is logged and contributes no positions, so one bad
|
|
7
|
+
* protocol read never blocks the rest.
|
|
8
|
+
*/
|
|
9
|
+
class ExternalPositionRegistry {
|
|
10
|
+
constructor(providers = [], log = () => { }) {
|
|
11
|
+
this.log = log;
|
|
12
|
+
this.providers = [...providers];
|
|
13
|
+
}
|
|
14
|
+
add(provider) {
|
|
15
|
+
this.providers.push(provider);
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
async positionsFor(ctx) {
|
|
19
|
+
const results = await Promise.all(this.providers.map((provider) => provider.positionsFor(ctx).catch((err) => {
|
|
20
|
+
this.log(`external-position provider failed for ${ctx.vault}: ${err instanceof Error ? err.message : String(err)}`);
|
|
21
|
+
return [];
|
|
22
|
+
})));
|
|
23
|
+
return results.flat();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.ExternalPositionRegistry = ExternalPositionRegistry;
|
|
27
|
+
/** Returns a fixed list of positions; handy for tests and dry runs. */
|
|
28
|
+
class StaticPositionProvider {
|
|
29
|
+
constructor(positions) {
|
|
30
|
+
this.positions = positions;
|
|
31
|
+
}
|
|
32
|
+
async positionsFor() {
|
|
33
|
+
return this.positions;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.StaticPositionProvider = StaticPositionProvider;
|
|
37
|
+
//# sourceMappingURL=externalPositions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"externalPositions.js","sourceRoot":"","sources":["../../../src/services/consensusOracle/externalPositions.ts"],"names":[],"mappings":";;;AAYA;;;;GAIG;AACH,MAAa,wBAAwB;IAGnC,YACE,YAAwC,EAAE,EACzB,MAA6B,GAAG,EAAE,GAAE,CAAC;QAArC,QAAG,GAAH,GAAG,CAAkC;QAEtD,IAAI,CAAC,SAAS,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,QAAkC;QACpC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,GAA4B;QAE5B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC9B,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACvC,IAAI,CAAC,GAAG,CACN,yCAAyC,GAAG,CAAC,KAAK,KAChD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,EAAE,CACH,CAAC;YACF,OAAO,EAAwB,CAAC;QAClC,CAAC,CAAC,CACH,CACF,CAAC;QACF,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC;CACF;AAhCD,4DAgCC;AAED,uEAAuE;AACvE,MAAa,sBAAsB;IACjC,YAA6B,SAA6B;QAA7B,cAAS,GAAT,SAAS,CAAoB;IAAG,CAAC;IAE9D,KAAK,CAAC,YAAY;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AAND,wDAMC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/consensusOracle/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
__exportStar(require("./jupiterPriceSource"), exports);
|
|
19
|
+
__exportStar(require("./jupiterBalanceSource"), exports);
|
|
20
|
+
__exportStar(require("./externalPositions"), exports);
|
|
21
|
+
__exportStar(require("./mockYieldTracker"), exports);
|
|
22
|
+
__exportStar(require("./consensusOracleService"), exports);
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/consensusOracle/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,uDAAqC;AACrC,yDAAuC;AACvC,sDAAoC;AACpC,qDAAmC;AACnC,2DAAyC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* {@link WalletBalanceSource} backed by the Jupiter "portfolio" / Ultra balances
|
|
3
|
+
* API, with an on-chain RPC fallback.
|
|
4
|
+
*
|
|
5
|
+
* Primary: GET https://lite-api.jup.ag/ultra/v1/balances/{owner}
|
|
6
|
+
* → { "<mint>": { amount, uiAmount, slot, isFrozen }, "SOL": {…} }
|
|
7
|
+
* Fallback: `getParsedTokenAccountsByOwner` over the SPL Token and Token-2022
|
|
8
|
+
* programs, summed per mint.
|
|
9
|
+
*
|
|
10
|
+
* `amount` from Jupiter is already in raw base units, matching the on-chain
|
|
11
|
+
* `external_amount` unit, so no decimal conversion is applied here.
|
|
12
|
+
*/
|
|
13
|
+
import type { Address } from "@solana/kit";
|
|
14
|
+
import { Connection } from "@solana/web3.js";
|
|
15
|
+
import type { WalletBalanceSource } from "./types";
|
|
16
|
+
export interface JupiterBalanceSourceOptions {
|
|
17
|
+
baseUrl?: string;
|
|
18
|
+
fetchFn?: typeof fetch;
|
|
19
|
+
/** Skip the Jupiter call and read straight from RPC. */
|
|
20
|
+
rpcOnly?: boolean;
|
|
21
|
+
log?: (msg: string) => void;
|
|
22
|
+
}
|
|
23
|
+
export declare class JupiterBalanceSource implements WalletBalanceSource {
|
|
24
|
+
private readonly connection;
|
|
25
|
+
private readonly baseUrl;
|
|
26
|
+
private readonly fetchFn;
|
|
27
|
+
private readonly rpcOnly;
|
|
28
|
+
private readonly log;
|
|
29
|
+
constructor(connection: Connection, opts?: JupiterBalanceSourceOptions);
|
|
30
|
+
fetchBalances(owner: Address): Promise<Record<string, bigint>>;
|
|
31
|
+
private fetchFromJupiter;
|
|
32
|
+
private fetchFromRpc;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=jupiterBalanceSource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jupiterBalanceSource.d.ts","sourceRoot":"","sources":["../../../src/services/consensusOracle/jupiterBalanceSource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAa,MAAM,iBAAiB,CAAC;AAIxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAInD,MAAM,WAAW,2BAA2B;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,wDAAwD;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,qBAAa,oBAAqB,YAAW,mBAAmB;IAO5D,OAAO,CAAC,QAAQ,CAAC,UAAU;IAN7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAwB;gBAGzB,UAAU,EAAE,UAAU,EACvC,IAAI,GAAE,2BAAgC;IAQlC,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAgBtD,gBAAgB;YA+BhB,YAAY;CAuB3B"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JupiterBalanceSource = void 0;
|
|
4
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const spl_token_1 = require("@solana/spl-token");
|
|
6
|
+
const common_1 = require("common");
|
|
7
|
+
const DEFAULT_BASE_URL = "https://lite-api.jup.ag/ultra/v1/balances";
|
|
8
|
+
class JupiterBalanceSource {
|
|
9
|
+
constructor(connection, opts = {}) {
|
|
10
|
+
this.connection = connection;
|
|
11
|
+
this.baseUrl = opts.baseUrl ?? DEFAULT_BASE_URL;
|
|
12
|
+
this.fetchFn = opts.fetchFn ?? fetch;
|
|
13
|
+
this.rpcOnly = opts.rpcOnly ?? false;
|
|
14
|
+
this.log = opts.log ?? (() => { });
|
|
15
|
+
}
|
|
16
|
+
async fetchBalances(owner) {
|
|
17
|
+
if (!this.rpcOnly) {
|
|
18
|
+
try {
|
|
19
|
+
const fromJup = await this.fetchFromJupiter(owner);
|
|
20
|
+
if (Object.keys(fromJup).length > 0)
|
|
21
|
+
return fromJup;
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
this.log(`Jupiter balances failed for ${owner}, falling back to RPC: ${err instanceof Error ? err.message : String(err)}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return this.fetchFromRpc(owner);
|
|
28
|
+
}
|
|
29
|
+
async fetchFromJupiter(owner) {
|
|
30
|
+
const res = await this.fetchFn(`${this.baseUrl}/${owner.toString()}`);
|
|
31
|
+
if (!res.ok) {
|
|
32
|
+
throw new Error(`Jupiter balances API ${res.status}`);
|
|
33
|
+
}
|
|
34
|
+
const body = (await res.json());
|
|
35
|
+
if (!body || typeof body !== "object") {
|
|
36
|
+
throw new Error("Jupiter balances API returned a non-object body");
|
|
37
|
+
}
|
|
38
|
+
const out = {};
|
|
39
|
+
for (const [key, value] of Object.entries(body)) {
|
|
40
|
+
// "SOL" is native lamports, not an SPL holding — skip it.
|
|
41
|
+
if (key === "SOL")
|
|
42
|
+
continue;
|
|
43
|
+
if (!value || typeof value !== "object")
|
|
44
|
+
continue;
|
|
45
|
+
const amount = value.amount;
|
|
46
|
+
if (amount === undefined || amount === null)
|
|
47
|
+
continue;
|
|
48
|
+
try {
|
|
49
|
+
const raw = BigInt(String(amount));
|
|
50
|
+
if (raw > 0n)
|
|
51
|
+
out[key] = raw;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// Non-integer amount — ignore this entry.
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return out;
|
|
58
|
+
}
|
|
59
|
+
async fetchFromRpc(owner) {
|
|
60
|
+
const ownerPk = (0, common_1.asWeb3PublicKey)(owner);
|
|
61
|
+
const out = {};
|
|
62
|
+
for (const programId of [spl_token_1.TOKEN_PROGRAM_ID, spl_token_1.TOKEN_2022_PROGRAM_ID]) {
|
|
63
|
+
const { value } = await this.connection.getParsedTokenAccountsByOwner(ownerPk, { programId: new web3_js_1.PublicKey(programId) });
|
|
64
|
+
for (const { account } of value) {
|
|
65
|
+
const info = account.data.parsed
|
|
66
|
+
?.info;
|
|
67
|
+
const mint = info?.mint;
|
|
68
|
+
const amount = info?.tokenAmount?.amount;
|
|
69
|
+
if (!mint || amount === undefined)
|
|
70
|
+
continue;
|
|
71
|
+
const raw = BigInt(amount);
|
|
72
|
+
if (raw > 0n)
|
|
73
|
+
out[mint] = (out[mint] ?? 0n) + raw;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.JupiterBalanceSource = JupiterBalanceSource;
|
|
80
|
+
//# sourceMappingURL=jupiterBalanceSource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jupiterBalanceSource.js","sourceRoot":"","sources":["../../../src/services/consensusOracle/jupiterBalanceSource.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* {@link PriceSource} backed by the Jupiter price API.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the existing feed in `oracle-service/src/feeds/jupiter.ts`
|
|
5
|
+
* (`GET /price/v3`, batched at 50 ids, small retry, reads `usdPrice`) but is
|
|
6
|
+
* self-contained so `vault_sdk` keeps its lean dependency set.
|
|
7
|
+
*/
|
|
8
|
+
import type { Address } from "@solana/kit";
|
|
9
|
+
import type { PriceSource } from "./types";
|
|
10
|
+
export interface JupiterPriceSourceOptions {
|
|
11
|
+
/** Override the price endpoint (e.g. the keyed `api.jup.ag` host). */
|
|
12
|
+
baseUrl?: string;
|
|
13
|
+
/** Retry attempts per batch request. */
|
|
14
|
+
retries?: number;
|
|
15
|
+
/** Injectable fetch (for tests); defaults to global `fetch`. */
|
|
16
|
+
fetchFn?: typeof fetch;
|
|
17
|
+
}
|
|
18
|
+
export declare class JupiterPriceSource implements PriceSource {
|
|
19
|
+
private readonly baseUrl;
|
|
20
|
+
private readonly retries;
|
|
21
|
+
private readonly fetchFn;
|
|
22
|
+
constructor(opts?: JupiterPriceSourceOptions);
|
|
23
|
+
fetchUsdPrices(mints: Address[]): Promise<Record<string, number>>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=jupiterPriceSource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jupiterPriceSource.d.ts","sourceRoot":"","sources":["../../../src/services/consensusOracle/jupiterPriceSource.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAM3C,MAAM,WAAW,yBAAyB;IACxC,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB;AAyBD,qBAAa,kBAAmB,YAAW,WAAW;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;gBAE3B,IAAI,GAAE,yBAA8B;IAM1C,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAiCxE"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JupiterPriceSource = void 0;
|
|
4
|
+
const DEFAULT_BASE_URL = "https://lite-api.jup.ag/price/v3";
|
|
5
|
+
const BATCH_SIZE = 50;
|
|
6
|
+
const DEFAULT_RETRIES = 6;
|
|
7
|
+
function chunk(items, size) {
|
|
8
|
+
const out = [];
|
|
9
|
+
for (let i = 0; i < items.length; i += size) {
|
|
10
|
+
out.push(items.slice(i, i + size));
|
|
11
|
+
}
|
|
12
|
+
return out;
|
|
13
|
+
}
|
|
14
|
+
async function withRetry(fn, attempts) {
|
|
15
|
+
let lastErr;
|
|
16
|
+
for (let i = 0; i < attempts; i += 1) {
|
|
17
|
+
try {
|
|
18
|
+
return await fn();
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
lastErr = err;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
|
|
25
|
+
}
|
|
26
|
+
class JupiterPriceSource {
|
|
27
|
+
constructor(opts = {}) {
|
|
28
|
+
this.baseUrl = opts.baseUrl ?? DEFAULT_BASE_URL;
|
|
29
|
+
this.retries = opts.retries ?? DEFAULT_RETRIES;
|
|
30
|
+
this.fetchFn = opts.fetchFn ?? fetch;
|
|
31
|
+
}
|
|
32
|
+
async fetchUsdPrices(mints) {
|
|
33
|
+
const unique = [...new Set(mints.map((m) => m.toString()))];
|
|
34
|
+
if (unique.length === 0)
|
|
35
|
+
return {};
|
|
36
|
+
const batches = chunk(unique, BATCH_SIZE);
|
|
37
|
+
const responses = await Promise.all(batches.map((batch) => withRetry(async () => {
|
|
38
|
+
const url = `${this.baseUrl}?ids=${batch.join(",")}`;
|
|
39
|
+
const res = await this.fetchFn(url);
|
|
40
|
+
if (!res.ok) {
|
|
41
|
+
throw new Error(`Jupiter price API ${res.status} for ${url}`);
|
|
42
|
+
}
|
|
43
|
+
const body = (await res.json());
|
|
44
|
+
if (!body || typeof body !== "object") {
|
|
45
|
+
throw new Error("Jupiter price API returned a non-object body");
|
|
46
|
+
}
|
|
47
|
+
return body;
|
|
48
|
+
}, this.retries)));
|
|
49
|
+
const merged = Object.assign({}, ...responses);
|
|
50
|
+
const prices = {};
|
|
51
|
+
for (const mint of unique) {
|
|
52
|
+
const entry = merged[mint];
|
|
53
|
+
if (entry && typeof entry === "object" && "usdPrice" in entry) {
|
|
54
|
+
const usd = Number(entry.usdPrice);
|
|
55
|
+
if (Number.isFinite(usd) && usd > 0)
|
|
56
|
+
prices[mint] = usd;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return prices;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.JupiterPriceSource = JupiterPriceSource;
|
|
63
|
+
//# sourceMappingURL=jupiterPriceSource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jupiterPriceSource.js","sourceRoot":"","sources":["../../../src/services/consensusOracle/jupiterPriceSource.ts"],"names":[],"mappings":"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"}
|