@elmntl/jlpd-sdk 0.13.5 → 0.13.7
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/jlpd-strategy/fluid-view.d.ts +8 -0
- package/dist/jlpd-strategy/fluid-view.js +16 -0
- package/dist/jlpd-strategy/hedge-derived.d.ts +63 -32
- package/dist/jlpd-strategy/hedge-derived.js +112 -48
- package/dist/jlpd-strategy/hedge-instructions.d.ts +5 -4
- package/dist/jlpd-strategy/hedge-instructions.js +33 -11
- package/dist/jlpd-strategy/hedge-state.d.ts +6 -7
- package/dist/jlpd-strategy/hedge-state.js +8 -3
- package/dist/jlpd-strategy/settle-yield.d.ts +4 -4
- package/dist/jlpd-strategy/settle-yield.js +3 -3
- package/dist/p-stv-core/accounts.d.ts +18 -2
- package/dist/p-stv-core/accounts.js +27 -2
- package/dist/p-stv-core/constants.d.ts +55 -0
- package/dist/p-stv-core/constants.js +58 -2
- package/dist/p-stv-core/events.js +53 -15
- package/dist/p-stv-core/instructions.d.ts +32 -1
- package/dist/p-stv-core/instructions.js +48 -2
- package/dist/p-stv-core/types.d.ts +74 -1
- package/package.json +3 -3
|
@@ -60,6 +60,14 @@ export interface FluidTick {
|
|
|
60
60
|
* program — byte-identical to the on-chain `derive_fluid_tick_pda` (golden-vector tested).
|
|
61
61
|
*/
|
|
62
62
|
export declare function deriveFluidTickPda(vaultId: number, tick: number): PublicKey;
|
|
63
|
+
/**
|
|
64
|
+
* Net RAW debt of a decoded position: tick-implied minus dust — the `net_debt_raw` the deployed
|
|
65
|
+
* partial-repay acceptance predicate is evaluated against (hedge_repay.rs). Supply-only positions
|
|
66
|
+
* read at the COLD tick and therefore return 0. Dust exceeding the tick-implied debt means the
|
|
67
|
+
* decoded (tick, collateral, dust) triple is inconsistent — a STRUCTURAL error the caller must
|
|
68
|
+
* treat as terminal, never as "no debt".
|
|
69
|
+
*/
|
|
70
|
+
export declare function fluidNetDebtRaw(position: FluidPosition): bigint;
|
|
63
71
|
/**
|
|
64
72
|
* The Tick account settle_yield's per-slot triple must carry for `position`: the canonical
|
|
65
73
|
* `Tick(vaultId, position.tick)` for an ACTIVE debt position, or the `Tick(vaultId, MIN_TICK)`
|
|
@@ -20,6 +20,7 @@ exports.FLUID_ZERO_TICK_SCALED_RATIO = exports.JUP_LEND_EARN_MAX_SANE_RATE = exp
|
|
|
20
20
|
exports.getRatioAtTick = getRatioAtTick;
|
|
21
21
|
exports.decodeFluidPosition = decodeFluidPosition;
|
|
22
22
|
exports.deriveFluidTickPda = deriveFluidTickPda;
|
|
23
|
+
exports.fluidNetDebtRaw = fluidNetDebtRaw;
|
|
23
24
|
exports.settleTickPdaForPosition = settleTickPdaForPosition;
|
|
24
25
|
exports.decodeFluidTick = decodeFluidTick;
|
|
25
26
|
exports.requireFluidPositionLiquidationCurrent = requireFluidPositionLiquidationCurrent;
|
|
@@ -296,6 +297,21 @@ function deriveFluidTickPda(vaultId, tick) {
|
|
|
296
297
|
normalizedLe.writeInt32LE(tick - FLUID_MIN_TICK);
|
|
297
298
|
return web3_js_1.PublicKey.findProgramAddressSync([TICK_SEED, vaultIdLe, normalizedLe], constants_1.JUP_LEND_BORROW_PROGRAM_ID)[0];
|
|
298
299
|
}
|
|
300
|
+
/**
|
|
301
|
+
* Net RAW debt of a decoded position: tick-implied minus dust — the `net_debt_raw` the deployed
|
|
302
|
+
* partial-repay acceptance predicate is evaluated against (hedge_repay.rs). Supply-only positions
|
|
303
|
+
* read at the COLD tick and therefore return 0. Dust exceeding the tick-implied debt means the
|
|
304
|
+
* decoded (tick, collateral, dust) triple is inconsistent — a STRUCTURAL error the caller must
|
|
305
|
+
* treat as terminal, never as "no debt".
|
|
306
|
+
*/
|
|
307
|
+
function fluidNetDebtRaw(position) {
|
|
308
|
+
const tick = position.isSupplyOnly ? FLUID_COLD_TICK : position.tick;
|
|
309
|
+
const tickDebt = tickImpliedDebtRaw(tick, position.collateralRaw);
|
|
310
|
+
if (position.dustDebtRaw > tickDebt) {
|
|
311
|
+
throw new Error(`fluidNetDebtRaw: dust ${position.dustDebtRaw} exceeds tick-implied debt ${tickDebt} — inconsistent position`);
|
|
312
|
+
}
|
|
313
|
+
return tickDebt - position.dustDebtRaw;
|
|
314
|
+
}
|
|
299
315
|
/**
|
|
300
316
|
* The Tick account settle_yield's per-slot triple must carry for `position`: the canonical
|
|
301
317
|
* `Tick(vaultId, position.tick)` for an ACTIVE debt position, or the `Tick(vaultId, MIN_TICK)`
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
* `hedge-state.ts` that answers the same questions the on-chain guards answer:
|
|
6
6
|
* - per-slot LTV, valued on that slot's OWN pinned Fluid oracle (matches `hedge_borrow`'s /
|
|
7
7
|
* `hedge_withdraw_collateral`'s post-op guard basis exactly — see `fluid-view.ts`)
|
|
8
|
-
* - pledged collateral
|
|
9
|
-
* - swap-churn budget remaining (`maxSwapNotionalPerSettle - swapNotionalSinceSettle`)
|
|
8
|
+
* - each slot's pledged collateral vs its `HedgeState.maxPledgedBps` share of total controlled JLP
|
|
10
9
|
*/
|
|
11
10
|
import { PublicKey } from "@solana/web3.js";
|
|
12
11
|
import type { SolanaConnection } from "../common/connection";
|
|
13
12
|
import { type HedgeState, type HedgePositionSlot } from "./hedge-state";
|
|
13
|
+
import { type FluidPosition } from "./fluid-view";
|
|
14
14
|
/**
|
|
15
15
|
* Native decimals for each known hedge debt mint — mirrors `utils/oracle.rs`'s
|
|
16
16
|
* `TOKEN_DECIMALS_{BTC,ETH,SOL,JUPUSD}` constants (the four mints
|
|
@@ -27,13 +27,13 @@ export declare function resolveDebtManifestAta(state: HedgeState, debtMint: Publ
|
|
|
27
27
|
/** Sum already-decoded per-slot collateral (pure, never throws — for read-only dashboards). */
|
|
28
28
|
export declare function sumPledgedCollateral(perSlotCollateralJlp: bigint[]): bigint;
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* before
|
|
34
|
-
*
|
|
30
|
+
* Mirror of `check_pledged_bps`: for each slot i, `collateral_i * 10000 <= maxPledgedBps[i] *
|
|
31
|
+
* (vaultJlpFree + Σ pledged)`. `perSlotCollateralJlp` is indexed BY SLOT (0 for a disabled/absent
|
|
32
|
+
* slot). Returns total pledged; throws on the first slot over its bps share. For DRIVER preflight
|
|
33
|
+
* (reject before a tx that would revert); dashboards should use `sumPledgedCollateral` instead so an
|
|
34
|
+
* (unexpected) over-cap reading still renders.
|
|
35
35
|
*/
|
|
36
|
-
export declare function
|
|
36
|
+
export declare function checkPledgedBps(perSlotCollateralJlp: bigint[], maxPledgedBps: number[], vaultJlpFree: bigint): bigint;
|
|
37
37
|
/**
|
|
38
38
|
* `hedge_repay` repay-all sentinel (u64::MAX) — the only mode that guarantees `debt == 0`.
|
|
39
39
|
* Fund the debt ATA to the on-chain budget (ceiled reading + 0.1% + 2 units) and crank the
|
|
@@ -63,6 +63,43 @@ export declare function fluidPartialRepayCreditRaw(xNative: bigint, debtDecimals
|
|
|
63
63
|
* minimum position debt). `netRawDebt` = tick-implied − dust (fluid-view's `netDebtRaw` basis).
|
|
64
64
|
*/
|
|
65
65
|
export declare function isPartialRepayAcceptable(xNative: bigint, netRawDebt: bigint, debtDecimals: number, borrowExPrice: bigint): boolean;
|
|
66
|
+
export interface FluidPartialRepayVerdict {
|
|
67
|
+
accepted: boolean;
|
|
68
|
+
/** Human reason when refused; null when accepted. */
|
|
69
|
+
reason: string | null;
|
|
70
|
+
creditRaw: bigint | null;
|
|
71
|
+
netRaw: bigint;
|
|
72
|
+
minDebtRaw: bigint;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The DEPLOYED acceptance predicate for a partial repay of `x`, evaluated from a decoded
|
|
76
|
+
* position, extended with the driver's balance precondition (Fluid pulls `x + 1` on payback):
|
|
77
|
+
*
|
|
78
|
+
* x ≥ MIN_OPERATE ∧ C(x) ≥ 1 ∧ netRaw ≥ C(x) + minDebtRaw ∧ debtAtaBalance ≥ x + 1
|
|
79
|
+
*
|
|
80
|
+
* An EXACT payoff must use the repay-all sentinel — the residual bound enforces that. Throws only
|
|
81
|
+
* on an INCONSISTENT position (dust > tick-implied), which is structural and terminal.
|
|
82
|
+
*/
|
|
83
|
+
export declare function evaluateFluidPartialRepay(args: {
|
|
84
|
+
xNative: bigint;
|
|
85
|
+
position: FluidPosition;
|
|
86
|
+
borrowExPrice: bigint;
|
|
87
|
+
debtDecimals: number;
|
|
88
|
+
debtAtaBalance: bigint;
|
|
89
|
+
}): FluidPartialRepayVerdict;
|
|
90
|
+
/**
|
|
91
|
+
* Largest acceptable partial repay ≤ `desiredNative` given the position AND the debt-ATA balance
|
|
92
|
+
* (Fluid's `x + 1` over-pull). Built on `maxPartialRepayNative`'s invert-and-verify, then
|
|
93
|
+
* re-verified through the full predicate so the ATA bound participates. Null = no acceptable
|
|
94
|
+
* partial exists — the caller escalates to repay-all (if fundable) or reports top-up-required.
|
|
95
|
+
*/
|
|
96
|
+
export declare function maxAcceptedFluidPartialRepay(args: {
|
|
97
|
+
desiredNative: bigint;
|
|
98
|
+
position: FluidPosition;
|
|
99
|
+
borrowExPrice: bigint;
|
|
100
|
+
debtDecimals: number;
|
|
101
|
+
debtAtaBalance: bigint;
|
|
102
|
+
}): bigint | null;
|
|
66
103
|
/**
|
|
67
104
|
* Largest partial repay (native) the on-chain acceptance admits for `netRawDebt` at the given
|
|
68
105
|
* stored price — the driver's sizing cap (anything larger reverts; anything at/below is safe at
|
|
@@ -70,18 +107,6 @@ export declare function isPartialRepayAcceptable(xNative: bigint, netRawDebt: bi
|
|
|
70
107
|
* use the repay-all sentinel instead).
|
|
71
108
|
*/
|
|
72
109
|
export declare function maxPartialRepayNative(netRawDebt: bigint, debtDecimals: number, borrowExPrice: bigint): bigint;
|
|
73
|
-
/**
|
|
74
|
-
* Swap-churn budget remaining before the next `settle_yield` resets the accumulator — mirrors
|
|
75
|
-
* `HedgeState.maxSwapNotionalPerSettle - HedgeState.swapNotionalSinceSettle` (USD, 6-dec),
|
|
76
|
-
* floored at 0 (the accumulator should never on-chain exceed the cap, but this stays
|
|
77
|
-
* fail-safe against a stale/racing read).
|
|
78
|
-
*/
|
|
79
|
-
export declare function churnBudgetRemainingUsd(state: Pick<HedgeState, "maxSwapNotionalPerSettle" | "swapNotionalSinceSettle">): bigint;
|
|
80
|
-
/**
|
|
81
|
-
* `HedgeState.maxPledgedCollateralJlp` as a bigint — headroom convenience: pass the result of
|
|
82
|
-
* `sumAndCheckPledgedCollateral`'s successful total (or a raw sum) to get remaining pledge room.
|
|
83
|
-
*/
|
|
84
|
-
export declare function pledgeHeadroomJlp(state: Pick<HedgeState, "maxPledgedCollateralJlp">, totalPledgedJlp: bigint): bigint;
|
|
85
110
|
/** One enabled `HedgeState.positions` slot's derived valuation. */
|
|
86
111
|
export interface HedgeSlotDerived {
|
|
87
112
|
slotIndex: number;
|
|
@@ -109,27 +134,33 @@ export declare function fetchHedgeSlotDerived(connection: SolanaConnection, stat
|
|
|
109
134
|
*/
|
|
110
135
|
export declare function fetchAllHedgeSlotsDerived(connection: SolanaConnection, state: HedgeState): Promise<HedgeSlotDerived[]>;
|
|
111
136
|
/**
|
|
112
|
-
* Portfolio-level hedge exposure: total pledged JLP collateral
|
|
113
|
-
* `HedgeState.
|
|
114
|
-
* keyed by the debt mint's base58 — different debt mints are never summed together, since
|
|
137
|
+
* Portfolio-level hedge exposure: total pledged JLP collateral, each slot's pledged SHARE of total
|
|
138
|
+
* controlled JLP (bps, vs `HedgeState.maxPledgedBps`), and per-debt-mint net debt exposure (native
|
|
139
|
+
* units, keyed by the debt mint's base58 — different debt mints are never summed together, since
|
|
115
140
|
* they are different tokens).
|
|
116
141
|
*/
|
|
117
142
|
export interface HedgeExposure {
|
|
118
143
|
/** Σ `collateralJlpNative` across every enabled slot. */
|
|
119
144
|
totalPledgedCollateralJlp: bigint;
|
|
120
|
-
/**
|
|
121
|
-
|
|
145
|
+
/** Per-slot (indexed by slot) pledged share of total controlled JLP (free vault JLP + Σ pledged), bps. */
|
|
146
|
+
pledgedShareBps: number[];
|
|
122
147
|
/**
|
|
123
|
-
*
|
|
124
|
-
* the on-chain guard (`hedge_supply_collateral`
|
|
125
|
-
*
|
|
148
|
+
* True if any slot's share exceeds its `HedgeState.maxPledgedBps[i]` — should never be true given
|
|
149
|
+
* the on-chain admission guard (`hedge_supply_collateral` rejects it every supply), but surfaced
|
|
150
|
+
* rather than thrown so a stale/racing read still renders on a dashboard.
|
|
126
151
|
*/
|
|
127
152
|
pledgeCapExceeded: boolean;
|
|
128
153
|
/** Per-debt-mint (base58) → summed native debt across every slot borrowing that mint. */
|
|
129
154
|
debtByMint: Record<string, bigint>;
|
|
130
|
-
/** Swap-churn budget remaining (USD, 6-dec). */
|
|
131
|
-
churnBudgetRemainingUsd: bigint;
|
|
132
155
|
slots: HedgeSlotDerived[];
|
|
133
156
|
}
|
|
134
|
-
/**
|
|
135
|
-
|
|
157
|
+
/**
|
|
158
|
+
* Compute portfolio-level hedge exposure. `vaultJlpFree` is the config-owned vault JLP ATA balance
|
|
159
|
+
* (base units) — the free-JLP term of the pledge-cap denominator; fetch it alongside the state.
|
|
160
|
+
*
|
|
161
|
+
* NOTE: this reads each position's stored collateral WITHOUT applying the Fluid
|
|
162
|
+
* liquidation-staleness gate (`requireFluidPositionLiquidationCurrent`), so during a
|
|
163
|
+
* liquidation-stale window a slot's collateral (and thus `pledgedShareBps` / `pledgeCapExceeded`)
|
|
164
|
+
* can be phantom. Best-effort for dashboards; the on-chain guards are authoritative.
|
|
165
|
+
*/
|
|
166
|
+
export declare function fetchHedgeExposure(connection: SolanaConnection, state: HedgeState, vaultJlpFree: bigint): Promise<HedgeExposure>;
|
|
@@ -6,22 +6,21 @@
|
|
|
6
6
|
* `hedge-state.ts` that answers the same questions the on-chain guards answer:
|
|
7
7
|
* - per-slot LTV, valued on that slot's OWN pinned Fluid oracle (matches `hedge_borrow`'s /
|
|
8
8
|
* `hedge_withdraw_collateral`'s post-op guard basis exactly — see `fluid-view.ts`)
|
|
9
|
-
* - pledged collateral
|
|
10
|
-
* - swap-churn budget remaining (`maxSwapNotionalPerSettle - swapNotionalSinceSettle`)
|
|
9
|
+
* - each slot's pledged collateral vs its `HedgeState.maxPledgedBps` share of total controlled JLP
|
|
11
10
|
*/
|
|
12
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
12
|
exports.FLUID_MIN_OPERATE_NATIVE = exports.REPAY_ALL_SENTINEL = void 0;
|
|
14
13
|
exports.debtMintDecimals = debtMintDecimals;
|
|
15
14
|
exports.resolveDebtManifestAta = resolveDebtManifestAta;
|
|
16
15
|
exports.sumPledgedCollateral = sumPledgedCollateral;
|
|
17
|
-
exports.
|
|
16
|
+
exports.checkPledgedBps = checkPledgedBps;
|
|
18
17
|
exports.clampRepayAmount = clampRepayAmount;
|
|
19
18
|
exports.fluidMinDebtRaw = fluidMinDebtRaw;
|
|
20
19
|
exports.fluidPartialRepayCreditRaw = fluidPartialRepayCreditRaw;
|
|
21
20
|
exports.isPartialRepayAcceptable = isPartialRepayAcceptable;
|
|
21
|
+
exports.evaluateFluidPartialRepay = evaluateFluidPartialRepay;
|
|
22
|
+
exports.maxAcceptedFluidPartialRepay = maxAcceptedFluidPartialRepay;
|
|
22
23
|
exports.maxPartialRepayNative = maxPartialRepayNative;
|
|
23
|
-
exports.churnBudgetRemainingUsd = churnBudgetRemainingUsd;
|
|
24
|
-
exports.pledgeHeadroomJlp = pledgeHeadroomJlp;
|
|
25
24
|
exports.fetchHedgeSlotDerived = fetchHedgeSlotDerived;
|
|
26
25
|
exports.fetchAllHedgeSlotsDerived = fetchAllHedgeSlotsDerived;
|
|
27
26
|
exports.fetchHedgeExposure = fetchHedgeExposure;
|
|
@@ -73,18 +72,33 @@ function sumPledgedCollateral(perSlotCollateralJlp) {
|
|
|
73
72
|
return total;
|
|
74
73
|
}
|
|
75
74
|
/**
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* before
|
|
80
|
-
*
|
|
75
|
+
* Mirror of `check_pledged_bps`: for each slot i, `collateral_i * 10000 <= maxPledgedBps[i] *
|
|
76
|
+
* (vaultJlpFree + Σ pledged)`. `perSlotCollateralJlp` is indexed BY SLOT (0 for a disabled/absent
|
|
77
|
+
* slot). Returns total pledged; throws on the first slot over its bps share. For DRIVER preflight
|
|
78
|
+
* (reject before a tx that would revert); dashboards should use `sumPledgedCollateral` instead so an
|
|
79
|
+
* (unexpected) over-cap reading still renders.
|
|
81
80
|
*/
|
|
82
|
-
function
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
function checkPledgedBps(perSlotCollateralJlp, maxPledgedBps, vaultJlpFree) {
|
|
82
|
+
// Mirror the program's fixed [_; MAX_HEDGE_POSITIONS] arrays: validate EVERY slot's bps, so a
|
|
83
|
+
// short array can't skip an out-of-range later entry the way the on-chain check never would.
|
|
84
|
+
if (perSlotCollateralJlp.length !== constants_1.MAX_HEDGE_POSITIONS ||
|
|
85
|
+
maxPledgedBps.length !== constants_1.MAX_HEDGE_POSITIONS) {
|
|
86
|
+
throw new Error(`checkPledgedBps: expected ${constants_1.MAX_HEDGE_POSITIONS} slot entries, got ` +
|
|
87
|
+
`collateral=${perSlotCollateralJlp.length} bps=${maxPledgedBps.length}`);
|
|
86
88
|
}
|
|
87
|
-
|
|
89
|
+
const totalPledged = sumPledgedCollateral(perSlotCollateralJlp);
|
|
90
|
+
const totalControlled = vaultJlpFree + totalPledged;
|
|
91
|
+
for (let i = 0; i < perSlotCollateralJlp.length; i++) {
|
|
92
|
+
const bps = maxPledgedBps[i] ?? 0;
|
|
93
|
+
if (!Number.isInteger(bps) || bps < 0 || bps > 10000) {
|
|
94
|
+
throw new Error(`checkPledgedBps: maxPledgedBps[${i}] out of range: ${bps}`);
|
|
95
|
+
}
|
|
96
|
+
if (perSlotCollateralJlp[i] * 10000n > BigInt(bps) * totalControlled) {
|
|
97
|
+
throw new Error(`checkPledgedBps: slot ${i} pledged ${perSlotCollateralJlp[i]} exceeds ${bps}bps of ` +
|
|
98
|
+
`controlled JLP ${totalControlled}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return totalPledged;
|
|
88
102
|
}
|
|
89
103
|
/**
|
|
90
104
|
* `hedge_repay` repay-all sentinel (u64::MAX) — the only mode that guarantees `debt == 0`.
|
|
@@ -145,6 +159,70 @@ function isPartialRepayAcceptable(xNative, netRawDebt, debtDecimals, borrowExPri
|
|
|
145
159
|
}
|
|
146
160
|
return credit >= 1n && credit + fluidMinDebtRaw(debtDecimals) <= netRawDebt;
|
|
147
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* The DEPLOYED acceptance predicate for a partial repay of `x`, evaluated from a decoded
|
|
164
|
+
* position, extended with the driver's balance precondition (Fluid pulls `x + 1` on payback):
|
|
165
|
+
*
|
|
166
|
+
* x ≥ MIN_OPERATE ∧ C(x) ≥ 1 ∧ netRaw ≥ C(x) + minDebtRaw ∧ debtAtaBalance ≥ x + 1
|
|
167
|
+
*
|
|
168
|
+
* An EXACT payoff must use the repay-all sentinel — the residual bound enforces that. Throws only
|
|
169
|
+
* on an INCONSISTENT position (dust > tick-implied), which is structural and terminal.
|
|
170
|
+
*/
|
|
171
|
+
function evaluateFluidPartialRepay(args) {
|
|
172
|
+
const netRaw = (0, fluid_view_1.fluidNetDebtRaw)(args.position);
|
|
173
|
+
const minDebtRaw = fluidMinDebtRaw(args.debtDecimals);
|
|
174
|
+
const base = { netRaw, minDebtRaw };
|
|
175
|
+
if (args.xNative < exports.FLUID_MIN_OPERATE_NATIVE) {
|
|
176
|
+
return { accepted: false, reason: `x ${args.xNative} < Fluid minimum ${exports.FLUID_MIN_OPERATE_NATIVE}`, creditRaw: null, ...base };
|
|
177
|
+
}
|
|
178
|
+
if (args.debtAtaBalance < args.xNative + 1n) {
|
|
179
|
+
return {
|
|
180
|
+
accepted: false,
|
|
181
|
+
reason: `debt ATA ${args.debtAtaBalance} < x+1 (${args.xNative + 1n}) — Fluid over-pulls one native unit`,
|
|
182
|
+
creditRaw: null,
|
|
183
|
+
...base,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
let creditRaw;
|
|
187
|
+
try {
|
|
188
|
+
creditRaw = fluidPartialRepayCreditRaw(args.xNative, args.debtDecimals, args.borrowExPrice);
|
|
189
|
+
}
|
|
190
|
+
catch (e) {
|
|
191
|
+
return { accepted: false, reason: e instanceof Error ? e.message : String(e), creditRaw: null, ...base };
|
|
192
|
+
}
|
|
193
|
+
if (creditRaw < 1n || netRaw < creditRaw + minDebtRaw) {
|
|
194
|
+
return {
|
|
195
|
+
accepted: false,
|
|
196
|
+
reason: `residual bound: net ${netRaw} < credit ${creditRaw} + min ${minDebtRaw}`,
|
|
197
|
+
creditRaw,
|
|
198
|
+
...base,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
return { accepted: true, reason: null, creditRaw, ...base };
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Largest acceptable partial repay ≤ `desiredNative` given the position AND the debt-ATA balance
|
|
205
|
+
* (Fluid's `x + 1` over-pull). Built on `maxPartialRepayNative`'s invert-and-verify, then
|
|
206
|
+
* re-verified through the full predicate so the ATA bound participates. Null = no acceptable
|
|
207
|
+
* partial exists — the caller escalates to repay-all (if fundable) or reports top-up-required.
|
|
208
|
+
*/
|
|
209
|
+
function maxAcceptedFluidPartialRepay(args) {
|
|
210
|
+
const netRaw = (0, fluid_view_1.fluidNetDebtRaw)(args.position);
|
|
211
|
+
let x = maxPartialRepayNative(netRaw, args.debtDecimals, args.borrowExPrice);
|
|
212
|
+
if (x <= 0n)
|
|
213
|
+
return null;
|
|
214
|
+
if (x > args.desiredNative)
|
|
215
|
+
x = args.desiredNative;
|
|
216
|
+
if (args.debtAtaBalance < 2n)
|
|
217
|
+
return null;
|
|
218
|
+
if (x > args.debtAtaBalance - 1n)
|
|
219
|
+
x = args.debtAtaBalance - 1n;
|
|
220
|
+
for (let i = 0; i < 4 && x >= exports.FLUID_MIN_OPERATE_NATIVE; i++, x -= 1n) {
|
|
221
|
+
if (evaluateFluidPartialRepay({ ...args, xNative: x }).accepted)
|
|
222
|
+
return x;
|
|
223
|
+
}
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
148
226
|
/**
|
|
149
227
|
* Largest partial repay (native) the on-chain acceptance admits for `netRawDebt` at the given
|
|
150
228
|
* stored price — the driver's sizing cap (anything larger reverts; anything at/below is safe at
|
|
@@ -164,27 +242,6 @@ function maxPartialRepayNative(netRawDebt, debtDecimals, borrowExPrice) {
|
|
|
164
242
|
}
|
|
165
243
|
return x >= exports.FLUID_MIN_OPERATE_NATIVE ? x : 0n;
|
|
166
244
|
}
|
|
167
|
-
/**
|
|
168
|
-
* Swap-churn budget remaining before the next `settle_yield` resets the accumulator — mirrors
|
|
169
|
-
* `HedgeState.maxSwapNotionalPerSettle - HedgeState.swapNotionalSinceSettle` (USD, 6-dec),
|
|
170
|
-
* floored at 0 (the accumulator should never on-chain exceed the cap, but this stays
|
|
171
|
-
* fail-safe against a stale/racing read).
|
|
172
|
-
*/
|
|
173
|
-
function churnBudgetRemainingUsd(state) {
|
|
174
|
-
const max = BigInt(state.maxSwapNotionalPerSettle.toString());
|
|
175
|
-
const since = BigInt(state.swapNotionalSinceSettle.toString());
|
|
176
|
-
const remaining = max - since;
|
|
177
|
-
return remaining > 0n ? remaining : 0n;
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* `HedgeState.maxPledgedCollateralJlp` as a bigint — headroom convenience: pass the result of
|
|
181
|
-
* `sumAndCheckPledgedCollateral`'s successful total (or a raw sum) to get remaining pledge room.
|
|
182
|
-
*/
|
|
183
|
-
function pledgeHeadroomJlp(state, totalPledgedJlp) {
|
|
184
|
-
const cap = BigInt(state.maxPledgedCollateralJlp.toString());
|
|
185
|
-
const headroom = cap - totalPledgedJlp;
|
|
186
|
-
return headroom > 0n ? headroom : 0n;
|
|
187
|
-
}
|
|
188
245
|
/**
|
|
189
246
|
* Fetch + value ONE `HedgeState.positions[slotIndex]` slot — the async convenience wrapper
|
|
190
247
|
* matching `hedge_borrow`'s / `hedge_withdraw_collateral`'s post-op LTV guard basis exactly
|
|
@@ -210,22 +267,29 @@ async function fetchAllHedgeSlotsDerived(connection, state) {
|
|
|
210
267
|
const results = await Promise.all(state.positions.map((slot, slotIndex) => (0, hedge_state_1.isHedgePositionSlotDisabled)(slot) ? Promise.resolve(null) : fetchHedgeSlotDerived(connection, state, slotIndex)));
|
|
211
268
|
return results.filter((r) => r !== null);
|
|
212
269
|
}
|
|
213
|
-
/**
|
|
214
|
-
|
|
270
|
+
/**
|
|
271
|
+
* Compute portfolio-level hedge exposure. `vaultJlpFree` is the config-owned vault JLP ATA balance
|
|
272
|
+
* (base units) — the free-JLP term of the pledge-cap denominator; fetch it alongside the state.
|
|
273
|
+
*
|
|
274
|
+
* NOTE: this reads each position's stored collateral WITHOUT applying the Fluid
|
|
275
|
+
* liquidation-staleness gate (`requireFluidPositionLiquidationCurrent`), so during a
|
|
276
|
+
* liquidation-stale window a slot's collateral (and thus `pledgedShareBps` / `pledgeCapExceeded`)
|
|
277
|
+
* can be phantom. Best-effort for dashboards; the on-chain guards are authoritative.
|
|
278
|
+
*/
|
|
279
|
+
async function fetchHedgeExposure(connection, state, vaultJlpFree) {
|
|
215
280
|
const slots = await fetchAllHedgeSlotsDerived(connection, state);
|
|
216
|
-
|
|
217
|
-
const
|
|
281
|
+
// Per-slot collateral indexed BY SLOT (0 for disabled) so it aligns with maxPledgedBps.
|
|
282
|
+
const perSlot = state.positions.map(() => 0n);
|
|
283
|
+
for (const s of slots)
|
|
284
|
+
perSlot[s.slotIndex] = s.collateralJlpNative;
|
|
285
|
+
const totalPledgedCollateralJlp = sumPledgedCollateral(perSlot);
|
|
286
|
+
const totalControlled = vaultJlpFree + totalPledgedCollateralJlp;
|
|
287
|
+
const pledgedShareBps = perSlot.map((c) => totalControlled > 0n ? Number((c * 10000n) / totalControlled) : 0);
|
|
288
|
+
const pledgeCapExceeded = perSlot.some((c, i) => c * 10000n > BigInt(state.maxPledgedBps[i] ?? 0) * totalControlled);
|
|
218
289
|
const debtByMint = {};
|
|
219
290
|
for (const s of slots) {
|
|
220
291
|
const key = s.slot.debtMint.toBase58();
|
|
221
292
|
debtByMint[key] = (debtByMint[key] ?? 0n) + s.debtNative;
|
|
222
293
|
}
|
|
223
|
-
return {
|
|
224
|
-
totalPledgedCollateralJlp,
|
|
225
|
-
pledgeHeadroomJlp: cap - totalPledgedCollateralJlp > 0n ? cap - totalPledgedCollateralJlp : 0n,
|
|
226
|
-
pledgeCapExceeded: totalPledgedCollateralJlp > cap,
|
|
227
|
-
debtByMint,
|
|
228
|
-
churnBudgetRemainingUsd: churnBudgetRemainingUsd(state),
|
|
229
|
-
slots,
|
|
230
|
-
};
|
|
294
|
+
return { totalPledgedCollateralJlp, pledgedShareBps, pledgeCapExceeded, debtByMint, slots };
|
|
231
295
|
}
|
|
@@ -184,10 +184,11 @@ export interface InitOrUpdateHedgeStateArgs {
|
|
|
184
184
|
jlWbtcLending?: PublicKey | null;
|
|
185
185
|
/** wETH Earn `lending` rate-source account. `null`/omitted = unchanged. */
|
|
186
186
|
jlWethLending?: PublicKey | null;
|
|
187
|
-
/**
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
187
|
+
/**
|
|
188
|
+
* Per-slot pledged-collateral cap, bps of total controlled JLP, one entry per positions slot
|
|
189
|
+
* (each 0..=10000, Σ 0..=10000). `null`/omitted = unchanged (init: [0,0,0,0] = fail-closed).
|
|
190
|
+
*/
|
|
191
|
+
maxPledgedBps?: number[] | null;
|
|
191
192
|
/** Pair-native per-position LTV cap, bps (0..=`MAX_HEDGE_LTV_BPS`). `null`/omitted = unchanged (init: 0). */
|
|
192
193
|
maxLtvBps?: number | null;
|
|
193
194
|
/** Hedge master switch. `null`/omitted = unchanged (init: false). */
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.HedgeManifestRole = void 0;
|
|
7
4
|
exports.createHedgeSupplyCollateralIx = createHedgeSupplyCollateralIx;
|
|
@@ -12,7 +9,6 @@ exports.createHedgeSwapIx = createHedgeSwapIx;
|
|
|
12
9
|
exports.createInitOrUpdateHedgeStateIx = createInitOrUpdateHedgeStateIx;
|
|
13
10
|
const web3_js_1 = require("@solana/web3.js");
|
|
14
11
|
const spl_token_1 = require("@solana/spl-token");
|
|
15
|
-
const bn_js_1 = __importDefault(require("bn.js"));
|
|
16
12
|
const buffer_1 = require("../common/buffer");
|
|
17
13
|
const constants_1 = require("./constants");
|
|
18
14
|
function toBigIntAmount(v) {
|
|
@@ -92,7 +88,7 @@ function createHedgeWithdrawCollateralIx(args, programId = constants_1.PROGRAM_I
|
|
|
92
88
|
// 0. manager [signer]
|
|
93
89
|
// 1. config [] JLPD Config PDA (read-only — this ix never writes it)
|
|
94
90
|
// 2. manager_role [] ManagerRole PDA
|
|
95
|
-
// 3. hedge_state [
|
|
91
|
+
// 3. hedge_state [] HedgeState PDA (read-only — this ix never writes it)
|
|
96
92
|
// 4. src_ata [writable] == manifest_role_ata(hedge_state, params.src_role)
|
|
97
93
|
// 5. dst_ata [writable] == manifest_role_ata(hedge_state, params.dst_role)
|
|
98
94
|
// 6. price_oracle_src [] Doves oracle for src_role, if Doves-priced; else unused
|
|
@@ -160,7 +156,7 @@ function createHedgeSwapIx(args, programId = constants_1.PROGRAM_ID) {
|
|
|
160
156
|
{ pubkey: manager, isSigner: true, isWritable: false },
|
|
161
157
|
{ pubkey: config, isSigner: false, isWritable: false },
|
|
162
158
|
{ pubkey: managerRole, isSigner: false, isWritable: false },
|
|
163
|
-
{ pubkey: hedgeState, isSigner: false, isWritable:
|
|
159
|
+
{ pubkey: hedgeState, isSigner: false, isWritable: false },
|
|
164
160
|
{ pubkey: srcAta, isSigner: false, isWritable: true },
|
|
165
161
|
{ pubkey: dstAta, isSigner: false, isWritable: true },
|
|
166
162
|
{ pubkey: priceOracleSrc, isSigner: false, isWritable: false },
|
|
@@ -206,8 +202,7 @@ function createHedgeSwapIx(args, programId = constants_1.PROGRAM_ID) {
|
|
|
206
202
|
// jl_jupusd / jl_wbtc / jl_weth: Option<Pubkey> (3) — Earn fToken ATAs
|
|
207
203
|
// jl_jupusd_mint / jl_wbtc_mint / jl_weth_mint: Option<Pubkey> (3) — admin-set fToken mints
|
|
208
204
|
// jl_jupusd_lending / jl_wbtc_lending / jl_weth_lending: Option<Pubkey> (3) — Earn rate sources
|
|
209
|
-
//
|
|
210
|
-
// max_swap_notional_per_settle: Option<u64>
|
|
205
|
+
// max_pledged_bps: Option<[u16; MAX_HEDGE_POSITIONS(4)]>
|
|
211
206
|
// max_ltv_bps: Option<u16>
|
|
212
207
|
// enabled: Option<bool>
|
|
213
208
|
// ---------------------------------------------------------------------------
|
|
@@ -240,6 +235,33 @@ function writeOptionalBool(parts, value) {
|
|
|
240
235
|
parts.push(0x00);
|
|
241
236
|
}
|
|
242
237
|
}
|
|
238
|
+
/** Serialize `Option<[u16; n]>` — 1-byte tag, then n u16 LE if `Some` (a fixed-size Rust array, no
|
|
239
|
+
* length prefix). Mirrors the program's `validate_max_pledged_bps`: throws if the array is the
|
|
240
|
+
* wrong length, an entry exceeds 10000 (100%), or the entries sum above 10000 — so a bad governance
|
|
241
|
+
* proposal fails locally instead of on-chain. */
|
|
242
|
+
function writeOptionalU16Array(parts, value, n) {
|
|
243
|
+
if (value == null) {
|
|
244
|
+
parts.push(0x00);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (value.length !== n) {
|
|
248
|
+
throw new RangeError(`maxPledgedBps must have exactly ${n} entries, got ${value.length}`);
|
|
249
|
+
}
|
|
250
|
+
let sum = 0;
|
|
251
|
+
for (const v of value) {
|
|
252
|
+
if (!Number.isInteger(v) || v < 0 || v > 10000) {
|
|
253
|
+
throw new RangeError(`maxPledgedBps entry must be an integer in 0..=10000, got: ${v}`);
|
|
254
|
+
}
|
|
255
|
+
sum += v;
|
|
256
|
+
}
|
|
257
|
+
if (sum > 10000) {
|
|
258
|
+
throw new RangeError(`maxPledgedBps entries sum to ${sum}, exceeds 10000 (100%)`);
|
|
259
|
+
}
|
|
260
|
+
parts.push(0x01);
|
|
261
|
+
for (const v of value) {
|
|
262
|
+
parts.push(v & 0xff, (v >> 8) & 0xff);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
243
265
|
/**
|
|
244
266
|
* Build the on-chain `init_or_update_hedge_state` instruction (provisions/updates the singleton
|
|
245
267
|
* `HedgeState` PDA). See this section's module doc comment above for the full account list and
|
|
@@ -278,9 +300,9 @@ function createInitOrUpdateHedgeStateIx(args, programId = constants_1.PROGRAM_ID
|
|
|
278
300
|
(0, buffer_1.writeOptionalPubkey)(parts, args.jlJupusdLending ?? null);
|
|
279
301
|
(0, buffer_1.writeOptionalPubkey)(parts, args.jlWbtcLending ?? null);
|
|
280
302
|
(0, buffer_1.writeOptionalPubkey)(parts, args.jlWethLending ?? null);
|
|
281
|
-
// Guards.
|
|
282
|
-
|
|
283
|
-
(
|
|
303
|
+
// Guards. max_pledged_bps: Option<[u16; MAX_HEDGE_POSITIONS]> (1-byte tag + 4*u16 LE if Some),
|
|
304
|
+
// then max_ltv_bps: Option<u16>, then enabled: Option<bool>.
|
|
305
|
+
writeOptionalU16Array(parts, args.maxPledgedBps ?? null, constants_1.MAX_HEDGE_POSITIONS);
|
|
284
306
|
(0, buffer_1.writeOptionalU16)(parts, args.maxLtvBps ?? null);
|
|
285
307
|
writeOptionalBool(parts, args.enabled ?? null);
|
|
286
308
|
const data = Buffer.from(parts);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { PublicKey } from "@solana/web3.js";
|
|
2
|
-
import BN from "bn.js";
|
|
3
2
|
import type { SolanaConnection } from "../common/connection";
|
|
4
3
|
/**
|
|
5
4
|
* One Fluid borrow position: the position NFT, that vault's pinned
|
|
@@ -55,12 +54,12 @@ export interface HedgeState {
|
|
|
55
54
|
jlWbtcLending: PublicKey;
|
|
56
55
|
/** Canonical `lending` account for the wETH pool (disabled until `jlWethMint` is set). */
|
|
57
56
|
jlWethLending: PublicKey;
|
|
58
|
-
/**
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Per-slot pledged-collateral cap, bps of total controlled JLP (one entry per positions slot,
|
|
59
|
+
* each 0..=10000). Lives in the reserved tail at bytes [1120..1128]. Replaces the removed absolute
|
|
60
|
+
* pledge cap + the swap-churn cap/accumulator (bytes [1088..1112] are now reserved, unread).
|
|
61
|
+
*/
|
|
62
|
+
maxPledgedBps: number[];
|
|
64
63
|
/** Liquidation-probability cap in basis points, valued on each position's own pinned Fluid oracle. */
|
|
65
64
|
maxLtvBps: number;
|
|
66
65
|
/** Hedge switch bitfield; bit 0 (`HEDGE_FLAG_ENABLED`) is the master switch. */
|
|
@@ -84,9 +84,14 @@ function deserializeHedgeState(data) {
|
|
|
84
84
|
jlJupusdLending: (0, buffer_1.readPubkey)(data, afterPositions + 352),
|
|
85
85
|
jlWbtcLending: (0, buffer_1.readPubkey)(data, afterPositions + 384),
|
|
86
86
|
jlWethLending: (0, buffer_1.readPubkey)(data, afterPositions + 416),
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
// bytes [1088..1112] (afterPositions + 448..472) are reserved (removed guards), unread.
|
|
88
|
+
// max_pledged_bps: [u16; 4] in the reserved tail at byte 1120 (afterPositions + 480).
|
|
89
|
+
maxPledgedBps: [
|
|
90
|
+
(0, buffer_1.readU16)(data, afterPositions + 480),
|
|
91
|
+
(0, buffer_1.readU16)(data, afterPositions + 482),
|
|
92
|
+
(0, buffer_1.readU16)(data, afterPositions + 484),
|
|
93
|
+
(0, buffer_1.readU16)(data, afterPositions + 486),
|
|
94
|
+
],
|
|
90
95
|
maxLtvBps: (0, buffer_1.readU16)(data, afterPositions + 472),
|
|
91
96
|
flags: (0, buffer_1.readU16)(data, afterPositions + 474),
|
|
92
97
|
version: (0, buffer_1.readU8)(data, afterPositions + 476),
|
|
@@ -8,10 +8,10 @@ export interface CreateSettleYieldIxArgs {
|
|
|
8
8
|
tokenProgram?: PublicKey;
|
|
9
9
|
programId?: PublicKey;
|
|
10
10
|
/**
|
|
11
|
-
* Hedge block accounts (position/vault_state
|
|
12
|
-
* plus the manifest + earn block), appended after the 15 fixed accounts
|
|
13
|
-
* BEFORE `custodyAccounts`. Defaults to `[]` -- for now callers pass
|
|
14
|
-
* while the hedge is disabled.
|
|
11
|
+
* Hedge block accounts (position/vault_state/tick triples per enabled hedge
|
|
12
|
+
* slot, plus the manifest + earn block), appended after the 15 fixed accounts
|
|
13
|
+
* and BEFORE `custodyAccounts`. Defaults to `[]` -- for now callers pass
|
|
14
|
+
* nothing while the hedge is disabled.
|
|
15
15
|
*/
|
|
16
16
|
hedgeAccounts?: AccountMeta[];
|
|
17
17
|
/**
|
|
@@ -17,7 +17,7 @@ const ata_1 = require("../common/ata");
|
|
|
17
17
|
* Accounts (15 total):
|
|
18
18
|
* 0: config (JlpdConfig PDA)
|
|
19
19
|
* 1: manager_role (ManagerRole PDA)
|
|
20
|
-
* 2: hedge_state (HedgeState PDA,
|
|
20
|
+
* 2: hedge_state (HedgeState PDA, read-only)
|
|
21
21
|
* 3: vault_jlp_ata (JLP ATA owned by config)
|
|
22
22
|
* 4: stv_0 (BTC strategy_state, mut)
|
|
23
23
|
* 5: stv_1 (ETH strategy_state, mut)
|
|
@@ -31,7 +31,7 @@ const ata_1 = require("../common/ata");
|
|
|
31
31
|
* 13: jlp_mint_account
|
|
32
32
|
* 14: manager (signer)
|
|
33
33
|
* 15+: remaining_accounts, in this EXACT order:
|
|
34
|
-
* [0 ..
|
|
34
|
+
* [0 .. 3*enabled_hedge_slots) -- (position, vault_state, tick) triples per
|
|
35
35
|
* ENABLED hedge slot, then the manifest + earn block (one account per
|
|
36
36
|
* non-default hedge manifest slot). Empty while the hedge is disabled.
|
|
37
37
|
* [.. remainder) -- the JLP pool custody accounts, in pool `custodies`
|
|
@@ -46,7 +46,7 @@ function buildRawSettleYieldIx(args, programId = constants_1.PROGRAM_ID) {
|
|
|
46
46
|
const keys = [
|
|
47
47
|
{ pubkey: config, isSigner: false, isWritable: true },
|
|
48
48
|
{ pubkey: managerRole, isSigner: false, isWritable: false },
|
|
49
|
-
{ pubkey: hedgeState, isSigner: false, isWritable:
|
|
49
|
+
{ pubkey: hedgeState, isSigner: false, isWritable: false },
|
|
50
50
|
{ pubkey: vaultJlpAta, isSigner: false, isWritable: false },
|
|
51
51
|
{ pubkey: stv0, isSigner: false, isWritable: true },
|
|
52
52
|
{ pubkey: stv1, isSigner: false, isWritable: true },
|
|
@@ -99,11 +99,17 @@ export declare function warmAdminEffective(stv: Stv): PublicKey;
|
|
|
99
99
|
* [ 92.. 96] claimAvailableAfter u32 (unix seconds)
|
|
100
100
|
* [ 96.. 97] bump u8
|
|
101
101
|
* [ 97.. 98] version u8
|
|
102
|
-
* [ 98.. 99] requestFlags u8 (bit0 WR_FLAG_MIGRATE
|
|
102
|
+
* [ 98.. 99] requestFlags u8 (mask 0x0F: bit0 WR_FLAG_MIGRATE,
|
|
103
|
+
* bit1 WR_FLAG_FROZEN, bit2
|
|
104
|
+
* WR_FLAG_RECIPIENT_USER_OK, bit3
|
|
105
|
+
* WR_FLAG_RECIPIENT_COLD_OK)
|
|
103
106
|
* [ 99..104] _padding [u8; 5]
|
|
104
107
|
* [104..112] destVaultId u64 (migrate: dest STV vault_id; withdraw: 0)
|
|
105
108
|
* [112..120] minDestShares u64 (migrate: slippage floor; withdraw: 0)
|
|
106
|
-
* [120..
|
|
109
|
+
* [120..152] claimRecipient Pubkey (withdrawal-freeze co-signed
|
|
110
|
+
* redirect target; [0;32] = pay
|
|
111
|
+
* `user`, today's default)
|
|
112
|
+
* [152..168] _reserved [u8; 16]
|
|
107
113
|
*/
|
|
108
114
|
export declare function deserializeWithdrawRequest(data: Buffer): WithdrawRequest;
|
|
109
115
|
/**
|
|
@@ -111,6 +117,16 @@ export declare function deserializeWithdrawRequest(data: Buffer): WithdrawReques
|
|
|
111
117
|
* Returns `"migrate"` when WR_FLAG_MIGRATE (0x01) is set, else `"withdraw"`.
|
|
112
118
|
*/
|
|
113
119
|
export declare function withdrawRequestKind(wr: WithdrawRequest): "withdraw" | "migrate";
|
|
120
|
+
/** True if `WR_FLAG_FROZEN` is set on `requestFlags`. Mirrors `WithdrawRequest::is_frozen`. */
|
|
121
|
+
export declare function isWithdrawRequestFrozen(wr: WithdrawRequest): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* A redirect is ARMED iff `claimRecipient` is nonzero AND both the user's and
|
|
124
|
+
* cold's approval bits are set on the same stored value. Mirrors the on-chain
|
|
125
|
+
* `WithdrawRequest::is_redirect_armed()` (state/withdraw_request.rs) exactly —
|
|
126
|
+
* when armed, `execute_claim` pays the canonical `ATA(claimRecipient, baseMint)`
|
|
127
|
+
* instead of `user`.
|
|
128
|
+
*/
|
|
129
|
+
export declare function isRedirectArmed(wr: WithdrawRequest): boolean;
|
|
114
130
|
/**
|
|
115
131
|
* DelayedDepositRequest — per-(STV, user, epoch) pending deposit. Total 152 bytes.
|
|
116
132
|
*
|
|
@@ -5,6 +5,8 @@ exports.deserializeStv = deserializeStv;
|
|
|
5
5
|
exports.warmAdminEffective = warmAdminEffective;
|
|
6
6
|
exports.deserializeWithdrawRequest = deserializeWithdrawRequest;
|
|
7
7
|
exports.withdrawRequestKind = withdrawRequestKind;
|
|
8
|
+
exports.isWithdrawRequestFrozen = isWithdrawRequestFrozen;
|
|
9
|
+
exports.isRedirectArmed = isRedirectArmed;
|
|
8
10
|
exports.deserializeDelayedDepositRequest = deserializeDelayedDepositRequest;
|
|
9
11
|
exports.deserializeManagerRole = deserializeManagerRole;
|
|
10
12
|
exports.fetchGlobalConfig = fetchGlobalConfig;
|
|
@@ -209,11 +211,17 @@ function warmAdminEffective(stv) {
|
|
|
209
211
|
* [ 92.. 96] claimAvailableAfter u32 (unix seconds)
|
|
210
212
|
* [ 96.. 97] bump u8
|
|
211
213
|
* [ 97.. 98] version u8
|
|
212
|
-
* [ 98.. 99] requestFlags u8 (bit0 WR_FLAG_MIGRATE
|
|
214
|
+
* [ 98.. 99] requestFlags u8 (mask 0x0F: bit0 WR_FLAG_MIGRATE,
|
|
215
|
+
* bit1 WR_FLAG_FROZEN, bit2
|
|
216
|
+
* WR_FLAG_RECIPIENT_USER_OK, bit3
|
|
217
|
+
* WR_FLAG_RECIPIENT_COLD_OK)
|
|
213
218
|
* [ 99..104] _padding [u8; 5]
|
|
214
219
|
* [104..112] destVaultId u64 (migrate: dest STV vault_id; withdraw: 0)
|
|
215
220
|
* [112..120] minDestShares u64 (migrate: slippage floor; withdraw: 0)
|
|
216
|
-
* [120..
|
|
221
|
+
* [120..152] claimRecipient Pubkey (withdrawal-freeze co-signed
|
|
222
|
+
* redirect target; [0;32] = pay
|
|
223
|
+
* `user`, today's default)
|
|
224
|
+
* [152..168] _reserved [u8; 16]
|
|
217
225
|
*/
|
|
218
226
|
function deserializeWithdrawRequest(data) {
|
|
219
227
|
if (data.length < constants_1.WITHDRAW_REQUEST_SIZE) {
|
|
@@ -236,6 +244,7 @@ function deserializeWithdrawRequest(data) {
|
|
|
236
244
|
requestFlags: (0, buffer_1.readU8)(data, 98),
|
|
237
245
|
destVaultId: (0, buffer_1.readU64)(data, 104),
|
|
238
246
|
minDestShares: (0, buffer_1.readU64)(data, 112),
|
|
247
|
+
claimRecipient: (0, buffer_1.readPubkey)(data, 120),
|
|
239
248
|
};
|
|
240
249
|
}
|
|
241
250
|
/**
|
|
@@ -245,6 +254,22 @@ function deserializeWithdrawRequest(data) {
|
|
|
245
254
|
function withdrawRequestKind(wr) {
|
|
246
255
|
return (wr.requestFlags & 0x01) !== 0 ? "migrate" : "withdraw";
|
|
247
256
|
}
|
|
257
|
+
/** True if `WR_FLAG_FROZEN` is set on `requestFlags`. Mirrors `WithdrawRequest::is_frozen`. */
|
|
258
|
+
function isWithdrawRequestFrozen(wr) {
|
|
259
|
+
return (wr.requestFlags & constants_1.WR_FLAG_FROZEN) !== 0;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* A redirect is ARMED iff `claimRecipient` is nonzero AND both the user's and
|
|
263
|
+
* cold's approval bits are set on the same stored value. Mirrors the on-chain
|
|
264
|
+
* `WithdrawRequest::is_redirect_armed()` (state/withdraw_request.rs) exactly —
|
|
265
|
+
* when armed, `execute_claim` pays the canonical `ATA(claimRecipient, baseMint)`
|
|
266
|
+
* instead of `user`.
|
|
267
|
+
*/
|
|
268
|
+
function isRedirectArmed(wr) {
|
|
269
|
+
return (!wr.claimRecipient.equals(web3_js_1.PublicKey.default) &&
|
|
270
|
+
(wr.requestFlags & constants_1.WR_FLAG_RECIPIENT_USER_OK) !== 0 &&
|
|
271
|
+
(wr.requestFlags & constants_1.WR_FLAG_RECIPIENT_COLD_OK) !== 0);
|
|
272
|
+
}
|
|
248
273
|
/**
|
|
249
274
|
* DelayedDepositRequest — per-(STV, user, epoch) pending deposit. Total 152 bytes.
|
|
250
275
|
*
|
|
@@ -42,6 +42,25 @@ export declare const IX_ACCEPT_VAULT_ADMIN = 20;
|
|
|
42
42
|
* silently freezing a vault. See docs/spec-warm-admin-guardrails.md §4.3.
|
|
43
43
|
*/
|
|
44
44
|
export declare const IX_TRIP_CIRCUIT_BREAKER = 21;
|
|
45
|
+
/**
|
|
46
|
+
* freeze_withdraw_request (disc 0x16 = 22) — incident-response freeze on a
|
|
47
|
+
* single WithdrawRequest. OR-auth: the WR's own `user` (self-freeze) OR a
|
|
48
|
+
* valid manager for the STV. FIXED 4-account ABI (see
|
|
49
|
+
* `createFreezeWithdrawRequestIx`) — pause-exempt.
|
|
50
|
+
*/
|
|
51
|
+
export declare const IX_FREEZE_WITHDRAW_REQUEST = 22;
|
|
52
|
+
/**
|
|
53
|
+
* unfreeze_withdraw_request (disc 0x17 = 23) — clears `WR_FLAG_FROZEN`.
|
|
54
|
+
* `stv.coldAdmin` may always; `stv.warmAdminEffective()` may only when the
|
|
55
|
+
* redirect is ARMED. Pause-exempt.
|
|
56
|
+
*/
|
|
57
|
+
export declare const IX_UNFREEZE_WITHDRAW_REQUEST = 23;
|
|
58
|
+
/**
|
|
59
|
+
* set_claim_recipient (disc 0x18 = 24) — the 2-of-2 COLD-LOCK redirect.
|
|
60
|
+
* Signer is the WR's `user` OR `stv.coldAdmin` (never warm). WR must be
|
|
61
|
+
* frozen. Pause-exempt.
|
|
62
|
+
*/
|
|
63
|
+
export declare const IX_SET_CLAIM_RECIPIENT = 24;
|
|
45
64
|
export declare const EVT_CONFIG_INITIALIZED = 0;
|
|
46
65
|
export declare const EVT_CONFIG_UPDATED = 1;
|
|
47
66
|
export declare const EVT_STV_CREATED = 2;
|
|
@@ -91,6 +110,31 @@ export declare const EVT_CIRCUIT_BREAKER_TRIPPED = 27;
|
|
|
91
110
|
export declare const TRIP_AUTHORITY_KIND_COLD = 0;
|
|
92
111
|
export declare const TRIP_AUTHORITY_KIND_WARM = 1;
|
|
93
112
|
export declare const TRIP_AUTHORITY_KIND_MANAGER = 2;
|
|
113
|
+
/**
|
|
114
|
+
* WithdrawRequestFrozen — emitted by freeze_withdraw_request (disc 22).
|
|
115
|
+
* Fields: wr(32), stv(32), user(32), epochId(4), authority(32), authorityKind(1).
|
|
116
|
+
*/
|
|
117
|
+
export declare const EVT_WITHDRAW_REQUEST_FROZEN = 28;
|
|
118
|
+
/**
|
|
119
|
+
* WithdrawRequestUnfrozen — emitted by unfreeze_withdraw_request (disc 23).
|
|
120
|
+
* Fields: wr(32), stv(32), user(32), epochId(4), authority(32).
|
|
121
|
+
*/
|
|
122
|
+
export declare const EVT_WITHDRAW_REQUEST_UNFROZEN = 29;
|
|
123
|
+
/**
|
|
124
|
+
* ClaimRecipientSet — emitted by set_claim_recipient (disc 24).
|
|
125
|
+
* Fields: wr(32), stv(32), user(32), epochId(4), recipient(32), approverKind(1), armed(1).
|
|
126
|
+
*/
|
|
127
|
+
export declare const EVT_CLAIM_RECIPIENT_SET = 30;
|
|
128
|
+
/**
|
|
129
|
+
* freeze_withdraw_request / WithdrawRequestFrozenEvent authorityKind values.
|
|
130
|
+
*/
|
|
131
|
+
export declare const FREEZE_AUTHORITY_KIND_USER = 0;
|
|
132
|
+
export declare const FREEZE_AUTHORITY_KIND_MANAGER = 1;
|
|
133
|
+
/**
|
|
134
|
+
* set_claim_recipient / ClaimRecipientSetEvent approverKind values.
|
|
135
|
+
*/
|
|
136
|
+
export declare const RECIPIENT_APPROVER_KIND_USER = 0;
|
|
137
|
+
export declare const RECIPIENT_APPROVER_KIND_COLD = 1;
|
|
94
138
|
export declare const FLAG_PAUSED = 1;
|
|
95
139
|
export declare const FLAG_DEPOSITS_DISABLED = 2;
|
|
96
140
|
export declare const FLAG_WITHDRAWALS_DISABLED = 4;
|
|
@@ -131,6 +175,17 @@ export declare const FEE_CAP_BPS = 9900;
|
|
|
131
175
|
export declare const MAX_FEE_BPS = 1000;
|
|
132
176
|
/** WithdrawRequest.request_flags bit 0: 0 = withdraw, 1 = migrate. */
|
|
133
177
|
export declare const WR_FLAG_MIGRATE = 1;
|
|
178
|
+
/**
|
|
179
|
+
* WithdrawRequest.request_flags bit 1: the WR is frozen (incident response).
|
|
180
|
+
* Blocks payout in execute_claim unless a redirect is ARMED (exit-only).
|
|
181
|
+
*/
|
|
182
|
+
export declare const WR_FLAG_FROZEN = 2;
|
|
183
|
+
/** WithdrawRequest.request_flags bit 2: the WR's `user` approved `claimRecipient`. */
|
|
184
|
+
export declare const WR_FLAG_RECIPIENT_USER_OK = 4;
|
|
185
|
+
/** WithdrawRequest.request_flags bit 3: `stv.coldAdmin` approved `claimRecipient`. */
|
|
186
|
+
export declare const WR_FLAG_RECIPIENT_COLD_OK = 8;
|
|
187
|
+
/** All bits outside this mask are reserved and must be zero. */
|
|
188
|
+
export declare const WR_VALID_FLAGS_MASK = 15;
|
|
134
189
|
export declare const GLOBAL_CONFIG_SIZE = 56;
|
|
135
190
|
export declare const STV_SIZE = 664;
|
|
136
191
|
export declare const WITHDRAW_REQUEST_SIZE = 168;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
3
|
+
exports.EVT_FEES_SETTLED = exports.EVT_EPOCH_ADVANCED = exports.EVT_EPOCH_PROCESSED = exports.EVT_WITHDRAWN_FROM_STRATEGY = exports.EVT_DEPOSITED_TO_STRATEGY = exports.EVT_WITHDRAW_CLAIMED = exports.EVT_WITHDRAW_REQUEST_INCREASED = exports.EVT_WITHDRAW_REQUESTED = exports.EVT_DEPOSITED = exports.EVT_STV_UPDATED = exports.EVT_STV_CREATED = exports.EVT_CONFIG_UPDATED = exports.EVT_CONFIG_INITIALIZED = exports.IX_SET_CLAIM_RECIPIENT = exports.IX_UNFREEZE_WITHDRAW_REQUEST = exports.IX_FREEZE_WITHDRAW_REQUEST = exports.IX_TRIP_CIRCUIT_BREAKER = exports.IX_ACCEPT_VAULT_ADMIN = exports.IX_SEED_STV = exports.IX_INSTANT_WITHDRAW = exports.IX_MIGRATE_CANCEL = exports.IX_PROCESS_DELAYED_DEPOSIT = exports.IX_MIGRATE_EXECUTE = exports.IX_MIGRATE_REQUEST = exports.IX_MIGRATE_LEND = exports.IX_OVERRIDE_CLAIM_WITHDRAW = exports.IX_REMOVE_MANAGER = exports.IX_ADD_MANAGER = exports.IX_CLOSE_STV = exports.IX_WITHDRAW_FROM_STRATEGY = exports.IX_DEPOSIT_TO_STRATEGY = exports.IX_PROCESS_EPOCH = exports.IX_CLAIM_WITHDRAW = exports.IX_REQUEST_WITHDRAW = exports.IX_DEPOSIT = exports.IX_INIT_OR_UPDATE_STV = exports.IX_INIT_OR_UPDATE_CONFIG = exports.DISC_MANAGER_ROLE = exports.DISC_DELAYED_DEPOSIT_REQUEST = exports.DISC_WITHDRAW_REQUEST = exports.DISC_STV = exports.DISC_GLOBAL_CONFIG = exports.MANAGER_SEED = exports.DELAYED_DEPOSIT_SEED = exports.MIGRATE_REQUEST_SEED = exports.WITHDRAW_REQUEST_SEED = exports.EV_MINT_SEED = exports.STV_SEED = exports.CONFIG_SEED = exports.PROGRAM_ID = void 0;
|
|
4
|
+
exports.GLOBAL_CONFIG_SIZE = exports.WR_VALID_FLAGS_MASK = exports.WR_FLAG_RECIPIENT_COLD_OK = exports.WR_FLAG_RECIPIENT_USER_OK = exports.WR_FLAG_FROZEN = exports.WR_FLAG_MIGRATE = exports.MAX_FEE_BPS = exports.FEE_CAP_BPS = exports.MAX_STRATEGIES = exports.MAX_CHILD_VAULTS = exports.STALENESS_THRESHOLD = exports.BPS_DENOMINATOR = exports.PPS_DECIMALS = exports.CFG_FLAG_GLOBAL_PAUSED = exports.FLAG_SEEDED = exports.FLAG_BYPASS_MIGRATE_DST_WAITOUT = exports.FLAG_BYPASS_MIGRATE_SRC_WAITOUT = exports.FLAG_DELAYED_DEPOSIT = exports.FLAG_DEPOSIT_FEE_ON_MIGRATE = exports.FLAG_WITHDRAWAL_FEE_ON_MIGRATE = exports.FLAG_BYPASS_WITHDRAW_LIMIT = exports.FLAG_ALLOCATOR = exports.FLAG_REBALANCE_DISABLED = exports.FLAG_WITHDRAWALS_DISABLED = exports.FLAG_DEPOSITS_DISABLED = exports.FLAG_PAUSED = exports.RECIPIENT_APPROVER_KIND_COLD = exports.RECIPIENT_APPROVER_KIND_USER = exports.FREEZE_AUTHORITY_KIND_MANAGER = exports.FREEZE_AUTHORITY_KIND_USER = exports.EVT_CLAIM_RECIPIENT_SET = exports.EVT_WITHDRAW_REQUEST_UNFROZEN = exports.EVT_WITHDRAW_REQUEST_FROZEN = exports.TRIP_AUTHORITY_KIND_MANAGER = exports.TRIP_AUTHORITY_KIND_WARM = exports.TRIP_AUTHORITY_KIND_COLD = exports.EVT_CIRCUIT_BREAKER_TRIPPED = exports.EVT_WARM_ADMIN_SET = exports.EVT_ADMIN_ROTATION_ACCEPTED = exports.EVT_ADMIN_ROTATION_STARTED = exports.EVT_STV_SEEDED = exports.EVT_INSTANT_WITHDRAWN = exports.EVT_DELAYED_DEPOSIT_PROCESSED = exports.EVT_MIGRATE_EXECUTED = exports.EVT_MIGRATE_REQUESTED = exports.EVT_LEND_MIGRATED = exports.EVT_WITHDRAW_OVERRIDE_CLAIMED = exports.EVT_MANAGER_REMOVED = exports.EVT_MANAGER_ADDED = exports.EVT_STV_CLOSED = void 0;
|
|
5
|
+
exports.MANAGER_ROLE_SIZE = exports.DELAYED_DEPOSIT_REQUEST_SIZE = exports.WITHDRAW_REQUEST_SIZE = exports.STV_SIZE = void 0;
|
|
5
6
|
const web3_js_1 = require("@solana/web3.js");
|
|
6
7
|
// ---------------------------------------------------------------------------
|
|
7
8
|
// Program ID
|
|
@@ -68,6 +69,25 @@ exports.IX_ACCEPT_VAULT_ADMIN = 20;
|
|
|
68
69
|
* silently freezing a vault. See docs/spec-warm-admin-guardrails.md §4.3.
|
|
69
70
|
*/
|
|
70
71
|
exports.IX_TRIP_CIRCUIT_BREAKER = 21;
|
|
72
|
+
/**
|
|
73
|
+
* freeze_withdraw_request (disc 0x16 = 22) — incident-response freeze on a
|
|
74
|
+
* single WithdrawRequest. OR-auth: the WR's own `user` (self-freeze) OR a
|
|
75
|
+
* valid manager for the STV. FIXED 4-account ABI (see
|
|
76
|
+
* `createFreezeWithdrawRequestIx`) — pause-exempt.
|
|
77
|
+
*/
|
|
78
|
+
exports.IX_FREEZE_WITHDRAW_REQUEST = 22;
|
|
79
|
+
/**
|
|
80
|
+
* unfreeze_withdraw_request (disc 0x17 = 23) — clears `WR_FLAG_FROZEN`.
|
|
81
|
+
* `stv.coldAdmin` may always; `stv.warmAdminEffective()` may only when the
|
|
82
|
+
* redirect is ARMED. Pause-exempt.
|
|
83
|
+
*/
|
|
84
|
+
exports.IX_UNFREEZE_WITHDRAW_REQUEST = 23;
|
|
85
|
+
/**
|
|
86
|
+
* set_claim_recipient (disc 0x18 = 24) — the 2-of-2 COLD-LOCK redirect.
|
|
87
|
+
* Signer is the WR's `user` OR `stv.coldAdmin` (never warm). WR must be
|
|
88
|
+
* frozen. Pause-exempt.
|
|
89
|
+
*/
|
|
90
|
+
exports.IX_SET_CLAIM_RECIPIENT = 24;
|
|
71
91
|
// ---------------------------------------------------------------------------
|
|
72
92
|
// Event Discriminators (1-byte)
|
|
73
93
|
// ---------------------------------------------------------------------------
|
|
@@ -120,6 +140,31 @@ exports.EVT_CIRCUIT_BREAKER_TRIPPED = 27;
|
|
|
120
140
|
exports.TRIP_AUTHORITY_KIND_COLD = 0;
|
|
121
141
|
exports.TRIP_AUTHORITY_KIND_WARM = 1;
|
|
122
142
|
exports.TRIP_AUTHORITY_KIND_MANAGER = 2;
|
|
143
|
+
/**
|
|
144
|
+
* WithdrawRequestFrozen — emitted by freeze_withdraw_request (disc 22).
|
|
145
|
+
* Fields: wr(32), stv(32), user(32), epochId(4), authority(32), authorityKind(1).
|
|
146
|
+
*/
|
|
147
|
+
exports.EVT_WITHDRAW_REQUEST_FROZEN = 28;
|
|
148
|
+
/**
|
|
149
|
+
* WithdrawRequestUnfrozen — emitted by unfreeze_withdraw_request (disc 23).
|
|
150
|
+
* Fields: wr(32), stv(32), user(32), epochId(4), authority(32).
|
|
151
|
+
*/
|
|
152
|
+
exports.EVT_WITHDRAW_REQUEST_UNFROZEN = 29;
|
|
153
|
+
/**
|
|
154
|
+
* ClaimRecipientSet — emitted by set_claim_recipient (disc 24).
|
|
155
|
+
* Fields: wr(32), stv(32), user(32), epochId(4), recipient(32), approverKind(1), armed(1).
|
|
156
|
+
*/
|
|
157
|
+
exports.EVT_CLAIM_RECIPIENT_SET = 30;
|
|
158
|
+
/**
|
|
159
|
+
* freeze_withdraw_request / WithdrawRequestFrozenEvent authorityKind values.
|
|
160
|
+
*/
|
|
161
|
+
exports.FREEZE_AUTHORITY_KIND_USER = 0;
|
|
162
|
+
exports.FREEZE_AUTHORITY_KIND_MANAGER = 1;
|
|
163
|
+
/**
|
|
164
|
+
* set_claim_recipient / ClaimRecipientSetEvent approverKind values.
|
|
165
|
+
*/
|
|
166
|
+
exports.RECIPIENT_APPROVER_KIND_USER = 0;
|
|
167
|
+
exports.RECIPIENT_APPROVER_KIND_COLD = 1;
|
|
123
168
|
// ---------------------------------------------------------------------------
|
|
124
169
|
// Vault Flags
|
|
125
170
|
// ---------------------------------------------------------------------------
|
|
@@ -171,6 +216,17 @@ exports.FEE_CAP_BPS = 9900;
|
|
|
171
216
|
exports.MAX_FEE_BPS = 1000;
|
|
172
217
|
/** WithdrawRequest.request_flags bit 0: 0 = withdraw, 1 = migrate. */
|
|
173
218
|
exports.WR_FLAG_MIGRATE = 0x01;
|
|
219
|
+
/**
|
|
220
|
+
* WithdrawRequest.request_flags bit 1: the WR is frozen (incident response).
|
|
221
|
+
* Blocks payout in execute_claim unless a redirect is ARMED (exit-only).
|
|
222
|
+
*/
|
|
223
|
+
exports.WR_FLAG_FROZEN = 0x02;
|
|
224
|
+
/** WithdrawRequest.request_flags bit 2: the WR's `user` approved `claimRecipient`. */
|
|
225
|
+
exports.WR_FLAG_RECIPIENT_USER_OK = 0x04;
|
|
226
|
+
/** WithdrawRequest.request_flags bit 3: `stv.coldAdmin` approved `claimRecipient`. */
|
|
227
|
+
exports.WR_FLAG_RECIPIENT_COLD_OK = 0x08;
|
|
228
|
+
/** All bits outside this mask are reserved and must be zero. */
|
|
229
|
+
exports.WR_VALID_FLAGS_MASK = 0x0f;
|
|
174
230
|
// ---------------------------------------------------------------------------
|
|
175
231
|
// Account Sizes
|
|
176
232
|
// ---------------------------------------------------------------------------
|
|
@@ -59,12 +59,14 @@ function parseEventsFromLogs(logs, programId = constants_1.PROGRAM_ID) {
|
|
|
59
59
|
* [41..49] amount | [49..57] sharesMinted | [57..65] depositFeeShares |
|
|
60
60
|
* [65..73] pps
|
|
61
61
|
* WithdrawRequested [0..1] disc | [1..9] vaultId | [9..41] user |
|
|
62
|
-
* [41..49] shares | [49..53] epochId
|
|
62
|
+
* [41..49] shares | [49..53] epochId | [53..85] wr
|
|
63
63
|
* WithdrawRequestIncreased [0..1] disc | [1..9] vaultId | [9..41] user |
|
|
64
64
|
* [41..49] additionalShares | [49..57] totalShares |
|
|
65
|
-
* [57..61] epochId
|
|
65
|
+
* [57..61] epochId | [61..93] wr
|
|
66
66
|
* WithdrawClaimed [0..1] disc | [1..9] vaultId | [9..41] user |
|
|
67
|
-
* [41..49] shares | [49..57] baseAmount | [57..
|
|
67
|
+
* [41..49] shares | [49..57] baseAmount | [57..65] withdrawalFeeBase |
|
|
68
|
+
* [65..69] epochId | [69..101] wr | [101..133] recipient |
|
|
69
|
+
* [133..165] destination
|
|
68
70
|
* DepositedToStrategy [0..1] disc | [1..9] vaultId | [9..41] strategy |
|
|
69
71
|
* [41..49] amount | [49..57] sharesReceived
|
|
70
72
|
* WithdrawnFromStrategy [0..1] disc | [1..9] vaultId | [9..41] strategy |
|
|
@@ -117,21 +119,28 @@ function parseEventBuffer(data) {
|
|
|
117
119
|
depositFeeShares: (0, buffer_1.readU64)(data, 57), pps: (0, buffer_1.readU64)(data, 65),
|
|
118
120
|
} : null;
|
|
119
121
|
case constants_1.EVT_WITHDRAW_REQUESTED:
|
|
120
|
-
|
|
122
|
+
// Rust: vault_id(8), user(32), shares(8), epoch_id(4), wr(32) — wr appended (withdrawal-freeze feature).
|
|
123
|
+
return data.length >= 85 ? {
|
|
121
124
|
name: "WithdrawRequested", vaultId: (0, buffer_1.readU64)(data, 1), user: (0, buffer_1.readPubkey)(data, 9),
|
|
122
|
-
shares: (0, buffer_1.readU64)(data, 41), epochId: (0, buffer_1.readU32)(data, 49),
|
|
125
|
+
shares: (0, buffer_1.readU64)(data, 41), epochId: (0, buffer_1.readU32)(data, 49), wr: (0, buffer_1.readPubkey)(data, 53),
|
|
123
126
|
} : null;
|
|
124
127
|
case constants_1.EVT_WITHDRAW_REQUEST_INCREASED:
|
|
125
|
-
|
|
128
|
+
// Rust: vault_id(8), user(32), additional_shares(8), total_shares(8), epoch_id(4), wr(32) — wr appended.
|
|
129
|
+
return data.length >= 93 ? {
|
|
126
130
|
name: "WithdrawRequestIncreased", vaultId: (0, buffer_1.readU64)(data, 1), user: (0, buffer_1.readPubkey)(data, 9),
|
|
127
131
|
additionalShares: (0, buffer_1.readU64)(data, 41), totalShares: (0, buffer_1.readU64)(data, 49), epochId: (0, buffer_1.readU32)(data, 57),
|
|
132
|
+
wr: (0, buffer_1.readPubkey)(data, 61),
|
|
128
133
|
} : null;
|
|
129
134
|
case constants_1.EVT_WITHDRAW_CLAIMED:
|
|
130
|
-
// Rust: vault_id(8), user(32), shares(8), net_base(8), withdrawal_fee_base(8), epoch_id(4)
|
|
131
|
-
|
|
135
|
+
// Rust: vault_id(8), user(32), shares(8), net_base(8), withdrawal_fee_base(8), epoch_id(4),
|
|
136
|
+
// wr(32), recipient(32), destination(32) — wr/recipient/destination appended
|
|
137
|
+
// (withdrawal-freeze feature). recipient/destination equal user/vaultAta
|
|
138
|
+
// unless the redirect was armed at claim time.
|
|
139
|
+
return data.length >= 165 ? {
|
|
132
140
|
name: "WithdrawClaimed", vaultId: (0, buffer_1.readU64)(data, 1), user: (0, buffer_1.readPubkey)(data, 9),
|
|
133
141
|
shares: (0, buffer_1.readU64)(data, 41), baseAmount: (0, buffer_1.readU64)(data, 49),
|
|
134
142
|
withdrawalFeeBase: (0, buffer_1.readU64)(data, 57), epochId: (0, buffer_1.readU32)(data, 65),
|
|
143
|
+
wr: (0, buffer_1.readPubkey)(data, 69), recipient: (0, buffer_1.readPubkey)(data, 101), destination: (0, buffer_1.readPubkey)(data, 133),
|
|
135
144
|
} : null;
|
|
136
145
|
case constants_1.EVT_DEPOSITED_TO_STRATEGY:
|
|
137
146
|
return data.length >= 57 ? {
|
|
@@ -172,12 +181,15 @@ function parseEventBuffer(data) {
|
|
|
172
181
|
} : null;
|
|
173
182
|
case constants_1.EVT_WITHDRAW_OVERRIDE_CLAIMED:
|
|
174
183
|
// Rust: vault_id(8), manager(32), user(32), shares(8), net_base(8),
|
|
175
|
-
// withdrawal_fee_base(8), epoch_id(4), daily_withdrawn(8), daily_limit(8)
|
|
176
|
-
|
|
184
|
+
// withdrawal_fee_base(8), epoch_id(4), daily_withdrawn(8), daily_limit(8),
|
|
185
|
+
// wr(32), recipient(32), destination(32) — wr/recipient/destination
|
|
186
|
+
// appended (withdrawal-freeze feature).
|
|
187
|
+
return data.length >= 213 ? {
|
|
177
188
|
name: "WithdrawOverrideClaimed", vaultId: (0, buffer_1.readU64)(data, 1), manager: (0, buffer_1.readPubkey)(data, 9),
|
|
178
189
|
user: (0, buffer_1.readPubkey)(data, 41), shares: (0, buffer_1.readU64)(data, 73), baseAmount: (0, buffer_1.readU64)(data, 81),
|
|
179
190
|
withdrawalFeeBase: (0, buffer_1.readU64)(data, 89), epochId: (0, buffer_1.readU32)(data, 97),
|
|
180
191
|
dailyWithdrawnBase: (0, buffer_1.readU64)(data, 101), dailyLimit: (0, buffer_1.readU64)(data, 109),
|
|
192
|
+
wr: (0, buffer_1.readPubkey)(data, 117), recipient: (0, buffer_1.readPubkey)(data, 149), destination: (0, buffer_1.readPubkey)(data, 181),
|
|
181
193
|
} : null;
|
|
182
194
|
case constants_1.EVT_LEND_MIGRATED:
|
|
183
195
|
return data.length >= 89 ? {
|
|
@@ -185,19 +197,21 @@ function parseEventBuffer(data) {
|
|
|
185
197
|
newLendProgram: (0, buffer_1.readPubkey)(data, 41), sharesWithdrawn: (0, buffer_1.readU64)(data, 73), baseMigrated: (0, buffer_1.readU64)(data, 81),
|
|
186
198
|
} : null;
|
|
187
199
|
case constants_1.EVT_MIGRATE_REQUESTED:
|
|
188
|
-
// Rust: src_vault_id(8), dest_vault_id(8), user(32), shares(8), epoch_id(4)
|
|
189
|
-
return data.length >=
|
|
200
|
+
// Rust: src_vault_id(8), dest_vault_id(8), user(32), shares(8), epoch_id(4), wr(32) — wr appended.
|
|
201
|
+
return data.length >= 93 ? {
|
|
190
202
|
name: "MigrateRequested", srcVaultId: (0, buffer_1.readU64)(data, 1), destVaultId: (0, buffer_1.readU64)(data, 9),
|
|
191
203
|
user: (0, buffer_1.readPubkey)(data, 17), shares: (0, buffer_1.readU64)(data, 49), epochId: (0, buffer_1.readU32)(data, 57),
|
|
204
|
+
wr: (0, buffer_1.readPubkey)(data, 61),
|
|
192
205
|
} : null;
|
|
193
206
|
case constants_1.EVT_MIGRATE_EXECUTED:
|
|
194
207
|
// Rust: src_vault_id(8), dst_vault_id(8), user(32), shares_burned(8), base_moved(8),
|
|
195
|
-
// withdrawal_fee_base(8), deposit_fee_base(8), user_dest_shares(8), epoch_id(4)
|
|
196
|
-
|
|
208
|
+
// withdrawal_fee_base(8), deposit_fee_base(8), user_dest_shares(8), epoch_id(4),
|
|
209
|
+
// wr(32) — wr appended.
|
|
210
|
+
return data.length >= 125 ? {
|
|
197
211
|
name: "MigrateExecuted", srcVaultId: (0, buffer_1.readU64)(data, 1), destVaultId: (0, buffer_1.readU64)(data, 9),
|
|
198
212
|
user: (0, buffer_1.readPubkey)(data, 17), sharesBurned: (0, buffer_1.readU64)(data, 49), baseMoved: (0, buffer_1.readU64)(data, 57),
|
|
199
213
|
withdrawalFeeBase: (0, buffer_1.readU64)(data, 65), depositFeeBase: (0, buffer_1.readU64)(data, 73),
|
|
200
|
-
userDestShares: (0, buffer_1.readU64)(data, 81), epochId: (0, buffer_1.readU32)(data, 89),
|
|
214
|
+
userDestShares: (0, buffer_1.readU64)(data, 81), epochId: (0, buffer_1.readU32)(data, 89), wr: (0, buffer_1.readPubkey)(data, 93),
|
|
201
215
|
} : null;
|
|
202
216
|
case constants_1.EVT_DELAYED_DEPOSIT_PROCESSED:
|
|
203
217
|
return data.length >= 77 ? {
|
|
@@ -240,6 +254,30 @@ function parseEventBuffer(data) {
|
|
|
240
254
|
name: "CircuitBreakerTripped", vaultId: (0, buffer_1.readU64)(data, 1), trippedBy: (0, buffer_1.readPubkey)(data, 9),
|
|
241
255
|
authorityKind: data[41],
|
|
242
256
|
} : null;
|
|
257
|
+
case constants_1.EVT_WITHDRAW_REQUEST_FROZEN:
|
|
258
|
+
// Rust: wr(32), stv(32), user(32), epoch_id(4), authority(32), authority_kind(1)
|
|
259
|
+
// → total payload 134 bytes. authorityKind: 0=user, 1=manager
|
|
260
|
+
// (FREEZE_AUTHORITY_KIND_* in constants.ts).
|
|
261
|
+
return data.length >= 134 ? {
|
|
262
|
+
name: "WithdrawRequestFrozen", wr: (0, buffer_1.readPubkey)(data, 1), stv: (0, buffer_1.readPubkey)(data, 33),
|
|
263
|
+
user: (0, buffer_1.readPubkey)(data, 65), epochId: (0, buffer_1.readU32)(data, 97), authority: (0, buffer_1.readPubkey)(data, 101),
|
|
264
|
+
authorityKind: data[133],
|
|
265
|
+
} : null;
|
|
266
|
+
case constants_1.EVT_WITHDRAW_REQUEST_UNFROZEN:
|
|
267
|
+
// Rust: wr(32), stv(32), user(32), epoch_id(4), authority(32) → total payload 133 bytes.
|
|
268
|
+
return data.length >= 133 ? {
|
|
269
|
+
name: "WithdrawRequestUnfrozen", wr: (0, buffer_1.readPubkey)(data, 1), stv: (0, buffer_1.readPubkey)(data, 33),
|
|
270
|
+
user: (0, buffer_1.readPubkey)(data, 65), epochId: (0, buffer_1.readU32)(data, 97), authority: (0, buffer_1.readPubkey)(data, 101),
|
|
271
|
+
} : null;
|
|
272
|
+
case constants_1.EVT_CLAIM_RECIPIENT_SET:
|
|
273
|
+
// Rust: wr(32), stv(32), user(32), epoch_id(4), recipient(32), approver_kind(1), armed(1)
|
|
274
|
+
// → total payload 135 bytes. approverKind: 0=user, 1=cold
|
|
275
|
+
// (RECIPIENT_APPROVER_KIND_* in constants.ts).
|
|
276
|
+
return data.length >= 135 ? {
|
|
277
|
+
name: "ClaimRecipientSet", wr: (0, buffer_1.readPubkey)(data, 1), stv: (0, buffer_1.readPubkey)(data, 33),
|
|
278
|
+
user: (0, buffer_1.readPubkey)(data, 65), epochId: (0, buffer_1.readU32)(data, 97), recipient: (0, buffer_1.readPubkey)(data, 101),
|
|
279
|
+
approverKind: data[133], armed: data[134] !== 0,
|
|
280
|
+
} : null;
|
|
243
281
|
default:
|
|
244
282
|
return null;
|
|
245
283
|
}
|
|
@@ -216,7 +216,7 @@ export interface OverrideClaimWithdrawArgs {
|
|
|
216
216
|
authority: PublicKey;
|
|
217
217
|
/** GlobalConfig PDA — checked for CFG_FLAG_GLOBAL_PAUSED */
|
|
218
218
|
config: PublicKey;
|
|
219
|
-
/** WithdrawRequest owner.
|
|
219
|
+
/** WithdrawRequest owner. Signer — MUST be distinct from `authority` (the on-chain handler rejects authority == user). */
|
|
220
220
|
user: PublicKey;
|
|
221
221
|
stv: PublicKey;
|
|
222
222
|
withdrawRequest: PublicKey;
|
|
@@ -635,3 +635,34 @@ export interface TripCircuitBreakerArgs {
|
|
|
635
635
|
managerRole?: PublicKey;
|
|
636
636
|
}
|
|
637
637
|
export declare function createTripCircuitBreakerIx(args: TripCircuitBreakerArgs, programId?: PublicKey): TransactionInstruction;
|
|
638
|
+
export interface FreezeWithdrawRequestArgs {
|
|
639
|
+
/** Self-freeze: the WR's own `user`. Manager path: any valid manager for the STV. */
|
|
640
|
+
authority: PublicKey;
|
|
641
|
+
stv: PublicKey;
|
|
642
|
+
withdrawRequest: PublicKey;
|
|
643
|
+
/**
|
|
644
|
+
* ManagerRole PDA for (stv, authority). ALWAYS required on the wire (FIXED
|
|
645
|
+
* 4-account ABI) — the handler destructures exactly 4 accounts regardless
|
|
646
|
+
* of path. Pass a real ManagerRole PDA when `authority` is a manager;
|
|
647
|
+
* pass any account (e.g. `findStvManagerRolePda(stv, authority)`) as an
|
|
648
|
+
* unread placeholder when self-freezing (`authority === wr.user`).
|
|
649
|
+
*/
|
|
650
|
+
managerRole: PublicKey;
|
|
651
|
+
}
|
|
652
|
+
export declare function createFreezeWithdrawRequestIx(args: FreezeWithdrawRequestArgs, programId?: PublicKey): TransactionInstruction;
|
|
653
|
+
export interface UnfreezeWithdrawRequestArgs {
|
|
654
|
+
/** stv.coldAdmin (always) or stv.warmAdminEffective() (only when the redirect is armed). */
|
|
655
|
+
authority: PublicKey;
|
|
656
|
+
stv: PublicKey;
|
|
657
|
+
withdrawRequest: PublicKey;
|
|
658
|
+
}
|
|
659
|
+
export declare function createUnfreezeWithdrawRequestIx(args: UnfreezeWithdrawRequestArgs, programId?: PublicKey): TransactionInstruction;
|
|
660
|
+
export interface SetClaimRecipientArgs {
|
|
661
|
+
/** wr.user OR stv.coldAdmin. Never warm — see module doc. */
|
|
662
|
+
authority: PublicKey;
|
|
663
|
+
stv: PublicKey;
|
|
664
|
+
withdrawRequest: PublicKey;
|
|
665
|
+
/** Recipient to propose/approve. `PublicKey.default` resets (cold-only). */
|
|
666
|
+
recipient: PublicKey;
|
|
667
|
+
}
|
|
668
|
+
export declare function createSetClaimRecipientIx(args: SetClaimRecipientArgs, programId?: PublicKey): TransactionInstruction;
|
|
@@ -24,6 +24,9 @@ exports.createInstantWithdrawIx = createInstantWithdrawIx;
|
|
|
24
24
|
exports.createSeedStvIx = createSeedStvIx;
|
|
25
25
|
exports.createAcceptVaultAdminIx = createAcceptVaultAdminIx;
|
|
26
26
|
exports.createTripCircuitBreakerIx = createTripCircuitBreakerIx;
|
|
27
|
+
exports.createFreezeWithdrawRequestIx = createFreezeWithdrawRequestIx;
|
|
28
|
+
exports.createUnfreezeWithdrawRequestIx = createUnfreezeWithdrawRequestIx;
|
|
29
|
+
exports.createSetClaimRecipientIx = createSetClaimRecipientIx;
|
|
27
30
|
const web3_js_1 = require("@solana/web3.js");
|
|
28
31
|
const spl_token_1 = require("@solana/spl-token");
|
|
29
32
|
const buffer_1 = require("../common/buffer");
|
|
@@ -217,13 +220,15 @@ function createOverrideClaimWithdrawIx(args, programId = constants_1.PROGRAM_ID)
|
|
|
217
220
|
const { authority, config, user, stv, withdrawRequest, vaultAta, userBaseAta, feeReceiverBaseAta, baseMint, tokenProgram, remainingAccounts = [], autoUnrouteCount = 0, protocolAumCount = 0, } = args;
|
|
218
221
|
// Data: auto_unroute_count(1) + protocol_aum_count(1) — protocol_aum_count is data[1],
|
|
219
222
|
// so always serialize both bytes (handler reads data[0]/data[1]). Data layout
|
|
220
|
-
// is unchanged by warm-admin-guardrails — only the
|
|
223
|
+
// is unchanged by warm-admin-guardrails / withdrawal-freeze — only the
|
|
224
|
+
// account list (and user's signer flag) changed.
|
|
221
225
|
const data = Buffer.from([constants_1.IX_OVERRIDE_CLAIM_WITHDRAW, autoUnrouteCount & 0xff, protocolAumCount & 0xff]);
|
|
222
226
|
return new web3_js_1.TransactionInstruction({
|
|
223
227
|
keys: [
|
|
224
228
|
{ pubkey: authority, isSigner: true, isWritable: false },
|
|
225
229
|
{ pubkey: config, isSigner: false, isWritable: false },
|
|
226
|
-
|
|
230
|
+
// user is now a required signer, distinct from authority — see module doc.
|
|
231
|
+
{ pubkey: user, isSigner: true, isWritable: true },
|
|
227
232
|
{ pubkey: stv, isSigner: false, isWritable: true },
|
|
228
233
|
{ pubkey: withdrawRequest, isSigner: false, isWritable: true },
|
|
229
234
|
{ pubkey: vaultAta, isSigner: false, isWritable: true },
|
|
@@ -668,3 +673,44 @@ function createTripCircuitBreakerIx(args, programId = constants_1.PROGRAM_ID) {
|
|
|
668
673
|
data: Buffer.from([constants_1.IX_TRIP_CIRCUIT_BREAKER]),
|
|
669
674
|
});
|
|
670
675
|
}
|
|
676
|
+
function createFreezeWithdrawRequestIx(args, programId = constants_1.PROGRAM_ID) {
|
|
677
|
+
const { authority, stv, withdrawRequest, managerRole } = args;
|
|
678
|
+
return new web3_js_1.TransactionInstruction({
|
|
679
|
+
keys: [
|
|
680
|
+
{ pubkey: authority, isSigner: true, isWritable: false },
|
|
681
|
+
{ pubkey: stv, isSigner: false, isWritable: false },
|
|
682
|
+
{ pubkey: withdrawRequest, isSigner: false, isWritable: true },
|
|
683
|
+
{ pubkey: managerRole, isSigner: false, isWritable: false },
|
|
684
|
+
],
|
|
685
|
+
programId,
|
|
686
|
+
data: Buffer.from([constants_1.IX_FREEZE_WITHDRAW_REQUEST]),
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
function createUnfreezeWithdrawRequestIx(args, programId = constants_1.PROGRAM_ID) {
|
|
690
|
+
const { authority, stv, withdrawRequest } = args;
|
|
691
|
+
return new web3_js_1.TransactionInstruction({
|
|
692
|
+
keys: [
|
|
693
|
+
{ pubkey: authority, isSigner: true, isWritable: false },
|
|
694
|
+
{ pubkey: stv, isSigner: false, isWritable: false },
|
|
695
|
+
{ pubkey: withdrawRequest, isSigner: false, isWritable: true },
|
|
696
|
+
],
|
|
697
|
+
programId,
|
|
698
|
+
data: Buffer.from([constants_1.IX_UNFREEZE_WITHDRAW_REQUEST]),
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
function createSetClaimRecipientIx(args, programId = constants_1.PROGRAM_ID) {
|
|
702
|
+
const { authority, stv, withdrawRequest, recipient } = args;
|
|
703
|
+
const data = Buffer.concat([
|
|
704
|
+
Buffer.from([constants_1.IX_SET_CLAIM_RECIPIENT]),
|
|
705
|
+
recipient.toBuffer(),
|
|
706
|
+
]);
|
|
707
|
+
return new web3_js_1.TransactionInstruction({
|
|
708
|
+
keys: [
|
|
709
|
+
{ pubkey: authority, isSigner: true, isWritable: false },
|
|
710
|
+
{ pubkey: stv, isSigner: false, isWritable: false },
|
|
711
|
+
{ pubkey: withdrawRequest, isSigner: false, isWritable: true },
|
|
712
|
+
],
|
|
713
|
+
programId,
|
|
714
|
+
data,
|
|
715
|
+
});
|
|
716
|
+
}
|
|
@@ -125,6 +125,14 @@ export interface WithdrawRequest {
|
|
|
125
125
|
destVaultId: BN;
|
|
126
126
|
/** Migrate kind: minimum dest shares (slippage protection). Withdraw kind: 0. */
|
|
127
127
|
minDestShares: BN;
|
|
128
|
+
/**
|
|
129
|
+
* Incident-response redirect target for `execute_claim` payout (offset 120).
|
|
130
|
+
* `PublicKey.default` (`[0;32]`, the deployed zero state) = pay `user`,
|
|
131
|
+
* exactly today's behavior. A redirect is ARMED iff this is nonzero AND both
|
|
132
|
+
* `WR_FLAG_RECIPIENT_USER_OK` and `WR_FLAG_RECIPIENT_COLD_OK` are set on
|
|
133
|
+
* `requestFlags` — see `isRedirectArmed` (accounts.ts).
|
|
134
|
+
*/
|
|
135
|
+
claimRecipient: PublicKey;
|
|
128
136
|
}
|
|
129
137
|
export interface DelayedDepositRequest {
|
|
130
138
|
stv: PublicKey;
|
|
@@ -183,6 +191,8 @@ export interface WithdrawRequestedEvent {
|
|
|
183
191
|
user: PublicKey;
|
|
184
192
|
shares: BN;
|
|
185
193
|
epochId: number;
|
|
194
|
+
/** WithdrawRequest PDA (appended field, withdrawal-freeze feature). */
|
|
195
|
+
wr: PublicKey;
|
|
186
196
|
}
|
|
187
197
|
export interface WithdrawRequestIncreasedEvent {
|
|
188
198
|
name: "WithdrawRequestIncreased";
|
|
@@ -191,6 +201,8 @@ export interface WithdrawRequestIncreasedEvent {
|
|
|
191
201
|
additionalShares: BN;
|
|
192
202
|
totalShares: BN;
|
|
193
203
|
epochId: number;
|
|
204
|
+
/** WithdrawRequest PDA (appended field, withdrawal-freeze feature). */
|
|
205
|
+
wr: PublicKey;
|
|
194
206
|
}
|
|
195
207
|
export interface WithdrawClaimedEvent {
|
|
196
208
|
name: "WithdrawClaimed";
|
|
@@ -200,6 +212,15 @@ export interface WithdrawClaimedEvent {
|
|
|
200
212
|
baseAmount: BN;
|
|
201
213
|
withdrawalFeeBase: BN;
|
|
202
214
|
epochId: number;
|
|
215
|
+
/** WithdrawRequest PDA (appended field, withdrawal-freeze feature). */
|
|
216
|
+
wr: PublicKey;
|
|
217
|
+
/**
|
|
218
|
+
* Payout target: `user` unless the redirect was ARMED at claim time, in
|
|
219
|
+
* which case this is the stored `claimRecipient`.
|
|
220
|
+
*/
|
|
221
|
+
recipient: PublicKey;
|
|
222
|
+
/** ATA the payout was actually sent to: `ATA(recipient, baseMint)`. */
|
|
223
|
+
destination: PublicKey;
|
|
203
224
|
}
|
|
204
225
|
export interface DepositedToStrategyEvent {
|
|
205
226
|
name: "DepositedToStrategy";
|
|
@@ -268,6 +289,15 @@ export interface WithdrawOverrideClaimedEvent {
|
|
|
268
289
|
epochId: number;
|
|
269
290
|
dailyWithdrawnBase: BN;
|
|
270
291
|
dailyLimit: BN;
|
|
292
|
+
/** WithdrawRequest PDA (appended field, withdrawal-freeze feature). */
|
|
293
|
+
wr: PublicKey;
|
|
294
|
+
/**
|
|
295
|
+
* Payout target: `user` unless the redirect was ARMED at claim time, in
|
|
296
|
+
* which case this is the stored `claimRecipient`.
|
|
297
|
+
*/
|
|
298
|
+
recipient: PublicKey;
|
|
299
|
+
/** ATA the payout was actually sent to: `ATA(recipient, baseMint)`. */
|
|
300
|
+
destination: PublicKey;
|
|
271
301
|
}
|
|
272
302
|
export interface LendMigratedEvent {
|
|
273
303
|
name: "LendMigrated";
|
|
@@ -284,6 +314,8 @@ export interface MigrateRequestedEvent {
|
|
|
284
314
|
user: PublicKey;
|
|
285
315
|
shares: BN;
|
|
286
316
|
epochId: number;
|
|
317
|
+
/** WithdrawRequest (migrate-kind) PDA (appended field, withdrawal-freeze feature). */
|
|
318
|
+
wr: PublicKey;
|
|
287
319
|
}
|
|
288
320
|
export interface MigrateExecutedEvent {
|
|
289
321
|
name: "MigrateExecuted";
|
|
@@ -296,6 +328,8 @@ export interface MigrateExecutedEvent {
|
|
|
296
328
|
depositFeeBase: BN;
|
|
297
329
|
userDestShares: BN;
|
|
298
330
|
epochId: number;
|
|
331
|
+
/** WithdrawRequest (migrate-kind) PDA (appended field, withdrawal-freeze feature). */
|
|
332
|
+
wr: PublicKey;
|
|
299
333
|
}
|
|
300
334
|
export interface DelayedDepositProcessedEvent {
|
|
301
335
|
name: "DelayedDepositProcessed";
|
|
@@ -358,4 +392,43 @@ export interface CircuitBreakerTrippedEvent {
|
|
|
358
392
|
trippedBy: PublicKey;
|
|
359
393
|
authorityKind: number;
|
|
360
394
|
}
|
|
361
|
-
|
|
395
|
+
/**
|
|
396
|
+
* Emitted by `freeze_withdraw_request` (disc 22).
|
|
397
|
+
* `authorityKind`: 0 = user (self-freeze), 1 = manager
|
|
398
|
+
* (see `FREEZE_AUTHORITY_KIND_*` in constants.ts).
|
|
399
|
+
*/
|
|
400
|
+
export interface WithdrawRequestFrozenEvent {
|
|
401
|
+
name: "WithdrawRequestFrozen";
|
|
402
|
+
wr: PublicKey;
|
|
403
|
+
stv: PublicKey;
|
|
404
|
+
user: PublicKey;
|
|
405
|
+
epochId: number;
|
|
406
|
+
authority: PublicKey;
|
|
407
|
+
authorityKind: number;
|
|
408
|
+
}
|
|
409
|
+
/** Emitted by `unfreeze_withdraw_request` (disc 23). */
|
|
410
|
+
export interface WithdrawRequestUnfrozenEvent {
|
|
411
|
+
name: "WithdrawRequestUnfrozen";
|
|
412
|
+
wr: PublicKey;
|
|
413
|
+
stv: PublicKey;
|
|
414
|
+
user: PublicKey;
|
|
415
|
+
epochId: number;
|
|
416
|
+
authority: PublicKey;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Emitted by `set_claim_recipient` (disc 24).
|
|
420
|
+
* `approverKind`: 0 = user, 1 = cold (see `RECIPIENT_APPROVER_KIND_*` in
|
|
421
|
+
* constants.ts). `armed` mirrors `WithdrawRequest.isRedirectArmed()` as of
|
|
422
|
+
* this call.
|
|
423
|
+
*/
|
|
424
|
+
export interface ClaimRecipientSetEvent {
|
|
425
|
+
name: "ClaimRecipientSet";
|
|
426
|
+
wr: PublicKey;
|
|
427
|
+
stv: PublicKey;
|
|
428
|
+
user: PublicKey;
|
|
429
|
+
epochId: number;
|
|
430
|
+
recipient: PublicKey;
|
|
431
|
+
approverKind: number;
|
|
432
|
+
armed: boolean;
|
|
433
|
+
}
|
|
434
|
+
export type StvEvent = ConfigInitializedEvent | ConfigUpdatedEvent | StvCreatedEvent | StvUpdatedEvent | DepositedEvent | WithdrawRequestedEvent | WithdrawRequestIncreasedEvent | WithdrawClaimedEvent | DepositedToStrategyEvent | WithdrawnFromStrategyEvent | EpochProcessedEvent | EpochAdvancedEvent | FeesSettledEvent | StvClosedEvent | ManagerAddedEvent | ManagerRemovedEvent | WithdrawOverrideClaimedEvent | LendMigratedEvent | MigrateRequestedEvent | MigrateExecutedEvent | DelayedDepositProcessedEvent | InstantWithdrawnEvent | StvSeededEvent | AdminRotationStartedEvent | AdminRotationAcceptedEvent | WarmAdminSetEvent | CircuitBreakerTrippedEvent | WithdrawRequestFrozenEvent | WithdrawRequestUnfrozenEvent | ClaimRecipientSetEvent;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elmntl/jlpd-sdk",
|
|
3
|
-
"version": "0.13.
|
|
4
|
-
"description": "SDK for JLP.D (JLP Deconstructed) by Elemental
|
|
3
|
+
"version": "0.13.7",
|
|
4
|
+
"description": "SDK for JLP.D (JLP Deconstructed) by Elemental — p-stv-core, jlpd-strategy, and elemental-lend clients",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"solana",
|
|
@@ -70,4 +70,4 @@
|
|
|
70
70
|
"publishConfig": {
|
|
71
71
|
"access": "public"
|
|
72
72
|
}
|
|
73
|
-
}
|
|
73
|
+
}
|