@epicentral/sos-sdk 0.9.1-beta → 0.10.1-beta
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 +14 -2
- package/accounts/fetchers.ts +79 -9
- package/accounts/list.ts +12 -6
- package/accounts/resolve-option.ts +60 -19
- package/generated/accounts/collateralPool.ts +29 -1
- package/generated/accounts/makerCollateralShare.ts +9 -1
- package/generated/errors/optionProgram.ts +48 -36
- package/generated/instructions/autoExerciseAllExpired.ts +32 -86
- package/generated/instructions/autoExerciseExpired.ts +38 -95
- package/generated/instructions/claimMakerRemaining.ts +452 -0
- package/generated/instructions/depositCollateral.ts +6 -6
- package/generated/instructions/index.ts +1 -0
- package/generated/instructions/initCollateralPool.ts +3 -3
- package/generated/instructions/settleMakerCollateral.ts +50 -74
- package/generated/programs/optionProgram.ts +24 -0
- package/package.json +1 -1
- package/short/builders.ts +8 -8
package/README.md
CHANGED
|
@@ -63,7 +63,8 @@ Additional modules:
|
|
|
63
63
|
| `buildUnwindWriterUnsoldTransactionWithDerivation` | Builds unwind unsold transaction. |
|
|
64
64
|
| `buildUnwindWriterUnsoldWithLoanRepayment` | **Unwind + repay pool loans in one tx.** Use when closing unsold shorts that borrowed from OMLP. |
|
|
65
65
|
| `buildSyncWriterPositionTransaction` | Syncs writer position with pool accumulators. |
|
|
66
|
-
| `buildSettleMakerCollateralTransaction` |
|
|
66
|
+
| `buildSettleMakerCollateralTransaction` | Expiry Phase A: repays one active loan's principal + accrued interest to OMLP from collateral vault. Writers with multiple loans for the expired option call it once per loan; maker residual is claimed separately. |
|
|
67
|
+
| `getClaimMakerRemainingInstructionAsync` | Expiry Phase C generated instruction: returns remaining maker collateral after Phase B buyer payouts complete. |
|
|
67
68
|
| `buildCloseOptionTransaction` | Closes option token account. |
|
|
68
69
|
| `buildClaimThetaTransaction` | Claims theta (time-decay share) for writer. |
|
|
69
70
|
| `buildRepayPoolLoanFromCollateralInstruction` | Repays pool loan from collateral (short/pool). |
|
|
@@ -77,8 +78,19 @@ Additional modules:
|
|
|
77
78
|
- On-chain transfers for lender repayment and collateral return are authorized by program PDAs (`collateral_pool` / `option_pool`) where applicable.
|
|
78
79
|
- `buildSettleMakerCollateralTransaction`
|
|
79
80
|
- No maker transaction signer is required by this instruction format.
|
|
80
|
-
- On-chain repayment (`collateral_vault` -> `omlp_vault`)
|
|
81
|
+
- On-chain repayment (`collateral_vault` -> `omlp_vault`) is signed by the `collateral_pool` PDA.
|
|
81
82
|
- Lender repayment is sourced from collateral vault funds, not maker wallet funds.
|
|
83
|
+
- Expiry residual maker collateral is returned later by `claim_maker_remaining` after buyer payout Phase B.
|
|
84
|
+
|
|
85
|
+
### Expiry Settlement
|
|
86
|
+
|
|
87
|
+
Expiry settlement is lender-first and split across three instructions:
|
|
88
|
+
|
|
89
|
+
1. `settle_maker_collateral` (Phase A) for every non-liquidated maker. Lender repayment is paid to the loan vault's ATA for the pool collateral mint, so devnet fake SOL/USDC pools and mainnet WSOL pools use the same mint-safe path. If a writer has multiple active `PoolLoan` accounts for that expired option, keepers submit one Phase A transaction per loan; the maker share is not marked Phase A settled until all are repaid.
|
|
90
|
+
2. `auto_exercise_expired` / `auto_exercise_all_expired` (Phase B) for buyers, capped by `eligible_maker_pot`; options with zero buyer positions are considered buyer-settled so maker claims do not stall. The single and batch paths take the collateral/settlement mint so cash-settled payouts use the correct token decimals; batch remaining accounts must pair each position with that buyer's token account for the same mint.
|
|
91
|
+
3. `claim_maker_remaining` (Phase C) for makers after `phase_b_complete`, returning residual collateral in the pool collateral mint.
|
|
92
|
+
|
|
93
|
+
New program errors exposed in the IDL: `LenderRepaymentNotComplete`, `BuyerPayoutNotComplete`, and `MakerLiquidated`.
|
|
82
94
|
|
|
83
95
|
### OMLP (Lending)
|
|
84
96
|
|
package/accounts/fetchers.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
+
COLLATERAL_POOL_DISCRIMINATOR,
|
|
3
|
+
OPTION_POOL_DISCRIMINATOR,
|
|
2
4
|
getCollateralPoolDecoder,
|
|
3
5
|
getLenderPositionDecoder,
|
|
4
6
|
getMarketDataAccountDecoder,
|
|
@@ -19,10 +21,74 @@ import {
|
|
|
19
21
|
type WriterPosition,
|
|
20
22
|
} from "../generated/accounts";
|
|
21
23
|
import type { Address } from "@solana/kit";
|
|
24
|
+
import bs58 from "bs58";
|
|
22
25
|
import { toAddress } from "../client/program";
|
|
23
26
|
import type { AddressLike, KitRpc } from "../client/types";
|
|
24
27
|
|
|
25
|
-
|
|
28
|
+
/** Anchor `CollateralPool`: discriminator + option_account (32) + collateral_mint (32), then collateral_vault. */
|
|
29
|
+
const COLLATERAL_POOL_COLLATERAL_VAULT_OFFSET =
|
|
30
|
+
COLLATERAL_POOL_DISCRIMINATOR.length + 32 + 32;
|
|
31
|
+
|
|
32
|
+
/** Sequential pubkeys before numeric fields (`option_pool` Anchor layout). */
|
|
33
|
+
const OPTION_POOL_UNDERLYING_MINT_OFFSET =
|
|
34
|
+
OPTION_POOL_DISCRIMINATOR.length + 32 + 32 + 32;
|
|
35
|
+
const OPTION_POOL_ESCROW_LONG_OFFSET = OPTION_POOL_UNDERLYING_MINT_OFFSET + 32;
|
|
36
|
+
const OPTION_POOL_PREMIUM_VAULT_OFFSET = OPTION_POOL_ESCROW_LONG_OFFSET + 32;
|
|
37
|
+
|
|
38
|
+
function discriminatorMatches(expected: Uint8Array, data: Uint8Array): boolean {
|
|
39
|
+
if (data.length < expected.length) return false;
|
|
40
|
+
for (let i = 0; i < expected.length; i++) {
|
|
41
|
+
if (data[i] !== expected[i]!) return false;
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function collateralPoolDiscriminatorMatches(data: Uint8Array): boolean {
|
|
47
|
+
return discriminatorMatches(COLLATERAL_POOL_DISCRIMINATOR, data);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function optionPoolDiscriminatorMatches(data: Uint8Array): boolean {
|
|
51
|
+
return discriminatorMatches(OPTION_POOL_DISCRIMINATOR, data);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* If full `OptionPool` decode fails, read the pubkey fields layout-traders need for resolving pool routes.
|
|
56
|
+
*/
|
|
57
|
+
export function decodeOptionPoolTradePubkeysFromRawData(data: Uint8Array): {
|
|
58
|
+
underlyingMint: Address;
|
|
59
|
+
escrowLongAccount: Address;
|
|
60
|
+
premiumVault: Address;
|
|
61
|
+
} | undefined {
|
|
62
|
+
const end = OPTION_POOL_PREMIUM_VAULT_OFFSET + 32;
|
|
63
|
+
if (data.length < end) return undefined;
|
|
64
|
+
if (!optionPoolDiscriminatorMatches(data)) return undefined;
|
|
65
|
+
return {
|
|
66
|
+
underlyingMint: toAddress(
|
|
67
|
+
bs58.encode(data.subarray(OPTION_POOL_UNDERLYING_MINT_OFFSET, OPTION_POOL_UNDERLYING_MINT_OFFSET + 32)),
|
|
68
|
+
),
|
|
69
|
+
escrowLongAccount: toAddress(
|
|
70
|
+
bs58.encode(data.subarray(OPTION_POOL_ESCROW_LONG_OFFSET, OPTION_POOL_ESCROW_LONG_OFFSET + 32)),
|
|
71
|
+
),
|
|
72
|
+
premiumVault: toAddress(
|
|
73
|
+
bs58.encode(data.subarray(OPTION_POOL_PREMIUM_VAULT_OFFSET, OPTION_POOL_PREMIUM_VAULT_OFFSET + 32)),
|
|
74
|
+
),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* If full Codama decode fails (IDL / deployed account size mismatch), read `collateral_vault`
|
|
80
|
+
* from the fixed Anchor field order. This is sufficient for txs that only need vault + pool PDAs.
|
|
81
|
+
*/
|
|
82
|
+
export function decodeCollateralVaultFromCollateralPoolRawData(
|
|
83
|
+
data: Uint8Array
|
|
84
|
+
): Address | undefined {
|
|
85
|
+
const end = COLLATERAL_POOL_COLLATERAL_VAULT_OFFSET + 32;
|
|
86
|
+
if (data.length < end) return undefined;
|
|
87
|
+
if (!collateralPoolDiscriminatorMatches(data)) return undefined;
|
|
88
|
+
return toAddress(bs58.encode(data.subarray(COLLATERAL_POOL_COLLATERAL_VAULT_OFFSET, end)));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function fetchAccountData(
|
|
26
92
|
rpc: KitRpc,
|
|
27
93
|
address: AddressLike
|
|
28
94
|
): Promise<Uint8Array | null> {
|
|
@@ -32,7 +98,7 @@ async function fetchRawAccount(
|
|
|
32
98
|
const [data] = accountInfo.data;
|
|
33
99
|
const binary = atob(data);
|
|
34
100
|
const bytes = new Uint8Array(binary.length);
|
|
35
|
-
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)
|
|
101
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)!;
|
|
36
102
|
return bytes;
|
|
37
103
|
}
|
|
38
104
|
|
|
@@ -41,9 +107,13 @@ async function decodeAccount<T>(
|
|
|
41
107
|
address: AddressLike,
|
|
42
108
|
decoder: { decode: (value: Uint8Array) => T }
|
|
43
109
|
): Promise<T | null> {
|
|
44
|
-
const data = await
|
|
110
|
+
const data = await fetchAccountData(rpc, address);
|
|
45
111
|
if (!data) return null;
|
|
46
|
-
|
|
112
|
+
try {
|
|
113
|
+
return decoder.decode(data);
|
|
114
|
+
} catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
47
117
|
}
|
|
48
118
|
|
|
49
119
|
export async function fetchOptionAccount(
|
|
@@ -148,21 +218,21 @@ export async function fetchOptionAccounts(
|
|
|
148
218
|
for (let i = 0; i < keys.length; i++) {
|
|
149
219
|
const accountInfo = infos[i];
|
|
150
220
|
if (!accountInfo) {
|
|
151
|
-
result.set(keys[i]
|
|
221
|
+
result.set(keys[i]!, null);
|
|
152
222
|
continue;
|
|
153
223
|
}
|
|
154
224
|
const [b64] = accountInfo.data;
|
|
155
225
|
if (!b64) {
|
|
156
|
-
result.set(keys[i]
|
|
226
|
+
result.set(keys[i]!, null);
|
|
157
227
|
continue;
|
|
158
228
|
}
|
|
159
229
|
const binary = atob(b64);
|
|
160
230
|
const data = new Uint8Array(binary.length);
|
|
161
|
-
for (let j = 0; j < binary.length; j++) data[j] = binary.charCodeAt(j)
|
|
231
|
+
for (let j = 0; j < binary.length; j++) data[j] = binary.charCodeAt(j)!;
|
|
162
232
|
try {
|
|
163
|
-
result.set(keys[i]
|
|
233
|
+
result.set(keys[i]!, optionDecoder.decode(data));
|
|
164
234
|
} catch {
|
|
165
|
-
result.set(keys[i]
|
|
235
|
+
result.set(keys[i]!, null);
|
|
166
236
|
}
|
|
167
237
|
}
|
|
168
238
|
return result;
|
package/accounts/list.ts
CHANGED
|
@@ -97,14 +97,20 @@ async function fetchAndDecodeProgramAccounts<T>(
|
|
|
97
97
|
? (response as Array<ProgramAccountResponse>)
|
|
98
98
|
: (response as { value: Array<ProgramAccountResponse> }).value;
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
const out: Array<ListedAccount<T>> = [];
|
|
101
|
+
for (const { pubkey, account } of rawAccounts) {
|
|
101
102
|
const base64Data =
|
|
102
103
|
Array.isArray(account.data) ? account.data[0] : account.data;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
try {
|
|
105
|
+
out.push({
|
|
106
|
+
address: pubkey,
|
|
107
|
+
data: decoder.decode(decodeBase64Data(base64Data)),
|
|
108
|
+
});
|
|
109
|
+
} catch {
|
|
110
|
+
/** Skip malformed / IDL-size mismatches instead of throwing from getProgramAccounts. */
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
108
114
|
}
|
|
109
115
|
|
|
110
116
|
export async function fetchWriterPositionsByWriter(
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import type { Address } from "@solana/kit";
|
|
2
2
|
import { OptionType } from "../generated/types";
|
|
3
|
-
import { toAddress } from "../client/program";
|
|
4
3
|
import type { AddressLike, KitRpc } from "../client/types";
|
|
4
|
+
import type { CollateralPool, OptionAccount, OptionPool } from "../generated/accounts";
|
|
5
|
+
import {
|
|
6
|
+
getCollateralPoolDecoder,
|
|
7
|
+
getOptionAccountDecoder,
|
|
8
|
+
getOptionPoolDecoder,
|
|
9
|
+
} from "../generated/accounts";
|
|
5
10
|
import {
|
|
6
11
|
deriveCollateralPoolPda,
|
|
7
12
|
deriveLongMintPda,
|
|
@@ -11,7 +16,11 @@ import {
|
|
|
11
16
|
deriveOptionPoolPda,
|
|
12
17
|
deriveShortMintPda,
|
|
13
18
|
} from "./pdas";
|
|
14
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
decodeCollateralVaultFromCollateralPoolRawData,
|
|
21
|
+
decodeOptionPoolTradePubkeysFromRawData,
|
|
22
|
+
fetchAccountData,
|
|
23
|
+
} from "./fetchers";
|
|
15
24
|
|
|
16
25
|
export interface ResolveOptionAccountsParams {
|
|
17
26
|
underlyingAsset: AddressLike;
|
|
@@ -34,9 +43,9 @@ export interface ResolvedOptionAccounts {
|
|
|
34
43
|
escrowLongAccount?: Address;
|
|
35
44
|
premiumVault?: Address;
|
|
36
45
|
collateralVault?: Address;
|
|
37
|
-
optionPoolData?:
|
|
38
|
-
optionAccountData?:
|
|
39
|
-
collateralPoolData?:
|
|
46
|
+
optionPoolData?: OptionPool;
|
|
47
|
+
optionAccountData?: OptionAccount;
|
|
48
|
+
collateralPoolData?: CollateralPool;
|
|
40
49
|
}
|
|
41
50
|
|
|
42
51
|
/**
|
|
@@ -76,27 +85,59 @@ export async function resolveOptionAccounts(
|
|
|
76
85
|
};
|
|
77
86
|
|
|
78
87
|
if (params.rpc) {
|
|
79
|
-
const
|
|
88
|
+
const optionPoolDecoder = getOptionPoolDecoder();
|
|
89
|
+
const optionAccountDecoder = getOptionAccountDecoder();
|
|
90
|
+
const collateralPoolDecoder = getCollateralPoolDecoder();
|
|
91
|
+
const [optionPoolBytes, optionAccountBytes, collateralPoolBytes] =
|
|
80
92
|
await Promise.all([
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
93
|
+
fetchAccountData(params.rpc, optionPool),
|
|
94
|
+
fetchAccountData(params.rpc, optionAccount),
|
|
95
|
+
fetchAccountData(params.rpc, collateralPool),
|
|
84
96
|
]);
|
|
85
97
|
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
98
|
+
if (optionPoolBytes) {
|
|
99
|
+
let optionPoolDecoded: OptionPool | null = null;
|
|
100
|
+
try {
|
|
101
|
+
optionPoolDecoded = optionPoolDecoder.decode(optionPoolBytes);
|
|
102
|
+
} catch {
|
|
103
|
+
optionPoolDecoded = null;
|
|
104
|
+
}
|
|
105
|
+
if (optionPoolDecoded) {
|
|
106
|
+
result.optionPoolData = optionPoolDecoded;
|
|
107
|
+
result.escrowLongAccount = optionPoolDecoded.escrowLongAccount;
|
|
108
|
+
result.premiumVault = optionPoolDecoded.premiumVault;
|
|
109
|
+
result.underlyingMint = optionPoolDecoded.underlyingMint;
|
|
110
|
+
} else {
|
|
111
|
+
const tradePubkeys =
|
|
112
|
+
decodeOptionPoolTradePubkeysFromRawData(optionPoolBytes);
|
|
113
|
+
if (tradePubkeys) {
|
|
114
|
+
result.escrowLongAccount = tradePubkeys.escrowLongAccount;
|
|
115
|
+
result.premiumVault = tradePubkeys.premiumVault;
|
|
116
|
+
result.underlyingMint = tradePubkeys.underlyingMint;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
91
119
|
}
|
|
92
120
|
|
|
93
|
-
if (
|
|
94
|
-
|
|
121
|
+
if (optionAccountBytes) {
|
|
122
|
+
try {
|
|
123
|
+
result.optionAccountData = optionAccountDecoder.decode(optionAccountBytes);
|
|
124
|
+
} catch {
|
|
125
|
+
/* layout drift: PDAs remain valid; Greeks-only consumers see no OptionAccount snapshot */
|
|
126
|
+
}
|
|
95
127
|
}
|
|
96
128
|
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
|
|
129
|
+
if (collateralPoolBytes) {
|
|
130
|
+
try {
|
|
131
|
+
const collateralPoolFetched = collateralPoolDecoder.decode(collateralPoolBytes);
|
|
132
|
+
result.collateralPoolData = collateralPoolFetched;
|
|
133
|
+
result.collateralVault = collateralPoolFetched.collateralVault;
|
|
134
|
+
} catch {
|
|
135
|
+
const vaultFallback =
|
|
136
|
+
decodeCollateralVaultFromCollateralPoolRawData(collateralPoolBytes);
|
|
137
|
+
if (vaultFallback) {
|
|
138
|
+
result.collateralVault = vaultFallback;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
100
141
|
}
|
|
101
142
|
}
|
|
102
143
|
|
|
@@ -70,6 +70,13 @@ export type CollateralPool = {
|
|
|
70
70
|
makerCount: number;
|
|
71
71
|
isExercised: boolean;
|
|
72
72
|
isFullySettled: boolean;
|
|
73
|
+
phaseAComplete: boolean;
|
|
74
|
+
phaseBComplete: boolean;
|
|
75
|
+
eligibleMakerPot: bigint;
|
|
76
|
+
remainingMakerPostDebtCollateral: bigint;
|
|
77
|
+
eligibleMakerCount: number;
|
|
78
|
+
makersPhaseASettled: number;
|
|
79
|
+
totalBuyerIntrinsicOwedSnapshot: bigint;
|
|
73
80
|
createdAt: bigint;
|
|
74
81
|
lastUpdated: bigint;
|
|
75
82
|
bump: number;
|
|
@@ -89,6 +96,13 @@ export type CollateralPoolArgs = {
|
|
|
89
96
|
makerCount: number;
|
|
90
97
|
isExercised: boolean;
|
|
91
98
|
isFullySettled: boolean;
|
|
99
|
+
phaseAComplete: boolean;
|
|
100
|
+
phaseBComplete: boolean;
|
|
101
|
+
eligibleMakerPot: number | bigint;
|
|
102
|
+
remainingMakerPostDebtCollateral: number | bigint;
|
|
103
|
+
eligibleMakerCount: number;
|
|
104
|
+
makersPhaseASettled: number;
|
|
105
|
+
totalBuyerIntrinsicOwedSnapshot: number | bigint;
|
|
92
106
|
createdAt: number | bigint;
|
|
93
107
|
lastUpdated: number | bigint;
|
|
94
108
|
bump: number;
|
|
@@ -112,6 +126,13 @@ export function getCollateralPoolEncoder(): FixedSizeEncoder<CollateralPoolArgs>
|
|
|
112
126
|
["makerCount", getU32Encoder()],
|
|
113
127
|
["isExercised", getBooleanEncoder()],
|
|
114
128
|
["isFullySettled", getBooleanEncoder()],
|
|
129
|
+
["phaseAComplete", getBooleanEncoder()],
|
|
130
|
+
["phaseBComplete", getBooleanEncoder()],
|
|
131
|
+
["eligibleMakerPot", getU64Encoder()],
|
|
132
|
+
["remainingMakerPostDebtCollateral", getU64Encoder()],
|
|
133
|
+
["eligibleMakerCount", getU32Encoder()],
|
|
134
|
+
["makersPhaseASettled", getU32Encoder()],
|
|
135
|
+
["totalBuyerIntrinsicOwedSnapshot", getU64Encoder()],
|
|
115
136
|
["createdAt", getI64Encoder()],
|
|
116
137
|
["lastUpdated", getI64Encoder()],
|
|
117
138
|
["bump", getU8Encoder()],
|
|
@@ -137,6 +158,13 @@ export function getCollateralPoolDecoder(): FixedSizeDecoder<CollateralPool> {
|
|
|
137
158
|
["makerCount", getU32Decoder()],
|
|
138
159
|
["isExercised", getBooleanDecoder()],
|
|
139
160
|
["isFullySettled", getBooleanDecoder()],
|
|
161
|
+
["phaseAComplete", getBooleanDecoder()],
|
|
162
|
+
["phaseBComplete", getBooleanDecoder()],
|
|
163
|
+
["eligibleMakerPot", getU64Decoder()],
|
|
164
|
+
["remainingMakerPostDebtCollateral", getU64Decoder()],
|
|
165
|
+
["eligibleMakerCount", getU32Decoder()],
|
|
166
|
+
["makersPhaseASettled", getU32Decoder()],
|
|
167
|
+
["totalBuyerIntrinsicOwedSnapshot", getU64Decoder()],
|
|
140
168
|
["createdAt", getI64Decoder()],
|
|
141
169
|
["lastUpdated", getI64Decoder()],
|
|
142
170
|
["bump", getU8Decoder()],
|
|
@@ -213,5 +241,5 @@ export async function fetchAllMaybeCollateralPool(
|
|
|
213
241
|
}
|
|
214
242
|
|
|
215
243
|
export function getCollateralPoolSize(): number {
|
|
216
|
-
return
|
|
244
|
+
return 217;
|
|
217
245
|
}
|
|
@@ -65,7 +65,9 @@ export type MakerCollateralShare = {
|
|
|
65
65
|
premiumCollected: bigint;
|
|
66
66
|
exercisePayout: bigint;
|
|
67
67
|
lenderRepayment: bigint;
|
|
68
|
+
postDebtCollateral: bigint;
|
|
68
69
|
makerReturn: bigint;
|
|
70
|
+
phaseASettled: boolean;
|
|
69
71
|
isSettled: boolean;
|
|
70
72
|
realizedPnl: bigint;
|
|
71
73
|
createdAt: bigint;
|
|
@@ -84,7 +86,9 @@ export type MakerCollateralShareArgs = {
|
|
|
84
86
|
premiumCollected: number | bigint;
|
|
85
87
|
exercisePayout: number | bigint;
|
|
86
88
|
lenderRepayment: number | bigint;
|
|
89
|
+
postDebtCollateral: number | bigint;
|
|
87
90
|
makerReturn: number | bigint;
|
|
91
|
+
phaseASettled: boolean;
|
|
88
92
|
isSettled: boolean;
|
|
89
93
|
realizedPnl: number | bigint;
|
|
90
94
|
createdAt: number | bigint;
|
|
@@ -107,7 +111,9 @@ export function getMakerCollateralShareEncoder(): FixedSizeEncoder<MakerCollater
|
|
|
107
111
|
["premiumCollected", getU64Encoder()],
|
|
108
112
|
["exercisePayout", getU64Encoder()],
|
|
109
113
|
["lenderRepayment", getU64Encoder()],
|
|
114
|
+
["postDebtCollateral", getU64Encoder()],
|
|
110
115
|
["makerReturn", getU64Encoder()],
|
|
116
|
+
["phaseASettled", getBooleanEncoder()],
|
|
111
117
|
["isSettled", getBooleanEncoder()],
|
|
112
118
|
["realizedPnl", getI64Encoder()],
|
|
113
119
|
["createdAt", getI64Encoder()],
|
|
@@ -135,7 +141,9 @@ export function getMakerCollateralShareDecoder(): FixedSizeDecoder<MakerCollater
|
|
|
135
141
|
["premiumCollected", getU64Decoder()],
|
|
136
142
|
["exercisePayout", getU64Decoder()],
|
|
137
143
|
["lenderRepayment", getU64Decoder()],
|
|
144
|
+
["postDebtCollateral", getU64Decoder()],
|
|
138
145
|
["makerReturn", getU64Decoder()],
|
|
146
|
+
["phaseASettled", getBooleanDecoder()],
|
|
139
147
|
["isSettled", getBooleanDecoder()],
|
|
140
148
|
["realizedPnl", getI64Decoder()],
|
|
141
149
|
["createdAt", getI64Decoder()],
|
|
@@ -225,5 +233,5 @@ export async function fetchAllMaybeMakerCollateralShare(
|
|
|
225
233
|
}
|
|
226
234
|
|
|
227
235
|
export function getMakerCollateralShareSize(): number {
|
|
228
|
-
return
|
|
236
|
+
return 203;
|
|
229
237
|
}
|
|
@@ -154,78 +154,84 @@ export const OPTION_PROGRAM_ERROR__COLLATERAL_POOL_NOT_FOUND = 0x17b3; // 6067
|
|
|
154
154
|
export const OPTION_PROGRAM_ERROR__NO_COLLATERAL_TO_WITHDRAW = 0x17b4; // 6068
|
|
155
155
|
/** OptionNotExpired: Option has not expired yet - cannot settle */
|
|
156
156
|
export const OPTION_PROGRAM_ERROR__OPTION_NOT_EXPIRED = 0x17b5; // 6069
|
|
157
|
+
/** LenderRepaymentNotComplete: Lender repayment phase is not complete */
|
|
158
|
+
export const OPTION_PROGRAM_ERROR__LENDER_REPAYMENT_NOT_COMPLETE = 0x17b6; // 6070
|
|
159
|
+
/** BuyerPayoutNotComplete: Buyer payout phase is not complete */
|
|
160
|
+
export const OPTION_PROGRAM_ERROR__BUYER_PAYOUT_NOT_COMPLETE = 0x17b7; // 6071
|
|
161
|
+
/** MakerLiquidated: Maker was liquidated and is excluded from expiry settlement */
|
|
162
|
+
export const OPTION_PROGRAM_ERROR__MAKER_LIQUIDATED = 0x17b8; // 6072
|
|
157
163
|
/** SupplyLimitExceeded: Deposit would exceed vault supply limit */
|
|
158
|
-
export const OPTION_PROGRAM_ERROR__SUPPLY_LIMIT_EXCEEDED =
|
|
164
|
+
export const OPTION_PROGRAM_ERROR__SUPPLY_LIMIT_EXCEEDED = 0x17b9; // 6073
|
|
159
165
|
/** InvalidFeeWallet: Invalid fee wallet - must match protocol constant */
|
|
160
|
-
export const OPTION_PROGRAM_ERROR__INVALID_FEE_WALLET =
|
|
166
|
+
export const OPTION_PROGRAM_ERROR__INVALID_FEE_WALLET = 0x17ba; // 6074
|
|
161
167
|
/** InvalidProtocolFee: Invalid protocol fee rate */
|
|
162
|
-
export const OPTION_PROGRAM_ERROR__INVALID_PROTOCOL_FEE =
|
|
168
|
+
export const OPTION_PROGRAM_ERROR__INVALID_PROTOCOL_FEE = 0x17bb; // 6075
|
|
163
169
|
/** UnderlyingAssetMismatch: Underlying asset mismatch - market data or mint does not match option */
|
|
164
|
-
export const OPTION_PROGRAM_ERROR__UNDERLYING_ASSET_MISMATCH =
|
|
170
|
+
export const OPTION_PROGRAM_ERROR__UNDERLYING_ASSET_MISMATCH = 0x17bc; // 6076
|
|
165
171
|
/** InvalidMint: Invalid token mint - does not match expected underlying asset */
|
|
166
|
-
export const OPTION_PROGRAM_ERROR__INVALID_MINT =
|
|
172
|
+
export const OPTION_PROGRAM_ERROR__INVALID_MINT = 0x17bd; // 6077
|
|
167
173
|
/** BatchSizeExceeded: Batch size exceeds maximum allowed (10 positions) */
|
|
168
|
-
export const OPTION_PROGRAM_ERROR__BATCH_SIZE_EXCEEDED =
|
|
174
|
+
export const OPTION_PROGRAM_ERROR__BATCH_SIZE_EXCEEDED = 0x17be; // 6078
|
|
169
175
|
/** NoPositionsProvided: No positions provided in batch */
|
|
170
|
-
export const OPTION_PROGRAM_ERROR__NO_POSITIONS_PROVIDED =
|
|
176
|
+
export const OPTION_PROGRAM_ERROR__NO_POSITIONS_PROVIDED = 0x17bf; // 6079
|
|
171
177
|
/** PositionOptionMismatch: Position account does not belong to this option */
|
|
172
|
-
export const OPTION_PROGRAM_ERROR__POSITION_OPTION_MISMATCH =
|
|
178
|
+
export const OPTION_PROGRAM_ERROR__POSITION_OPTION_MISMATCH = 0x17c0; // 6080
|
|
173
179
|
/** OptionPoolMismatch: Option account does not match the option pool's option account */
|
|
174
|
-
export const OPTION_PROGRAM_ERROR__OPTION_POOL_MISMATCH =
|
|
180
|
+
export const OPTION_PROGRAM_ERROR__OPTION_POOL_MISMATCH = 0x17c1; // 6081
|
|
175
181
|
/** InvalidSeed: Invalid seed - must be exactly 32 bytes */
|
|
176
|
-
export const OPTION_PROGRAM_ERROR__INVALID_SEED =
|
|
182
|
+
export const OPTION_PROGRAM_ERROR__INVALID_SEED = 0x17c2; // 6082
|
|
177
183
|
/** InvalidAuthority: Invalid authority - does not match escrow authority */
|
|
178
|
-
export const OPTION_PROGRAM_ERROR__INVALID_AUTHORITY =
|
|
184
|
+
export const OPTION_PROGRAM_ERROR__INVALID_AUTHORITY = 0x17c3; // 6083
|
|
179
185
|
/** EscrowAccountRequired: Escrow accounts required when borrowed_amount > 0 */
|
|
180
|
-
export const OPTION_PROGRAM_ERROR__ESCROW_ACCOUNT_REQUIRED =
|
|
186
|
+
export const OPTION_PROGRAM_ERROR__ESCROW_ACCOUNT_REQUIRED = 0x17c4; // 6084
|
|
181
187
|
/** InvalidEscrowMaker: Escrow state maker does not match instruction maker */
|
|
182
|
-
export const OPTION_PROGRAM_ERROR__INVALID_ESCROW_MAKER =
|
|
188
|
+
export const OPTION_PROGRAM_ERROR__INVALID_ESCROW_MAKER = 0x17c5; // 6085
|
|
183
189
|
/** EscrowMintMismatch: Escrow collateral mint does not match collateral pool mint */
|
|
184
|
-
export const OPTION_PROGRAM_ERROR__ESCROW_MINT_MISMATCH =
|
|
190
|
+
export const OPTION_PROGRAM_ERROR__ESCROW_MINT_MISMATCH = 0x17c6; // 6086
|
|
185
191
|
/** InsufficientEscrowBalance: Insufficient balance in escrow token account */
|
|
186
|
-
export const OPTION_PROGRAM_ERROR__INSUFFICIENT_ESCROW_BALANCE =
|
|
192
|
+
export const OPTION_PROGRAM_ERROR__INSUFFICIENT_ESCROW_BALANCE = 0x17c7; // 6087
|
|
187
193
|
/** InvalidEscrowOwner: Escrow token account owner mismatch */
|
|
188
|
-
export const OPTION_PROGRAM_ERROR__INVALID_ESCROW_OWNER =
|
|
194
|
+
export const OPTION_PROGRAM_ERROR__INVALID_ESCROW_OWNER = 0x17c8; // 6088
|
|
189
195
|
/** InvalidEscrowMint: Escrow token account mint mismatch */
|
|
190
|
-
export const OPTION_PROGRAM_ERROR__INVALID_ESCROW_MINT =
|
|
196
|
+
export const OPTION_PROGRAM_ERROR__INVALID_ESCROW_MINT = 0x17c9; // 6089
|
|
191
197
|
/** AccountFrozen: Token account is frozen and cannot be burned */
|
|
192
|
-
export const OPTION_PROGRAM_ERROR__ACCOUNT_FROZEN =
|
|
198
|
+
export const OPTION_PROGRAM_ERROR__ACCOUNT_FROZEN = 0x17ca; // 6090
|
|
193
199
|
/** InvalidAccount: Invalid account - does not match expected account */
|
|
194
|
-
export const OPTION_PROGRAM_ERROR__INVALID_ACCOUNT =
|
|
200
|
+
export const OPTION_PROGRAM_ERROR__INVALID_ACCOUNT = 0x17cb; // 6091
|
|
195
201
|
/** UnwindRepayAccountsMissing: Unwind repayment accounts are required when active pool loans exist */
|
|
196
|
-
export const OPTION_PROGRAM_ERROR__UNWIND_REPAY_ACCOUNTS_MISSING =
|
|
202
|
+
export const OPTION_PROGRAM_ERROR__UNWIND_REPAY_ACCOUNTS_MISSING = 0x17cc; // 6092
|
|
197
203
|
/** InsufficientCollateralVault: Collateral vault has insufficient funds for unwind collateral return */
|
|
198
|
-
export const OPTION_PROGRAM_ERROR__INSUFFICIENT_COLLATERAL_VAULT =
|
|
204
|
+
export const OPTION_PROGRAM_ERROR__INSUFFICIENT_COLLATERAL_VAULT = 0x17cd; // 6093
|
|
199
205
|
/** InvalidVaultMint: Invalid vault mint - does not match expected collateral mint */
|
|
200
|
-
export const OPTION_PROGRAM_ERROR__INVALID_VAULT_MINT =
|
|
206
|
+
export const OPTION_PROGRAM_ERROR__INVALID_VAULT_MINT = 0x17ce; // 6094
|
|
201
207
|
/** InvalidCollateralMint: Invalid collateral mint - not supported or no vault exists */
|
|
202
|
-
export const OPTION_PROGRAM_ERROR__INVALID_COLLATERAL_MINT =
|
|
208
|
+
export const OPTION_PROGRAM_ERROR__INVALID_COLLATERAL_MINT = 0x17cf; // 6095
|
|
203
209
|
/** CollateralMismatch: Collateral mint mismatch - position uses different collateral type */
|
|
204
|
-
export const OPTION_PROGRAM_ERROR__COLLATERAL_MISMATCH =
|
|
210
|
+
export const OPTION_PROGRAM_ERROR__COLLATERAL_MISMATCH = 0x17d0; // 6096
|
|
205
211
|
/** BuyRemainingAccountsUnsorted: buy_from_pool remaining_accounts are not sorted by (created_at asc, pubkey asc) */
|
|
206
|
-
export const OPTION_PROGRAM_ERROR__BUY_REMAINING_ACCOUNTS_UNSORTED =
|
|
212
|
+
export const OPTION_PROGRAM_ERROR__BUY_REMAINING_ACCOUNTS_UNSORTED = 0x17d1; // 6097
|
|
207
213
|
/** CloseLongWritersIncomplete: close_long_to_pool requires a complete set of active WriterPositions: sum(sold_qty) must equal pool.total_sold_qty */
|
|
208
|
-
export const OPTION_PROGRAM_ERROR__CLOSE_LONG_WRITERS_INCOMPLETE =
|
|
214
|
+
export const OPTION_PROGRAM_ERROR__CLOSE_LONG_WRITERS_INCOMPLETE = 0x17d2; // 6098
|
|
209
215
|
/** CloseLongNoSoldInventory: close_long_to_pool cannot run because no writer has sold inventory for this pool */
|
|
210
|
-
export const OPTION_PROGRAM_ERROR__CLOSE_LONG_NO_SOLD_INVENTORY =
|
|
216
|
+
export const OPTION_PROGRAM_ERROR__CLOSE_LONG_NO_SOLD_INVENTORY = 0x17d3; // 6099
|
|
211
217
|
/** CloseLongDuplicateWriter: close_long_to_pool remaining_accounts contain duplicate WriterPosition entries */
|
|
212
|
-
export const OPTION_PROGRAM_ERROR__CLOSE_LONG_DUPLICATE_WRITER =
|
|
218
|
+
export const OPTION_PROGRAM_ERROR__CLOSE_LONG_DUPLICATE_WRITER = 0x17d4; // 6100
|
|
213
219
|
/** MaintenanceBufferBreached: Writer position breaches maintenance buffer: free_collateral + claimable_theta < accrued_interest + fees + buffer */
|
|
214
|
-
export const OPTION_PROGRAM_ERROR__MAINTENANCE_BUFFER_BREACHED =
|
|
220
|
+
export const OPTION_PROGRAM_ERROR__MAINTENANCE_BUFFER_BREACHED = 0x17d5; // 6101
|
|
215
221
|
/** LiquidationInsufficientCollateralForDebt: Liquidation cannot cover full debt (principal + interest + fees) from writer's collateral + theta; call rescue path instead */
|
|
216
|
-
export const OPTION_PROGRAM_ERROR__LIQUIDATION_INSUFFICIENT_COLLATERAL_FOR_DEBT =
|
|
222
|
+
export const OPTION_PROGRAM_ERROR__LIQUIDATION_INSUFFICIENT_COLLATERAL_FOR_DEBT = 0x17d6; // 6102
|
|
217
223
|
/** ThetaClaimDisabled: claim_theta instruction has been removed; theta is now auto-realized on unwind or forfeited on liquidation */
|
|
218
|
-
export const OPTION_PROGRAM_ERROR__THETA_CLAIM_DISABLED =
|
|
224
|
+
export const OPTION_PROGRAM_ERROR__THETA_CLAIM_DISABLED = 0x17d7; // 6103
|
|
219
225
|
/** PoolLoanWriterMismatch: PoolLoan.writer_position does not match the WriterPosition in this instruction */
|
|
220
|
-
export const OPTION_PROGRAM_ERROR__POOL_LOAN_WRITER_MISMATCH =
|
|
226
|
+
export const OPTION_PROGRAM_ERROR__POOL_LOAN_WRITER_MISMATCH = 0x17d8; // 6104
|
|
221
227
|
/** MaintenanceLoansIncomplete: Maintenance debt sync remaining_accounts must contain every active PoolLoan for this writer */
|
|
222
|
-
export const OPTION_PROGRAM_ERROR__MAINTENANCE_LOANS_INCOMPLETE =
|
|
228
|
+
export const OPTION_PROGRAM_ERROR__MAINTENANCE_LOANS_INCOMPLETE = 0x17d9; // 6105
|
|
223
229
|
/** RescueUnauthorized: Rescue liquidation is gated to the vault keeper */
|
|
224
|
-
export const OPTION_PROGRAM_ERROR__RESCUE_UNAUTHORIZED =
|
|
230
|
+
export const OPTION_PROGRAM_ERROR__RESCUE_UNAUTHORIZED = 0x17da; // 6106
|
|
225
231
|
/** InvalidLoanRepayment: Loan repayment amount exceeds synced balances (principal/interest/fees) */
|
|
226
|
-
export const OPTION_PROGRAM_ERROR__INVALID_LOAN_REPAYMENT =
|
|
232
|
+
export const OPTION_PROGRAM_ERROR__INVALID_LOAN_REPAYMENT = 0x17db; // 6107
|
|
227
233
|
/** RescuePreconditionsNotMet: Rescue preconditions not met: collateral_vault must be short of the remaining debt after theta forfeiture */
|
|
228
|
-
export const OPTION_PROGRAM_ERROR__RESCUE_PRECONDITIONS_NOT_MET =
|
|
234
|
+
export const OPTION_PROGRAM_ERROR__RESCUE_PRECONDITIONS_NOT_MET = 0x17dc; // 6108
|
|
229
235
|
|
|
230
236
|
export type OptionProgramError =
|
|
231
237
|
| typeof OPTION_PROGRAM_ERROR__ACCOUNT_FROZEN
|
|
@@ -233,6 +239,7 @@ export type OptionProgramError =
|
|
|
233
239
|
| typeof OPTION_PROGRAM_ERROR__ARITHMETIC_OVERFLOW
|
|
234
240
|
| typeof OPTION_PROGRAM_ERROR__ARITHMETIC_UNDERFLOW
|
|
235
241
|
| typeof OPTION_PROGRAM_ERROR__BATCH_SIZE_EXCEEDED
|
|
242
|
+
| typeof OPTION_PROGRAM_ERROR__BUYER_PAYOUT_NOT_COMPLETE
|
|
236
243
|
| typeof OPTION_PROGRAM_ERROR__BUY_REMAINING_ACCOUNTS_UNSORTED
|
|
237
244
|
| typeof OPTION_PROGRAM_ERROR__CLOSE_LONG_DUPLICATE_WRITER
|
|
238
245
|
| typeof OPTION_PROGRAM_ERROR__CLOSE_LONG_NO_SOLD_INVENTORY
|
|
@@ -289,10 +296,12 @@ export type OptionProgramError =
|
|
|
289
296
|
| typeof OPTION_PROGRAM_ERROR__INVALID_UNDERLYING_PRICE
|
|
290
297
|
| typeof OPTION_PROGRAM_ERROR__INVALID_VAULT_MINT
|
|
291
298
|
| typeof OPTION_PROGRAM_ERROR__INVALID_VOLATILITY
|
|
299
|
+
| typeof OPTION_PROGRAM_ERROR__LENDER_REPAYMENT_NOT_COMPLETE
|
|
292
300
|
| typeof OPTION_PROGRAM_ERROR__LIQUIDATION_INSUFFICIENT_COLLATERAL_FOR_DEBT
|
|
293
301
|
| typeof OPTION_PROGRAM_ERROR__LOW_ORACLE_PRICE_CONFIDENCE
|
|
294
302
|
| typeof OPTION_PROGRAM_ERROR__MAINTENANCE_BUFFER_BREACHED
|
|
295
303
|
| typeof OPTION_PROGRAM_ERROR__MAINTENANCE_LOANS_INCOMPLETE
|
|
304
|
+
| typeof OPTION_PROGRAM_ERROR__MAKER_LIQUIDATED
|
|
296
305
|
| typeof OPTION_PROGRAM_ERROR__MARKET_CLOSED
|
|
297
306
|
| typeof OPTION_PROGRAM_ERROR__MAXIMUM_POSITION_SIZE_EXCEEDED
|
|
298
307
|
| typeof OPTION_PROGRAM_ERROR__MAX_POSITIONS_REACHED
|
|
@@ -343,6 +352,7 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
343
352
|
[OPTION_PROGRAM_ERROR__ARITHMETIC_OVERFLOW]: `Arithmetic overflow occurred`,
|
|
344
353
|
[OPTION_PROGRAM_ERROR__ARITHMETIC_UNDERFLOW]: `Arithmetic underflow occurred`,
|
|
345
354
|
[OPTION_PROGRAM_ERROR__BATCH_SIZE_EXCEEDED]: `Batch size exceeds maximum allowed (10 positions)`,
|
|
355
|
+
[OPTION_PROGRAM_ERROR__BUYER_PAYOUT_NOT_COMPLETE]: `Buyer payout phase is not complete`,
|
|
346
356
|
[OPTION_PROGRAM_ERROR__BUY_REMAINING_ACCOUNTS_UNSORTED]: `buy_from_pool remaining_accounts are not sorted by (created_at asc, pubkey asc)`,
|
|
347
357
|
[OPTION_PROGRAM_ERROR__CLOSE_LONG_DUPLICATE_WRITER]: `close_long_to_pool remaining_accounts contain duplicate WriterPosition entries`,
|
|
348
358
|
[OPTION_PROGRAM_ERROR__CLOSE_LONG_NO_SOLD_INVENTORY]: `close_long_to_pool cannot run because no writer has sold inventory for this pool`,
|
|
@@ -399,10 +409,12 @@ if (process.env.NODE_ENV !== "production") {
|
|
|
399
409
|
[OPTION_PROGRAM_ERROR__INVALID_UNDERLYING_PRICE]: `Underlying price is invalid`,
|
|
400
410
|
[OPTION_PROGRAM_ERROR__INVALID_VAULT_MINT]: `Invalid vault mint - does not match expected collateral mint`,
|
|
401
411
|
[OPTION_PROGRAM_ERROR__INVALID_VOLATILITY]: `Volatility must be greater than zero`,
|
|
412
|
+
[OPTION_PROGRAM_ERROR__LENDER_REPAYMENT_NOT_COMPLETE]: `Lender repayment phase is not complete`,
|
|
402
413
|
[OPTION_PROGRAM_ERROR__LIQUIDATION_INSUFFICIENT_COLLATERAL_FOR_DEBT]: `Liquidation cannot cover full debt (principal + interest + fees) from writer's collateral + theta; call rescue path instead`,
|
|
403
414
|
[OPTION_PROGRAM_ERROR__LOW_ORACLE_PRICE_CONFIDENCE]: `Oracle price confidence is too low`,
|
|
404
415
|
[OPTION_PROGRAM_ERROR__MAINTENANCE_BUFFER_BREACHED]: `Writer position breaches maintenance buffer: free_collateral + claimable_theta < accrued_interest + fees + buffer`,
|
|
405
416
|
[OPTION_PROGRAM_ERROR__MAINTENANCE_LOANS_INCOMPLETE]: `Maintenance debt sync remaining_accounts must contain every active PoolLoan for this writer`,
|
|
417
|
+
[OPTION_PROGRAM_ERROR__MAKER_LIQUIDATED]: `Maker was liquidated and is excluded from expiry settlement`,
|
|
406
418
|
[OPTION_PROGRAM_ERROR__MARKET_CLOSED]: `Market is closed`,
|
|
407
419
|
[OPTION_PROGRAM_ERROR__MAXIMUM_POSITION_SIZE_EXCEEDED]: `Maximum position size exceeded`,
|
|
408
420
|
[OPTION_PROGRAM_ERROR__MAX_POSITIONS_REACHED]: `Maximum positions limit reached`,
|