@epicentral/sos-sdk 0.2.13 → 0.3.0-alpha.2
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 +120 -133
- package/accounts/pdas.ts +33 -0
- package/generated/instructions/index.ts +1 -0
- package/generated/instructions/repayPoolLoanFromWallet.ts +483 -0
- package/generated/instructions/unwindWriterUnsold.ts +31 -6
- package/generated/programs/optionProgram.ts +24 -0
- package/package.json +5 -2
- package/short/builders.ts +94 -0
- package/short/pool.ts +34 -0
package/README.md
CHANGED
|
@@ -1,177 +1,164 @@
|
|
|
1
1
|
# @epicentral/sos-sdk
|
|
2
2
|
|
|
3
|
-
Solana Option Standard
|
|
3
|
+
TypeScript/JavaScript SDK for the Solana Option Standard (SOS) program. The frontend-first SDK for native options trading on Solana. Built with `@solana/kit` and related Solana libraries.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Install
|
|
5
|
+
## Installation
|
|
8
6
|
|
|
9
7
|
```bash
|
|
10
|
-
pnpm add @epicentral/sos-sdk
|
|
8
|
+
pnpm add @epicentral/sos-sdk
|
|
11
9
|
```
|
|
12
10
|
|
|
11
|
+
Peer dependencies: `@solana/kit` (and your RPC client). The SDK uses `KitRpc` for account resolution and fetches.
|
|
12
|
+
|
|
13
13
|
## Overview
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
- **SHORT** — Mint options, unwind, sync, settle, claim premium, close option.
|
|
17
|
-
- **Pool** — Deposit, withdraw, borrow, repay liquidity.
|
|
18
|
-
- **OMLP** — Lender deposit and withdraw.
|
|
19
|
-
- **Accounts** — PDA derivation and account fetchers for options, pools, vaults.
|
|
15
|
+
The SDK supports two main flows:
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
- **Long (buyer)** – Buy options from the pool, close positions, exercise.
|
|
18
|
+
- **Short (writer)** – Mint options (write), unwind unsold, settle collateral, claim theta.
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
Additional modules:
|
|
24
21
|
|
|
25
|
-
|
|
22
|
+
- **OMLP** – Option Maker Liquidity Pool. Lenders deposit; writers borrow to collateralize shorts.
|
|
23
|
+
- **WSOL** – Helpers for wrapping/unwrapping SOL and creating token accounts.
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
import {
|
|
29
|
-
buildBuyFromPoolTransaction,
|
|
30
|
-
sendBuiltTransaction,
|
|
31
|
-
} from "@epicentral/sos-sdk";
|
|
25
|
+
## High-Level Functions and Instructions
|
|
32
26
|
|
|
33
|
-
|
|
34
|
-
const signature = await sendBuiltTransaction({
|
|
35
|
-
rpc,
|
|
36
|
-
rpcSubscriptions,
|
|
37
|
-
feePayer: walletSigner,
|
|
38
|
-
instructions: built.instructions,
|
|
39
|
-
});
|
|
40
|
-
```
|
|
27
|
+
### Accounts, PDAs, and Fetchers
|
|
41
28
|
|
|
42
|
-
|
|
29
|
+
| Function | Description |
|
|
30
|
+
|----------|-------------|
|
|
31
|
+
| `resolveOptionAccounts` | Resolves option pool, mints, vaults, and collateral accounts from option identity (underlying, type, strike, expiration). |
|
|
32
|
+
| `deriveVaultPda` | Derives OMLP vault PDA from mint. |
|
|
33
|
+
| `derivePoolLoanPdaFromVault` | Derives PoolLoan PDA from vault, maker, nonce (canonical; matches program). |
|
|
34
|
+
| `derivePoolLoanPda` | *(Deprecated)* Legacy derivation; use `derivePoolLoanPdaFromVault`. |
|
|
35
|
+
| `deriveWriterPositionPda` | Derives writer position PDA from option pool and writer. |
|
|
36
|
+
| `deriveAssociatedTokenAddress` | Derives ATA for owner + mint. |
|
|
37
|
+
| `fetchVault` | Fetches vault account by address. |
|
|
38
|
+
| `fetchPoolLoansByMaker` | Fetches active pool loans for a maker. |
|
|
39
|
+
| `fetchOptionPool` | Fetches option pool account. |
|
|
40
|
+
| `fetchWriterPositionsByWriter` | Fetches writer positions for a writer. |
|
|
41
|
+
| `fetchWriterPositionsForPool` | Fetches writer positions for an option pool. |
|
|
42
|
+
| `fetchPositionAccountsByBuyer` | Fetches buyer position accounts. |
|
|
43
|
+
| `fetchAllOptionPools` | Fetches all option pools. |
|
|
44
|
+
| `fetchAllVaults` | Fetches all vaults. |
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
import {
|
|
46
|
-
appendTransactionMessageInstructions,
|
|
47
|
-
createTransactionMessage,
|
|
48
|
-
pipe,
|
|
49
|
-
sendAndConfirmTransactionFactory,
|
|
50
|
-
setTransactionMessageFeePayerSigner,
|
|
51
|
-
setTransactionMessageLifetimeUsingBlockhash,
|
|
52
|
-
signTransactionMessageWithSigners,
|
|
53
|
-
} from "@solana/kit";
|
|
54
|
-
import { buildBuyFromPoolTransaction } from "@epicentral/sos-sdk";
|
|
55
|
-
|
|
56
|
-
const built = await buildBuyFromPoolTransaction(params);
|
|
57
|
-
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
|
|
58
|
-
|
|
59
|
-
const txMessage = pipe(
|
|
60
|
-
createTransactionMessage({ version: 0 }),
|
|
61
|
-
(tx) => setTransactionMessageFeePayerSigner(walletSigner, tx),
|
|
62
|
-
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
|
|
63
|
-
(tx) => appendTransactionMessageInstructions(built.instructions, tx)
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
const signedTx = await signTransactionMessageWithSigners(txMessage);
|
|
67
|
-
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTx, {
|
|
68
|
-
commitment: "confirmed",
|
|
69
|
-
});
|
|
70
|
-
```
|
|
46
|
+
### Long (Buyer) Flows
|
|
71
47
|
|
|
72
|
-
|
|
48
|
+
| Function | Description |
|
|
49
|
+
|----------|-------------|
|
|
50
|
+
| `buildBuyFromPoolTransactionWithDerivation` | Builds buy-from-pool transaction; resolves accounts from option identity. |
|
|
51
|
+
| `buildCloseLongToPoolTransactionWithDerivation` | Builds close-long-to-pool transaction. |
|
|
52
|
+
| `getBuyFromPoolRemainingAccounts` | Builds remaining_accounts for buy (writer positions, etc.). |
|
|
73
53
|
|
|
74
|
-
|
|
75
|
-
import {
|
|
76
|
-
buildBuyFromPoolTransaction,
|
|
77
|
-
buildCloseLongToPoolTransaction,
|
|
78
|
-
buildOptionExerciseTransaction,
|
|
79
|
-
} from "@epicentral/sos-sdk";
|
|
54
|
+
### Short (Writer) Flows
|
|
80
55
|
|
|
81
|
-
|
|
82
|
-
|
|
56
|
+
| Function | Description |
|
|
57
|
+
|----------|-------------|
|
|
58
|
+
| `buildOptionMintTransactionWithDerivation` | Builds option mint (write) transaction. |
|
|
59
|
+
| `buildUnwindWriterUnsoldTransactionWithDerivation` | Builds unwind unsold transaction. |
|
|
60
|
+
| `buildUnwindWriterUnsoldWithLoanRepayment` | **Unwind + repay pool loans in one tx.** Use when closing unsold shorts that borrowed from OMLP. |
|
|
61
|
+
| `buildSyncWriterPositionTransaction` | Syncs writer position with pool accumulators. |
|
|
62
|
+
| `buildSettleMakerCollateralTransaction` | Settles maker collateral after buyer closes. |
|
|
63
|
+
| `buildCloseOptionTransaction` | Closes option token account. |
|
|
64
|
+
| `buildClaimThetaTransaction` | Claims theta (time-decay share) for writer. |
|
|
65
|
+
| `buildRepayPoolLoanFromCollateralInstruction` | Repays pool loan from collateral (short/pool). |
|
|
66
|
+
| `buildRepayPoolLoanInstruction` | Repays pool loan with external funds (short/pool). |
|
|
67
|
+
| `buildRepayPoolLoanFromWalletInstruction` | Repays pool loan from maker's wallet (stuck loan recovery). |
|
|
83
68
|
|
|
84
|
-
|
|
85
|
-
const closeLong = await buildCloseLongToPoolTransaction(closeLongParams);
|
|
69
|
+
### OMLP (Lending)
|
|
86
70
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
71
|
+
| Function | Description |
|
|
72
|
+
|----------|-------------|
|
|
73
|
+
| `buildDepositToPositionTransaction` | Deposits liquidity to OMLP. |
|
|
74
|
+
| `buildWithdrawFromPositionTransaction` | Withdraws liquidity. |
|
|
75
|
+
| `withdrawAllFromPosition` | Withdraws full position (omlp/service). |
|
|
76
|
+
| `withdrawInterestFromPosition` | Withdraws accrued interest only (omlp/service). |
|
|
90
77
|
|
|
91
|
-
|
|
78
|
+
Borrow/repay for writers: use `buildOptionMintTransactionWithDerivation` (with vault/poolLoan) and `buildRepayPoolLoanFromCollateralInstruction` or `buildUnwindWriterUnsoldWithLoanRepayment`.
|
|
92
79
|
|
|
93
|
-
|
|
94
|
-
import {
|
|
95
|
-
buildOptionMintTransaction,
|
|
96
|
-
buildUnwindWriterUnsoldTransaction,
|
|
97
|
-
buildSyncWriterPositionTransaction,
|
|
98
|
-
buildSettleMakerCollateralTransaction,
|
|
99
|
-
buildClaimPremiumTransaction,
|
|
100
|
-
buildCloseOptionTransaction,
|
|
101
|
-
} from "@epicentral/sos-sdk";
|
|
102
|
-
import { OptionType } from "@epicentral/sos-sdk";
|
|
80
|
+
### WSOL / Token Helpers
|
|
103
81
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
underlyingAsset,
|
|
111
|
-
underlyingSymbol,
|
|
112
|
-
makerCollateralAmount,
|
|
113
|
-
borrowedAmount,
|
|
114
|
-
maker,
|
|
115
|
-
makerCollateralAccount,
|
|
116
|
-
underlyingMint,
|
|
117
|
-
});
|
|
82
|
+
| Function | Description |
|
|
83
|
+
|----------|-------------|
|
|
84
|
+
| `getWrapSOLInstructions` | Wraps SOL to WSOL. |
|
|
85
|
+
| `getUnwrapSOLInstructions` | Unwraps WSOL to SOL. |
|
|
86
|
+
| `getCreateAssociatedTokenIdempotentInstructionWithAddress` | Creates ATA if missing (idempotent). |
|
|
87
|
+
| `NATIVE_MINT` | WSOL mint address. |
|
|
118
88
|
|
|
119
|
-
|
|
120
|
-
const unwind = await buildUnwindWriterUnsoldTransaction(unwindParams);
|
|
121
|
-
const sync = buildSyncWriterPositionTransaction(syncParams);
|
|
122
|
-
const settle = await buildSettleMakerCollateralTransaction(settleParams);
|
|
89
|
+
## Unwind with Loan Repayment
|
|
123
90
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
91
|
+
When a writer unwinds an unsold short that had borrowed from the OMLP pool, the program repays lenders from the collateral vault inside `unwind_writer_unsold` (burn LONG+SHORT, repay loans, then return collateral to writer) in one instruction.
|
|
92
|
+
|
|
93
|
+
Use **`buildUnwindWriterUnsoldWithLoanRepayment`** so that:
|
|
94
|
+
|
|
95
|
+
1. Active pool loans for the option’s underlying vault are fetched.
|
|
96
|
+
2. `omlpVaultState` (Vault PDA), `omlpVault`, and `feeWallet` are passed as named accounts.
|
|
97
|
+
3. `remaining_accounts` = **[PoolLoan₁, PoolLoan₂, ...]** only (capped at 20 loans per tx).
|
|
98
|
+
4. One transaction burns, repays lenders from collateral vault, and returns collateral to the writer.
|
|
99
|
+
|
|
100
|
+
If there are no active pool loans for that vault, the API still works and passes empty `remaining_accounts`.
|
|
128
101
|
|
|
129
|
-
|
|
102
|
+
**Alternative (repay then unwind):** For writers with more than ~20 active loans, (1) build `repay_pool_loan_from_collateral` instructions first to reduce loans, then (2) unwind with the remaining loans.
|
|
103
|
+
|
|
104
|
+
**Stuck loan (InsufficientEscrowBalance):** When standard repay fails with `InsufficientEscrowBalance` (escrow underfunded or drained), use `buildRepayPoolLoanFromWalletInstruction` or `buildRepayPoolLoanFromWalletTransaction`. Same accounts as `buildRepayPoolLoanInstruction`; maker pays full principal + interest + fees from their wallet.
|
|
105
|
+
|
|
106
|
+
## Usage Examples
|
|
107
|
+
|
|
108
|
+
### Buy from pool (with derivation)
|
|
130
109
|
|
|
131
110
|
```ts
|
|
132
111
|
import {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
buildRepayPoolLoanTransaction,
|
|
112
|
+
buildBuyFromPoolTransactionWithDerivation,
|
|
113
|
+
resolveOptionAccounts,
|
|
114
|
+
OptionType,
|
|
137
115
|
} from "@epicentral/sos-sdk";
|
|
138
116
|
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
117
|
+
const tx = await buildBuyFromPoolTransactionWithDerivation({
|
|
118
|
+
underlyingAsset: "...",
|
|
119
|
+
optionType: OptionType.Call,
|
|
120
|
+
strikePrice: 100_000,
|
|
121
|
+
expirationDate: BigInt(1735689600),
|
|
122
|
+
buyer: walletAddress,
|
|
123
|
+
buyerPaymentAccount: buyerUsdcAta,
|
|
124
|
+
priceUpdate: pythPriceFeed,
|
|
125
|
+
quantity: 1_000_000,
|
|
126
|
+
premiumAmount: 50_000,
|
|
127
|
+
rpc,
|
|
128
|
+
});
|
|
143
129
|
```
|
|
144
130
|
|
|
145
|
-
###
|
|
131
|
+
### Unwind with loan repayment
|
|
146
132
|
|
|
147
133
|
```ts
|
|
148
134
|
import {
|
|
149
|
-
|
|
150
|
-
|
|
135
|
+
buildUnwindWriterUnsoldWithLoanRepayment,
|
|
136
|
+
OptionType,
|
|
151
137
|
} from "@epicentral/sos-sdk";
|
|
152
138
|
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
vault,
|
|
162
|
-
vaultTokenAccount,
|
|
163
|
-
lenderTokenAccount,
|
|
164
|
-
lender,
|
|
165
|
-
amount,
|
|
139
|
+
const tx = await buildUnwindWriterUnsoldWithLoanRepayment({
|
|
140
|
+
underlyingAsset: "...",
|
|
141
|
+
optionType: OptionType.Call,
|
|
142
|
+
strikePrice: 100_000,
|
|
143
|
+
expirationDate: BigInt(1735689600),
|
|
144
|
+
writer: walletAddress,
|
|
145
|
+
unwindQty: 500_000,
|
|
146
|
+
rpc,
|
|
166
147
|
});
|
|
167
148
|
```
|
|
168
149
|
|
|
169
|
-
|
|
150
|
+
## Types and Exports
|
|
170
151
|
|
|
171
|
-
|
|
172
|
-
import { fetchOptionAccount, fetchOptionPool, fetchVault } from "@epicentral/sos-sdk";
|
|
152
|
+
Key types exported from the package:
|
|
173
153
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
154
|
+
- `OptionType` – Call or Put.
|
|
155
|
+
- `BuiltTransaction` – `{ instructions: Instruction[] }`.
|
|
156
|
+
- `AddressLike` – `string | Address`.
|
|
157
|
+
- `KitRpc` – RPC client type for fetches.
|
|
158
|
+
- `RemainingAccountInput` – `{ address, isWritable, isSigner? }`.
|
|
159
|
+
|
|
160
|
+
PDAs, fetchers, and builders are exported from the package root.
|
|
161
|
+
|
|
162
|
+
## Program Compatibility
|
|
163
|
+
|
|
164
|
+
The SDK targets the Solana Option Standard program. Use `PROGRAM_ID` (or `getProgramId()`) from the package for the program address. Pass `programId` in builder params when using a different deployment.
|
package/accounts/pdas.ts
CHANGED
|
@@ -258,6 +258,39 @@ export async function deriveEscrowAuthorityPda(
|
|
|
258
258
|
});
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Derives the PoolLoan PDA using the canonical seeds: vault, maker, nonce.
|
|
263
|
+
* Matches the program's derivation in omlp_context.rs (BorrowFromPool).
|
|
264
|
+
*
|
|
265
|
+
* @param vault - OMLP vault PDA (from deriveVaultPda)
|
|
266
|
+
* @param maker - Writer/borrower pubkey
|
|
267
|
+
* @param nonce - Loan nonce (u64)
|
|
268
|
+
* @param programId - Optional program ID
|
|
269
|
+
*/
|
|
270
|
+
export async function derivePoolLoanPdaFromVault(
|
|
271
|
+
vault: AddressLike,
|
|
272
|
+
maker: AddressLike,
|
|
273
|
+
nonce: bigint | number,
|
|
274
|
+
programId: AddressLike = PROGRAM_ID
|
|
275
|
+
): Promise<readonly [Address, number]> {
|
|
276
|
+
const addressEncoder = getAddressEncoder();
|
|
277
|
+
return getProgramDerivedAddress({
|
|
278
|
+
programAddress: toAddress(programId),
|
|
279
|
+
seeds: [
|
|
280
|
+
new TextEncoder().encode("pool_loan"),
|
|
281
|
+
addressEncoder.encode(toAddress(vault)),
|
|
282
|
+
addressEncoder.encode(toAddress(maker)),
|
|
283
|
+
u64ToLeBytes(nonce),
|
|
284
|
+
],
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Derives the PoolLoan PDA using writer position and nonce.
|
|
290
|
+
*
|
|
291
|
+
* @deprecated This derivation does not match the program. Use {@link derivePoolLoanPdaFromVault}
|
|
292
|
+
* with (vault, maker, nonce) instead. Program seeds are: pool_loan, vault, maker, nonce (u64 le).
|
|
293
|
+
*/
|
|
261
294
|
export async function derivePoolLoanPda(
|
|
262
295
|
writerPosition: AddressLike,
|
|
263
296
|
nonce: bigint | number,
|
|
@@ -31,6 +31,7 @@ export * from "./optionMint";
|
|
|
31
31
|
export * from "./optionValidate";
|
|
32
32
|
export * from "./repayPoolLoan";
|
|
33
33
|
export * from "./repayPoolLoanFromCollateral";
|
|
34
|
+
export * from "./repayPoolLoanFromWallet";
|
|
34
35
|
export * from "./settleMakerCollateral";
|
|
35
36
|
export * from "./syncWriterPosition";
|
|
36
37
|
export * from "./transferAdmin";
|
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This code was AUTOGENERATED using the Codama library.
|
|
3
|
+
* Please DO NOT EDIT THIS FILE, instead use visitors
|
|
4
|
+
* to add features, then rerun Codama to update it.
|
|
5
|
+
*
|
|
6
|
+
* @see https://github.com/codama-idl/codama
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
combineCodec,
|
|
11
|
+
fixDecoderSize,
|
|
12
|
+
fixEncoderSize,
|
|
13
|
+
getAddressEncoder,
|
|
14
|
+
getBytesDecoder,
|
|
15
|
+
getBytesEncoder,
|
|
16
|
+
getProgramDerivedAddress,
|
|
17
|
+
getStructDecoder,
|
|
18
|
+
getStructEncoder,
|
|
19
|
+
transformEncoder,
|
|
20
|
+
type AccountMeta,
|
|
21
|
+
type AccountSignerMeta,
|
|
22
|
+
type Address,
|
|
23
|
+
type FixedSizeCodec,
|
|
24
|
+
type FixedSizeDecoder,
|
|
25
|
+
type FixedSizeEncoder,
|
|
26
|
+
type Instruction,
|
|
27
|
+
type InstructionWithAccounts,
|
|
28
|
+
type InstructionWithData,
|
|
29
|
+
type ReadonlyAccount,
|
|
30
|
+
type ReadonlySignerAccount,
|
|
31
|
+
type ReadonlyUint8Array,
|
|
32
|
+
type TransactionSigner,
|
|
33
|
+
type WritableAccount,
|
|
34
|
+
} from "@solana/kit";
|
|
35
|
+
import { OPTION_PROGRAM_PROGRAM_ADDRESS } from "../programs";
|
|
36
|
+
import {
|
|
37
|
+
expectAddress,
|
|
38
|
+
getAccountMetaFactory,
|
|
39
|
+
type ResolvedAccount,
|
|
40
|
+
} from "../shared";
|
|
41
|
+
|
|
42
|
+
export const REPAY_POOL_LOAN_FROM_WALLET_DISCRIMINATOR = new Uint8Array([
|
|
43
|
+
78, 130, 135, 90, 211, 21, 247, 247,
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
export function getRepayPoolLoanFromWalletDiscriminatorBytes() {
|
|
47
|
+
return fixEncoderSize(getBytesEncoder(), 8).encode(
|
|
48
|
+
REPAY_POOL_LOAN_FROM_WALLET_DISCRIMINATOR,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type RepayPoolLoanFromWalletInstruction<
|
|
53
|
+
TProgram extends string = typeof OPTION_PROGRAM_PROGRAM_ADDRESS,
|
|
54
|
+
TAccountPoolLoan extends string | AccountMeta<string> = string,
|
|
55
|
+
TAccountVault extends string | AccountMeta<string> = string,
|
|
56
|
+
TAccountVaultTokenAccount extends string | AccountMeta<string> = string,
|
|
57
|
+
TAccountEscrowState extends string | AccountMeta<string> = string,
|
|
58
|
+
TAccountEscrowAuthority extends string | AccountMeta<string> = string,
|
|
59
|
+
TAccountEscrowTokenAccount extends string | AccountMeta<string> = string,
|
|
60
|
+
TAccountMakerTokenAccount extends string | AccountMeta<string> = string,
|
|
61
|
+
TAccountFeeWalletTokenAccount extends string | AccountMeta<string> = string,
|
|
62
|
+
TAccountMaker extends string | AccountMeta<string> = string,
|
|
63
|
+
TAccountTokenProgram extends string | AccountMeta<string> =
|
|
64
|
+
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
|
|
65
|
+
TRemainingAccounts extends readonly AccountMeta<string>[] = [],
|
|
66
|
+
> = Instruction<TProgram> &
|
|
67
|
+
InstructionWithData<ReadonlyUint8Array> &
|
|
68
|
+
InstructionWithAccounts<
|
|
69
|
+
[
|
|
70
|
+
TAccountPoolLoan extends string
|
|
71
|
+
? WritableAccount<TAccountPoolLoan>
|
|
72
|
+
: TAccountPoolLoan,
|
|
73
|
+
TAccountVault extends string
|
|
74
|
+
? WritableAccount<TAccountVault>
|
|
75
|
+
: TAccountVault,
|
|
76
|
+
TAccountVaultTokenAccount extends string
|
|
77
|
+
? WritableAccount<TAccountVaultTokenAccount>
|
|
78
|
+
: TAccountVaultTokenAccount,
|
|
79
|
+
TAccountEscrowState extends string
|
|
80
|
+
? ReadonlyAccount<TAccountEscrowState>
|
|
81
|
+
: TAccountEscrowState,
|
|
82
|
+
TAccountEscrowAuthority extends string
|
|
83
|
+
? ReadonlyAccount<TAccountEscrowAuthority>
|
|
84
|
+
: TAccountEscrowAuthority,
|
|
85
|
+
TAccountEscrowTokenAccount extends string
|
|
86
|
+
? WritableAccount<TAccountEscrowTokenAccount>
|
|
87
|
+
: TAccountEscrowTokenAccount,
|
|
88
|
+
TAccountMakerTokenAccount extends string
|
|
89
|
+
? WritableAccount<TAccountMakerTokenAccount>
|
|
90
|
+
: TAccountMakerTokenAccount,
|
|
91
|
+
TAccountFeeWalletTokenAccount extends string
|
|
92
|
+
? WritableAccount<TAccountFeeWalletTokenAccount>
|
|
93
|
+
: TAccountFeeWalletTokenAccount,
|
|
94
|
+
TAccountMaker extends string
|
|
95
|
+
? ReadonlySignerAccount<TAccountMaker> &
|
|
96
|
+
AccountSignerMeta<TAccountMaker>
|
|
97
|
+
: TAccountMaker,
|
|
98
|
+
TAccountTokenProgram extends string
|
|
99
|
+
? ReadonlyAccount<TAccountTokenProgram>
|
|
100
|
+
: TAccountTokenProgram,
|
|
101
|
+
...TRemainingAccounts,
|
|
102
|
+
]
|
|
103
|
+
>;
|
|
104
|
+
|
|
105
|
+
export type RepayPoolLoanFromWalletInstructionData = {
|
|
106
|
+
discriminator: ReadonlyUint8Array;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export type RepayPoolLoanFromWalletInstructionDataArgs = {};
|
|
110
|
+
|
|
111
|
+
export function getRepayPoolLoanFromWalletInstructionDataEncoder(): FixedSizeEncoder<RepayPoolLoanFromWalletInstructionDataArgs> {
|
|
112
|
+
return transformEncoder(
|
|
113
|
+
getStructEncoder([["discriminator", fixEncoderSize(getBytesEncoder(), 8)]]),
|
|
114
|
+
(value) => ({
|
|
115
|
+
...value,
|
|
116
|
+
discriminator: REPAY_POOL_LOAN_FROM_WALLET_DISCRIMINATOR,
|
|
117
|
+
}),
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function getRepayPoolLoanFromWalletInstructionDataDecoder(): FixedSizeDecoder<RepayPoolLoanFromWalletInstructionData> {
|
|
122
|
+
return getStructDecoder([
|
|
123
|
+
["discriminator", fixDecoderSize(getBytesDecoder(), 8)],
|
|
124
|
+
]);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function getRepayPoolLoanFromWalletInstructionDataCodec(): FixedSizeCodec<
|
|
128
|
+
RepayPoolLoanFromWalletInstructionDataArgs,
|
|
129
|
+
RepayPoolLoanFromWalletInstructionData
|
|
130
|
+
> {
|
|
131
|
+
return combineCodec(
|
|
132
|
+
getRepayPoolLoanFromWalletInstructionDataEncoder(),
|
|
133
|
+
getRepayPoolLoanFromWalletInstructionDataDecoder(),
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export type RepayPoolLoanFromWalletAsyncInput<
|
|
138
|
+
TAccountPoolLoan extends string = string,
|
|
139
|
+
TAccountVault extends string = string,
|
|
140
|
+
TAccountVaultTokenAccount extends string = string,
|
|
141
|
+
TAccountEscrowState extends string = string,
|
|
142
|
+
TAccountEscrowAuthority extends string = string,
|
|
143
|
+
TAccountEscrowTokenAccount extends string = string,
|
|
144
|
+
TAccountMakerTokenAccount extends string = string,
|
|
145
|
+
TAccountFeeWalletTokenAccount extends string = string,
|
|
146
|
+
TAccountMaker extends string = string,
|
|
147
|
+
TAccountTokenProgram extends string = string,
|
|
148
|
+
> = {
|
|
149
|
+
poolLoan: Address<TAccountPoolLoan>;
|
|
150
|
+
vault: Address<TAccountVault>;
|
|
151
|
+
vaultTokenAccount: Address<TAccountVaultTokenAccount>;
|
|
152
|
+
escrowState: Address<TAccountEscrowState>;
|
|
153
|
+
escrowAuthority?: Address<TAccountEscrowAuthority>;
|
|
154
|
+
escrowTokenAccount: Address<TAccountEscrowTokenAccount>;
|
|
155
|
+
makerTokenAccount: Address<TAccountMakerTokenAccount>;
|
|
156
|
+
feeWalletTokenAccount: Address<TAccountFeeWalletTokenAccount>;
|
|
157
|
+
maker: TransactionSigner<TAccountMaker>;
|
|
158
|
+
tokenProgram?: Address<TAccountTokenProgram>;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export async function getRepayPoolLoanFromWalletInstructionAsync<
|
|
162
|
+
TAccountPoolLoan extends string,
|
|
163
|
+
TAccountVault extends string,
|
|
164
|
+
TAccountVaultTokenAccount extends string,
|
|
165
|
+
TAccountEscrowState extends string,
|
|
166
|
+
TAccountEscrowAuthority extends string,
|
|
167
|
+
TAccountEscrowTokenAccount extends string,
|
|
168
|
+
TAccountMakerTokenAccount extends string,
|
|
169
|
+
TAccountFeeWalletTokenAccount extends string,
|
|
170
|
+
TAccountMaker extends string,
|
|
171
|
+
TAccountTokenProgram extends string,
|
|
172
|
+
TProgramAddress extends Address = typeof OPTION_PROGRAM_PROGRAM_ADDRESS,
|
|
173
|
+
>(
|
|
174
|
+
input: RepayPoolLoanFromWalletAsyncInput<
|
|
175
|
+
TAccountPoolLoan,
|
|
176
|
+
TAccountVault,
|
|
177
|
+
TAccountVaultTokenAccount,
|
|
178
|
+
TAccountEscrowState,
|
|
179
|
+
TAccountEscrowAuthority,
|
|
180
|
+
TAccountEscrowTokenAccount,
|
|
181
|
+
TAccountMakerTokenAccount,
|
|
182
|
+
TAccountFeeWalletTokenAccount,
|
|
183
|
+
TAccountMaker,
|
|
184
|
+
TAccountTokenProgram
|
|
185
|
+
>,
|
|
186
|
+
config?: { programAddress?: TProgramAddress },
|
|
187
|
+
): Promise<
|
|
188
|
+
RepayPoolLoanFromWalletInstruction<
|
|
189
|
+
TProgramAddress,
|
|
190
|
+
TAccountPoolLoan,
|
|
191
|
+
TAccountVault,
|
|
192
|
+
TAccountVaultTokenAccount,
|
|
193
|
+
TAccountEscrowState,
|
|
194
|
+
TAccountEscrowAuthority,
|
|
195
|
+
TAccountEscrowTokenAccount,
|
|
196
|
+
TAccountMakerTokenAccount,
|
|
197
|
+
TAccountFeeWalletTokenAccount,
|
|
198
|
+
TAccountMaker,
|
|
199
|
+
TAccountTokenProgram
|
|
200
|
+
>
|
|
201
|
+
> {
|
|
202
|
+
// Program address.
|
|
203
|
+
const programAddress =
|
|
204
|
+
config?.programAddress ?? OPTION_PROGRAM_PROGRAM_ADDRESS;
|
|
205
|
+
|
|
206
|
+
// Original accounts.
|
|
207
|
+
const originalAccounts = {
|
|
208
|
+
poolLoan: { value: input.poolLoan ?? null, isWritable: true },
|
|
209
|
+
vault: { value: input.vault ?? null, isWritable: true },
|
|
210
|
+
vaultTokenAccount: {
|
|
211
|
+
value: input.vaultTokenAccount ?? null,
|
|
212
|
+
isWritable: true,
|
|
213
|
+
},
|
|
214
|
+
escrowState: { value: input.escrowState ?? null, isWritable: false },
|
|
215
|
+
escrowAuthority: {
|
|
216
|
+
value: input.escrowAuthority ?? null,
|
|
217
|
+
isWritable: false,
|
|
218
|
+
},
|
|
219
|
+
escrowTokenAccount: {
|
|
220
|
+
value: input.escrowTokenAccount ?? null,
|
|
221
|
+
isWritable: true,
|
|
222
|
+
},
|
|
223
|
+
makerTokenAccount: {
|
|
224
|
+
value: input.makerTokenAccount ?? null,
|
|
225
|
+
isWritable: true,
|
|
226
|
+
},
|
|
227
|
+
feeWalletTokenAccount: {
|
|
228
|
+
value: input.feeWalletTokenAccount ?? null,
|
|
229
|
+
isWritable: true,
|
|
230
|
+
},
|
|
231
|
+
maker: { value: input.maker ?? null, isWritable: false },
|
|
232
|
+
tokenProgram: { value: input.tokenProgram ?? null, isWritable: false },
|
|
233
|
+
};
|
|
234
|
+
const accounts = originalAccounts as Record<
|
|
235
|
+
keyof typeof originalAccounts,
|
|
236
|
+
ResolvedAccount
|
|
237
|
+
>;
|
|
238
|
+
|
|
239
|
+
// Resolve default values.
|
|
240
|
+
if (!accounts.escrowAuthority.value) {
|
|
241
|
+
accounts.escrowAuthority.value = await getProgramDerivedAddress({
|
|
242
|
+
programAddress,
|
|
243
|
+
seeds: [
|
|
244
|
+
getBytesEncoder().encode(
|
|
245
|
+
new Uint8Array([
|
|
246
|
+
101, 115, 99, 114, 111, 119, 95, 97, 117, 116, 104, 111, 114, 105,
|
|
247
|
+
116, 121, 95, 118, 50,
|
|
248
|
+
]),
|
|
249
|
+
),
|
|
250
|
+
getAddressEncoder().encode(expectAddress(accounts.escrowState.value)),
|
|
251
|
+
],
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
if (!accounts.tokenProgram.value) {
|
|
255
|
+
accounts.tokenProgram.value =
|
|
256
|
+
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address<"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA">;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const getAccountMeta = getAccountMetaFactory(programAddress, "programId");
|
|
260
|
+
return Object.freeze({
|
|
261
|
+
accounts: [
|
|
262
|
+
getAccountMeta(accounts.poolLoan),
|
|
263
|
+
getAccountMeta(accounts.vault),
|
|
264
|
+
getAccountMeta(accounts.vaultTokenAccount),
|
|
265
|
+
getAccountMeta(accounts.escrowState),
|
|
266
|
+
getAccountMeta(accounts.escrowAuthority),
|
|
267
|
+
getAccountMeta(accounts.escrowTokenAccount),
|
|
268
|
+
getAccountMeta(accounts.makerTokenAccount),
|
|
269
|
+
getAccountMeta(accounts.feeWalletTokenAccount),
|
|
270
|
+
getAccountMeta(accounts.maker),
|
|
271
|
+
getAccountMeta(accounts.tokenProgram),
|
|
272
|
+
],
|
|
273
|
+
data: getRepayPoolLoanFromWalletInstructionDataEncoder().encode({}),
|
|
274
|
+
programAddress,
|
|
275
|
+
} as RepayPoolLoanFromWalletInstruction<
|
|
276
|
+
TProgramAddress,
|
|
277
|
+
TAccountPoolLoan,
|
|
278
|
+
TAccountVault,
|
|
279
|
+
TAccountVaultTokenAccount,
|
|
280
|
+
TAccountEscrowState,
|
|
281
|
+
TAccountEscrowAuthority,
|
|
282
|
+
TAccountEscrowTokenAccount,
|
|
283
|
+
TAccountMakerTokenAccount,
|
|
284
|
+
TAccountFeeWalletTokenAccount,
|
|
285
|
+
TAccountMaker,
|
|
286
|
+
TAccountTokenProgram
|
|
287
|
+
>);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export type RepayPoolLoanFromWalletInput<
|
|
291
|
+
TAccountPoolLoan extends string = string,
|
|
292
|
+
TAccountVault extends string = string,
|
|
293
|
+
TAccountVaultTokenAccount extends string = string,
|
|
294
|
+
TAccountEscrowState extends string = string,
|
|
295
|
+
TAccountEscrowAuthority extends string = string,
|
|
296
|
+
TAccountEscrowTokenAccount extends string = string,
|
|
297
|
+
TAccountMakerTokenAccount extends string = string,
|
|
298
|
+
TAccountFeeWalletTokenAccount extends string = string,
|
|
299
|
+
TAccountMaker extends string = string,
|
|
300
|
+
TAccountTokenProgram extends string = string,
|
|
301
|
+
> = {
|
|
302
|
+
poolLoan: Address<TAccountPoolLoan>;
|
|
303
|
+
vault: Address<TAccountVault>;
|
|
304
|
+
vaultTokenAccount: Address<TAccountVaultTokenAccount>;
|
|
305
|
+
escrowState: Address<TAccountEscrowState>;
|
|
306
|
+
escrowAuthority: Address<TAccountEscrowAuthority>;
|
|
307
|
+
escrowTokenAccount: Address<TAccountEscrowTokenAccount>;
|
|
308
|
+
makerTokenAccount: Address<TAccountMakerTokenAccount>;
|
|
309
|
+
feeWalletTokenAccount: Address<TAccountFeeWalletTokenAccount>;
|
|
310
|
+
maker: TransactionSigner<TAccountMaker>;
|
|
311
|
+
tokenProgram?: Address<TAccountTokenProgram>;
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
export function getRepayPoolLoanFromWalletInstruction<
|
|
315
|
+
TAccountPoolLoan extends string,
|
|
316
|
+
TAccountVault extends string,
|
|
317
|
+
TAccountVaultTokenAccount extends string,
|
|
318
|
+
TAccountEscrowState extends string,
|
|
319
|
+
TAccountEscrowAuthority extends string,
|
|
320
|
+
TAccountEscrowTokenAccount extends string,
|
|
321
|
+
TAccountMakerTokenAccount extends string,
|
|
322
|
+
TAccountFeeWalletTokenAccount extends string,
|
|
323
|
+
TAccountMaker extends string,
|
|
324
|
+
TAccountTokenProgram extends string,
|
|
325
|
+
TProgramAddress extends Address = typeof OPTION_PROGRAM_PROGRAM_ADDRESS,
|
|
326
|
+
>(
|
|
327
|
+
input: RepayPoolLoanFromWalletInput<
|
|
328
|
+
TAccountPoolLoan,
|
|
329
|
+
TAccountVault,
|
|
330
|
+
TAccountVaultTokenAccount,
|
|
331
|
+
TAccountEscrowState,
|
|
332
|
+
TAccountEscrowAuthority,
|
|
333
|
+
TAccountEscrowTokenAccount,
|
|
334
|
+
TAccountMakerTokenAccount,
|
|
335
|
+
TAccountFeeWalletTokenAccount,
|
|
336
|
+
TAccountMaker,
|
|
337
|
+
TAccountTokenProgram
|
|
338
|
+
>,
|
|
339
|
+
config?: { programAddress?: TProgramAddress },
|
|
340
|
+
): RepayPoolLoanFromWalletInstruction<
|
|
341
|
+
TProgramAddress,
|
|
342
|
+
TAccountPoolLoan,
|
|
343
|
+
TAccountVault,
|
|
344
|
+
TAccountVaultTokenAccount,
|
|
345
|
+
TAccountEscrowState,
|
|
346
|
+
TAccountEscrowAuthority,
|
|
347
|
+
TAccountEscrowTokenAccount,
|
|
348
|
+
TAccountMakerTokenAccount,
|
|
349
|
+
TAccountFeeWalletTokenAccount,
|
|
350
|
+
TAccountMaker,
|
|
351
|
+
TAccountTokenProgram
|
|
352
|
+
> {
|
|
353
|
+
// Program address.
|
|
354
|
+
const programAddress =
|
|
355
|
+
config?.programAddress ?? OPTION_PROGRAM_PROGRAM_ADDRESS;
|
|
356
|
+
|
|
357
|
+
// Original accounts.
|
|
358
|
+
const originalAccounts = {
|
|
359
|
+
poolLoan: { value: input.poolLoan ?? null, isWritable: true },
|
|
360
|
+
vault: { value: input.vault ?? null, isWritable: true },
|
|
361
|
+
vaultTokenAccount: {
|
|
362
|
+
value: input.vaultTokenAccount ?? null,
|
|
363
|
+
isWritable: true,
|
|
364
|
+
},
|
|
365
|
+
escrowState: { value: input.escrowState ?? null, isWritable: false },
|
|
366
|
+
escrowAuthority: {
|
|
367
|
+
value: input.escrowAuthority ?? null,
|
|
368
|
+
isWritable: false,
|
|
369
|
+
},
|
|
370
|
+
escrowTokenAccount: {
|
|
371
|
+
value: input.escrowTokenAccount ?? null,
|
|
372
|
+
isWritable: true,
|
|
373
|
+
},
|
|
374
|
+
makerTokenAccount: {
|
|
375
|
+
value: input.makerTokenAccount ?? null,
|
|
376
|
+
isWritable: true,
|
|
377
|
+
},
|
|
378
|
+
feeWalletTokenAccount: {
|
|
379
|
+
value: input.feeWalletTokenAccount ?? null,
|
|
380
|
+
isWritable: true,
|
|
381
|
+
},
|
|
382
|
+
maker: { value: input.maker ?? null, isWritable: false },
|
|
383
|
+
tokenProgram: { value: input.tokenProgram ?? null, isWritable: false },
|
|
384
|
+
};
|
|
385
|
+
const accounts = originalAccounts as Record<
|
|
386
|
+
keyof typeof originalAccounts,
|
|
387
|
+
ResolvedAccount
|
|
388
|
+
>;
|
|
389
|
+
|
|
390
|
+
// Resolve default values.
|
|
391
|
+
if (!accounts.tokenProgram.value) {
|
|
392
|
+
accounts.tokenProgram.value =
|
|
393
|
+
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" as Address<"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA">;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const getAccountMeta = getAccountMetaFactory(programAddress, "programId");
|
|
397
|
+
return Object.freeze({
|
|
398
|
+
accounts: [
|
|
399
|
+
getAccountMeta(accounts.poolLoan),
|
|
400
|
+
getAccountMeta(accounts.vault),
|
|
401
|
+
getAccountMeta(accounts.vaultTokenAccount),
|
|
402
|
+
getAccountMeta(accounts.escrowState),
|
|
403
|
+
getAccountMeta(accounts.escrowAuthority),
|
|
404
|
+
getAccountMeta(accounts.escrowTokenAccount),
|
|
405
|
+
getAccountMeta(accounts.makerTokenAccount),
|
|
406
|
+
getAccountMeta(accounts.feeWalletTokenAccount),
|
|
407
|
+
getAccountMeta(accounts.maker),
|
|
408
|
+
getAccountMeta(accounts.tokenProgram),
|
|
409
|
+
],
|
|
410
|
+
data: getRepayPoolLoanFromWalletInstructionDataEncoder().encode({}),
|
|
411
|
+
programAddress,
|
|
412
|
+
} as RepayPoolLoanFromWalletInstruction<
|
|
413
|
+
TProgramAddress,
|
|
414
|
+
TAccountPoolLoan,
|
|
415
|
+
TAccountVault,
|
|
416
|
+
TAccountVaultTokenAccount,
|
|
417
|
+
TAccountEscrowState,
|
|
418
|
+
TAccountEscrowAuthority,
|
|
419
|
+
TAccountEscrowTokenAccount,
|
|
420
|
+
TAccountMakerTokenAccount,
|
|
421
|
+
TAccountFeeWalletTokenAccount,
|
|
422
|
+
TAccountMaker,
|
|
423
|
+
TAccountTokenProgram
|
|
424
|
+
>);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
export type ParsedRepayPoolLoanFromWalletInstruction<
|
|
428
|
+
TProgram extends string = typeof OPTION_PROGRAM_PROGRAM_ADDRESS,
|
|
429
|
+
TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[],
|
|
430
|
+
> = {
|
|
431
|
+
programAddress: Address<TProgram>;
|
|
432
|
+
accounts: {
|
|
433
|
+
poolLoan: TAccountMetas[0];
|
|
434
|
+
vault: TAccountMetas[1];
|
|
435
|
+
vaultTokenAccount: TAccountMetas[2];
|
|
436
|
+
escrowState: TAccountMetas[3];
|
|
437
|
+
escrowAuthority: TAccountMetas[4];
|
|
438
|
+
escrowTokenAccount: TAccountMetas[5];
|
|
439
|
+
makerTokenAccount: TAccountMetas[6];
|
|
440
|
+
feeWalletTokenAccount: TAccountMetas[7];
|
|
441
|
+
maker: TAccountMetas[8];
|
|
442
|
+
tokenProgram: TAccountMetas[9];
|
|
443
|
+
};
|
|
444
|
+
data: RepayPoolLoanFromWalletInstructionData;
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
export function parseRepayPoolLoanFromWalletInstruction<
|
|
448
|
+
TProgram extends string,
|
|
449
|
+
TAccountMetas extends readonly AccountMeta[],
|
|
450
|
+
>(
|
|
451
|
+
instruction: Instruction<TProgram> &
|
|
452
|
+
InstructionWithAccounts<TAccountMetas> &
|
|
453
|
+
InstructionWithData<ReadonlyUint8Array>,
|
|
454
|
+
): ParsedRepayPoolLoanFromWalletInstruction<TProgram, TAccountMetas> {
|
|
455
|
+
if (instruction.accounts.length < 10) {
|
|
456
|
+
// TODO: Coded error.
|
|
457
|
+
throw new Error("Not enough accounts");
|
|
458
|
+
}
|
|
459
|
+
let accountIndex = 0;
|
|
460
|
+
const getNextAccount = () => {
|
|
461
|
+
const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!;
|
|
462
|
+
accountIndex += 1;
|
|
463
|
+
return accountMeta;
|
|
464
|
+
};
|
|
465
|
+
return {
|
|
466
|
+
programAddress: instruction.programAddress,
|
|
467
|
+
accounts: {
|
|
468
|
+
poolLoan: getNextAccount(),
|
|
469
|
+
vault: getNextAccount(),
|
|
470
|
+
vaultTokenAccount: getNextAccount(),
|
|
471
|
+
escrowState: getNextAccount(),
|
|
472
|
+
escrowAuthority: getNextAccount(),
|
|
473
|
+
escrowTokenAccount: getNextAccount(),
|
|
474
|
+
makerTokenAccount: getNextAccount(),
|
|
475
|
+
feeWalletTokenAccount: getNextAccount(),
|
|
476
|
+
maker: getNextAccount(),
|
|
477
|
+
tokenProgram: getNextAccount(),
|
|
478
|
+
},
|
|
479
|
+
data: getRepayPoolLoanFromWalletInstructionDataDecoder().decode(
|
|
480
|
+
instruction.data,
|
|
481
|
+
),
|
|
482
|
+
};
|
|
483
|
+
}
|
|
@@ -63,6 +63,7 @@ export type UnwindWriterUnsoldInstruction<
|
|
|
63
63
|
TAccountWriterShortAccount extends string | AccountMeta<string> = string,
|
|
64
64
|
TAccountCollateralVault extends string | AccountMeta<string> = string,
|
|
65
65
|
TAccountWriterCollateralAccount extends string | AccountMeta<string> = string,
|
|
66
|
+
TAccountOmlpVaultState extends string | AccountMeta<string> = string,
|
|
66
67
|
TAccountOmlpVault extends string | AccountMeta<string> = string,
|
|
67
68
|
TAccountFeeWallet extends string | AccountMeta<string> = string,
|
|
68
69
|
TAccountWriter extends string | AccountMeta<string> = string,
|
|
@@ -105,6 +106,9 @@ export type UnwindWriterUnsoldInstruction<
|
|
|
105
106
|
TAccountWriterCollateralAccount extends string
|
|
106
107
|
? WritableAccount<TAccountWriterCollateralAccount>
|
|
107
108
|
: TAccountWriterCollateralAccount,
|
|
109
|
+
TAccountOmlpVaultState extends string
|
|
110
|
+
? WritableAccount<TAccountOmlpVaultState>
|
|
111
|
+
: TAccountOmlpVaultState,
|
|
108
112
|
TAccountOmlpVault extends string
|
|
109
113
|
? WritableAccount<TAccountOmlpVault>
|
|
110
114
|
: TAccountOmlpVault,
|
|
@@ -175,6 +179,7 @@ export type UnwindWriterUnsoldAsyncInput<
|
|
|
175
179
|
TAccountWriterShortAccount extends string = string,
|
|
176
180
|
TAccountCollateralVault extends string = string,
|
|
177
181
|
TAccountWriterCollateralAccount extends string = string,
|
|
182
|
+
TAccountOmlpVaultState extends string = string,
|
|
178
183
|
TAccountOmlpVault extends string = string,
|
|
179
184
|
TAccountFeeWallet extends string = string,
|
|
180
185
|
TAccountWriter extends string = string,
|
|
@@ -201,6 +206,8 @@ export type UnwindWriterUnsoldAsyncInput<
|
|
|
201
206
|
collateralVault: Address<TAccountCollateralVault>;
|
|
202
207
|
/** Writer's underlying token account (receives returned collateral) */
|
|
203
208
|
writerCollateralAccount: Address<TAccountWriterCollateralAccount>;
|
|
209
|
+
/** OMLP Vault state PDA (for total_loans, add_interest_to_index) - optional, required when repaying loans */
|
|
210
|
+
omlpVaultState?: Address<TAccountOmlpVaultState>;
|
|
204
211
|
/** OMLP vault token account (receives loan repayments) - optional */
|
|
205
212
|
omlpVault?: Address<TAccountOmlpVault>;
|
|
206
213
|
/** Protocol fee wallet (receives protocol fees) - optional */
|
|
@@ -222,6 +229,7 @@ export async function getUnwindWriterUnsoldInstructionAsync<
|
|
|
222
229
|
TAccountWriterShortAccount extends string,
|
|
223
230
|
TAccountCollateralVault extends string,
|
|
224
231
|
TAccountWriterCollateralAccount extends string,
|
|
232
|
+
TAccountOmlpVaultState extends string,
|
|
225
233
|
TAccountOmlpVault extends string,
|
|
226
234
|
TAccountFeeWallet extends string,
|
|
227
235
|
TAccountWriter extends string,
|
|
@@ -240,6 +248,7 @@ export async function getUnwindWriterUnsoldInstructionAsync<
|
|
|
240
248
|
TAccountWriterShortAccount,
|
|
241
249
|
TAccountCollateralVault,
|
|
242
250
|
TAccountWriterCollateralAccount,
|
|
251
|
+
TAccountOmlpVaultState,
|
|
243
252
|
TAccountOmlpVault,
|
|
244
253
|
TAccountFeeWallet,
|
|
245
254
|
TAccountWriter,
|
|
@@ -260,6 +269,7 @@ export async function getUnwindWriterUnsoldInstructionAsync<
|
|
|
260
269
|
TAccountWriterShortAccount,
|
|
261
270
|
TAccountCollateralVault,
|
|
262
271
|
TAccountWriterCollateralAccount,
|
|
272
|
+
TAccountOmlpVaultState,
|
|
263
273
|
TAccountOmlpVault,
|
|
264
274
|
TAccountFeeWallet,
|
|
265
275
|
TAccountWriter,
|
|
@@ -292,6 +302,7 @@ export async function getUnwindWriterUnsoldInstructionAsync<
|
|
|
292
302
|
value: input.writerCollateralAccount ?? null,
|
|
293
303
|
isWritable: true,
|
|
294
304
|
},
|
|
305
|
+
omlpVaultState: { value: input.omlpVaultState ?? null, isWritable: true },
|
|
295
306
|
omlpVault: { value: input.omlpVault ?? null, isWritable: true },
|
|
296
307
|
feeWallet: { value: input.feeWallet ?? null, isWritable: true },
|
|
297
308
|
writer: { value: input.writer ?? null, isWritable: true },
|
|
@@ -358,6 +369,7 @@ export async function getUnwindWriterUnsoldInstructionAsync<
|
|
|
358
369
|
getAccountMeta(accounts.writerShortAccount),
|
|
359
370
|
getAccountMeta(accounts.collateralVault),
|
|
360
371
|
getAccountMeta(accounts.writerCollateralAccount),
|
|
372
|
+
getAccountMeta(accounts.omlpVaultState),
|
|
361
373
|
getAccountMeta(accounts.omlpVault),
|
|
362
374
|
getAccountMeta(accounts.feeWallet),
|
|
363
375
|
getAccountMeta(accounts.writer),
|
|
@@ -380,6 +392,7 @@ export async function getUnwindWriterUnsoldInstructionAsync<
|
|
|
380
392
|
TAccountWriterShortAccount,
|
|
381
393
|
TAccountCollateralVault,
|
|
382
394
|
TAccountWriterCollateralAccount,
|
|
395
|
+
TAccountOmlpVaultState,
|
|
383
396
|
TAccountOmlpVault,
|
|
384
397
|
TAccountFeeWallet,
|
|
385
398
|
TAccountWriter,
|
|
@@ -399,6 +412,7 @@ export type UnwindWriterUnsoldInput<
|
|
|
399
412
|
TAccountWriterShortAccount extends string = string,
|
|
400
413
|
TAccountCollateralVault extends string = string,
|
|
401
414
|
TAccountWriterCollateralAccount extends string = string,
|
|
415
|
+
TAccountOmlpVaultState extends string = string,
|
|
402
416
|
TAccountOmlpVault extends string = string,
|
|
403
417
|
TAccountFeeWallet extends string = string,
|
|
404
418
|
TAccountWriter extends string = string,
|
|
@@ -425,6 +439,8 @@ export type UnwindWriterUnsoldInput<
|
|
|
425
439
|
collateralVault: Address<TAccountCollateralVault>;
|
|
426
440
|
/** Writer's underlying token account (receives returned collateral) */
|
|
427
441
|
writerCollateralAccount: Address<TAccountWriterCollateralAccount>;
|
|
442
|
+
/** OMLP Vault state PDA (for total_loans, add_interest_to_index) - optional, required when repaying loans */
|
|
443
|
+
omlpVaultState?: Address<TAccountOmlpVaultState>;
|
|
428
444
|
/** OMLP vault token account (receives loan repayments) - optional */
|
|
429
445
|
omlpVault?: Address<TAccountOmlpVault>;
|
|
430
446
|
/** Protocol fee wallet (receives protocol fees) - optional */
|
|
@@ -446,6 +462,7 @@ export function getUnwindWriterUnsoldInstruction<
|
|
|
446
462
|
TAccountWriterShortAccount extends string,
|
|
447
463
|
TAccountCollateralVault extends string,
|
|
448
464
|
TAccountWriterCollateralAccount extends string,
|
|
465
|
+
TAccountOmlpVaultState extends string,
|
|
449
466
|
TAccountOmlpVault extends string,
|
|
450
467
|
TAccountFeeWallet extends string,
|
|
451
468
|
TAccountWriter extends string,
|
|
@@ -464,6 +481,7 @@ export function getUnwindWriterUnsoldInstruction<
|
|
|
464
481
|
TAccountWriterShortAccount,
|
|
465
482
|
TAccountCollateralVault,
|
|
466
483
|
TAccountWriterCollateralAccount,
|
|
484
|
+
TAccountOmlpVaultState,
|
|
467
485
|
TAccountOmlpVault,
|
|
468
486
|
TAccountFeeWallet,
|
|
469
487
|
TAccountWriter,
|
|
@@ -483,6 +501,7 @@ export function getUnwindWriterUnsoldInstruction<
|
|
|
483
501
|
TAccountWriterShortAccount,
|
|
484
502
|
TAccountCollateralVault,
|
|
485
503
|
TAccountWriterCollateralAccount,
|
|
504
|
+
TAccountOmlpVaultState,
|
|
486
505
|
TAccountOmlpVault,
|
|
487
506
|
TAccountFeeWallet,
|
|
488
507
|
TAccountWriter,
|
|
@@ -514,6 +533,7 @@ export function getUnwindWriterUnsoldInstruction<
|
|
|
514
533
|
value: input.writerCollateralAccount ?? null,
|
|
515
534
|
isWritable: true,
|
|
516
535
|
},
|
|
536
|
+
omlpVaultState: { value: input.omlpVaultState ?? null, isWritable: true },
|
|
517
537
|
omlpVault: { value: input.omlpVault ?? null, isWritable: true },
|
|
518
538
|
feeWallet: { value: input.feeWallet ?? null, isWritable: true },
|
|
519
539
|
writer: { value: input.writer ?? null, isWritable: true },
|
|
@@ -551,6 +571,7 @@ export function getUnwindWriterUnsoldInstruction<
|
|
|
551
571
|
getAccountMeta(accounts.writerShortAccount),
|
|
552
572
|
getAccountMeta(accounts.collateralVault),
|
|
553
573
|
getAccountMeta(accounts.writerCollateralAccount),
|
|
574
|
+
getAccountMeta(accounts.omlpVaultState),
|
|
554
575
|
getAccountMeta(accounts.omlpVault),
|
|
555
576
|
getAccountMeta(accounts.feeWallet),
|
|
556
577
|
getAccountMeta(accounts.writer),
|
|
@@ -573,6 +594,7 @@ export function getUnwindWriterUnsoldInstruction<
|
|
|
573
594
|
TAccountWriterShortAccount,
|
|
574
595
|
TAccountCollateralVault,
|
|
575
596
|
TAccountWriterCollateralAccount,
|
|
597
|
+
TAccountOmlpVaultState,
|
|
576
598
|
TAccountOmlpVault,
|
|
577
599
|
TAccountFeeWallet,
|
|
578
600
|
TAccountWriter,
|
|
@@ -607,13 +629,15 @@ export type ParsedUnwindWriterUnsoldInstruction<
|
|
|
607
629
|
collateralVault: TAccountMetas[8];
|
|
608
630
|
/** Writer's underlying token account (receives returned collateral) */
|
|
609
631
|
writerCollateralAccount: TAccountMetas[9];
|
|
632
|
+
/** OMLP Vault state PDA (for total_loans, add_interest_to_index) - optional, required when repaying loans */
|
|
633
|
+
omlpVaultState?: TAccountMetas[10] | undefined;
|
|
610
634
|
/** OMLP vault token account (receives loan repayments) - optional */
|
|
611
|
-
omlpVault?: TAccountMetas[
|
|
635
|
+
omlpVault?: TAccountMetas[11] | undefined;
|
|
612
636
|
/** Protocol fee wallet (receives protocol fees) - optional */
|
|
613
|
-
feeWallet?: TAccountMetas[
|
|
614
|
-
writer: TAccountMetas[
|
|
615
|
-
tokenProgram: TAccountMetas[
|
|
616
|
-
systemProgram: TAccountMetas[
|
|
637
|
+
feeWallet?: TAccountMetas[12] | undefined;
|
|
638
|
+
writer: TAccountMetas[13];
|
|
639
|
+
tokenProgram: TAccountMetas[14];
|
|
640
|
+
systemProgram: TAccountMetas[15];
|
|
617
641
|
};
|
|
618
642
|
data: UnwindWriterUnsoldInstructionData;
|
|
619
643
|
};
|
|
@@ -626,7 +650,7 @@ export function parseUnwindWriterUnsoldInstruction<
|
|
|
626
650
|
InstructionWithAccounts<TAccountMetas> &
|
|
627
651
|
InstructionWithData<ReadonlyUint8Array>,
|
|
628
652
|
): ParsedUnwindWriterUnsoldInstruction<TProgram, TAccountMetas> {
|
|
629
|
-
if (instruction.accounts.length <
|
|
653
|
+
if (instruction.accounts.length < 16) {
|
|
630
654
|
// TODO: Coded error.
|
|
631
655
|
throw new Error("Not enough accounts");
|
|
632
656
|
}
|
|
@@ -655,6 +679,7 @@ export function parseUnwindWriterUnsoldInstruction<
|
|
|
655
679
|
writerShortAccount: getNextAccount(),
|
|
656
680
|
collateralVault: getNextAccount(),
|
|
657
681
|
writerCollateralAccount: getNextAccount(),
|
|
682
|
+
omlpVaultState: getNextOptionalAccount(),
|
|
658
683
|
omlpVault: getNextOptionalAccount(),
|
|
659
684
|
feeWallet: getNextOptionalAccount(),
|
|
660
685
|
writer: getNextAccount(),
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
parseOptionMintInstruction,
|
|
42
42
|
parseOptionValidateInstruction,
|
|
43
43
|
parseRepayPoolLoanFromCollateralInstruction,
|
|
44
|
+
parseRepayPoolLoanFromWalletInstruction,
|
|
44
45
|
parseRepayPoolLoanInstruction,
|
|
45
46
|
parseSettleMakerCollateralInstruction,
|
|
46
47
|
parseSyncWriterPositionInstruction,
|
|
@@ -74,6 +75,7 @@ import {
|
|
|
74
75
|
type ParsedOptionMintInstruction,
|
|
75
76
|
type ParsedOptionValidateInstruction,
|
|
76
77
|
type ParsedRepayPoolLoanFromCollateralInstruction,
|
|
78
|
+
type ParsedRepayPoolLoanFromWalletInstruction,
|
|
77
79
|
type ParsedRepayPoolLoanInstruction,
|
|
78
80
|
type ParsedSettleMakerCollateralInstruction,
|
|
79
81
|
type ParsedSyncWriterPositionInstruction,
|
|
@@ -282,6 +284,7 @@ export enum OptionProgramInstruction {
|
|
|
282
284
|
OptionValidate,
|
|
283
285
|
RepayPoolLoan,
|
|
284
286
|
RepayPoolLoanFromCollateral,
|
|
287
|
+
RepayPoolLoanFromWallet,
|
|
285
288
|
SettleMakerCollateral,
|
|
286
289
|
SyncWriterPosition,
|
|
287
290
|
TransferAdmin,
|
|
@@ -571,6 +574,17 @@ export function identifyOptionProgramInstruction(
|
|
|
571
574
|
) {
|
|
572
575
|
return OptionProgramInstruction.RepayPoolLoanFromCollateral;
|
|
573
576
|
}
|
|
577
|
+
if (
|
|
578
|
+
containsBytes(
|
|
579
|
+
data,
|
|
580
|
+
fixEncoderSize(getBytesEncoder(), 8).encode(
|
|
581
|
+
new Uint8Array([78, 130, 135, 90, 211, 21, 247, 247]),
|
|
582
|
+
),
|
|
583
|
+
0,
|
|
584
|
+
)
|
|
585
|
+
) {
|
|
586
|
+
return OptionProgramInstruction.RepayPoolLoanFromWallet;
|
|
587
|
+
}
|
|
574
588
|
if (
|
|
575
589
|
containsBytes(
|
|
576
590
|
data,
|
|
@@ -742,6 +756,9 @@ export type ParsedOptionProgramInstruction<
|
|
|
742
756
|
| ({
|
|
743
757
|
instructionType: OptionProgramInstruction.RepayPoolLoanFromCollateral;
|
|
744
758
|
} & ParsedRepayPoolLoanFromCollateralInstruction<TProgram>)
|
|
759
|
+
| ({
|
|
760
|
+
instructionType: OptionProgramInstruction.RepayPoolLoanFromWallet;
|
|
761
|
+
} & ParsedRepayPoolLoanFromWalletInstruction<TProgram>)
|
|
745
762
|
| ({
|
|
746
763
|
instructionType: OptionProgramInstruction.SettleMakerCollateral;
|
|
747
764
|
} & ParsedSettleMakerCollateralInstruction<TProgram>)
|
|
@@ -947,6 +964,13 @@ export function parseOptionProgramInstruction<TProgram extends string>(
|
|
|
947
964
|
...parseRepayPoolLoanFromCollateralInstruction(instruction),
|
|
948
965
|
};
|
|
949
966
|
}
|
|
967
|
+
case OptionProgramInstruction.RepayPoolLoanFromWallet: {
|
|
968
|
+
assertIsInstructionWithAccounts(instruction);
|
|
969
|
+
return {
|
|
970
|
+
instructionType: OptionProgramInstruction.RepayPoolLoanFromWallet,
|
|
971
|
+
...parseRepayPoolLoanFromWalletInstruction(instruction),
|
|
972
|
+
};
|
|
973
|
+
}
|
|
950
974
|
case OptionProgramInstruction.SettleMakerCollateral: {
|
|
951
975
|
assertIsInstructionWithAccounts(instruction);
|
|
952
976
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epicentral/sos-sdk",
|
|
3
|
-
"version": "0.2
|
|
3
|
+
"version": "0.3.0-alpha.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Solana Option Standard SDK. The frontend-first SDK for Native Options Trading on Solana. Created by Epicentral Labs.",
|
|
6
6
|
"type": "module",
|
|
@@ -23,6 +23,9 @@
|
|
|
23
23
|
"decimal.js": "^10.4.3"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
|
-
"typecheck": "tsc --project tsconfig.json --noEmit"
|
|
26
|
+
"typecheck": "tsc --project tsconfig.json --noEmit",
|
|
27
|
+
"publish-beta": "dotenv -e .env -- pnpm publish --access public --tag beta",
|
|
28
|
+
"publish-alpha": "dotenv -e .env -- pnpm publish --access public --tag alpha",
|
|
29
|
+
"deprecate": "dotenv -e .env -- pnpm exec npm deprecate"
|
|
27
30
|
}
|
|
28
31
|
}
|
package/short/builders.ts
CHANGED
|
@@ -8,11 +8,14 @@ import {
|
|
|
8
8
|
import type { Instruction } from "@solana/kit";
|
|
9
9
|
import { toAddress } from "../client/program";
|
|
10
10
|
import type { AddressLike, BuiltTransaction, KitRpc } from "../client/types";
|
|
11
|
+
import { fetchVault } from "../accounts/fetchers";
|
|
12
|
+
import { fetchPoolLoansByMaker } from "../accounts/list";
|
|
11
13
|
import { resolveOptionAccounts } from "../accounts/resolve-option";
|
|
12
14
|
import {
|
|
13
15
|
deriveAssociatedTokenAddress,
|
|
14
16
|
deriveMakerCollateralSharePda,
|
|
15
17
|
deriveMetadataPda,
|
|
18
|
+
deriveVaultPda,
|
|
16
19
|
deriveWriterPositionPda,
|
|
17
20
|
} from "../accounts/pdas";
|
|
18
21
|
import { assertNonNegativeAmount, assertPositiveAmount } from "../shared/amounts";
|
|
@@ -59,6 +62,9 @@ export interface BuildOptionMintParams {
|
|
|
59
62
|
remainingAccounts?: RemainingAccountInput[];
|
|
60
63
|
}
|
|
61
64
|
|
|
65
|
+
/** Max PoolLoans per unwind to stay under 64-account tx limit (~18 named + ~20 loans) */
|
|
66
|
+
const MAX_POOL_LOANS_PER_UNWIND = 20;
|
|
67
|
+
|
|
62
68
|
export interface BuildUnwindWriterUnsoldParams {
|
|
63
69
|
optionPool: AddressLike;
|
|
64
70
|
optionAccount: AddressLike;
|
|
@@ -72,6 +78,7 @@ export interface BuildUnwindWriterUnsoldParams {
|
|
|
72
78
|
unwindQty: bigint | number;
|
|
73
79
|
collateralPool?: AddressLike;
|
|
74
80
|
writerPosition?: AddressLike;
|
|
81
|
+
omlpVaultState?: AddressLike;
|
|
75
82
|
omlpVault?: AddressLike;
|
|
76
83
|
feeWallet?: AddressLike;
|
|
77
84
|
remainingAccounts?: RemainingAccountInput[];
|
|
@@ -308,6 +315,7 @@ export async function buildUnwindWriterUnsoldInstruction(
|
|
|
308
315
|
writerShortAccount: toAddress(params.writerShortAccount),
|
|
309
316
|
collateralVault: toAddress(params.collateralVault),
|
|
310
317
|
writerCollateralAccount: toAddress(params.writerCollateralAccount),
|
|
318
|
+
omlpVaultState: params.omlpVaultState ? toAddress(params.omlpVaultState) : undefined,
|
|
311
319
|
omlpVault: params.omlpVault ? toAddress(params.omlpVault) : undefined,
|
|
312
320
|
feeWallet: params.feeWallet ? toAddress(params.feeWallet) : undefined,
|
|
313
321
|
writer: toAddress(params.writer) as any,
|
|
@@ -333,11 +341,96 @@ export interface BuildUnwindWriterUnsoldTransactionWithDerivationParams {
|
|
|
333
341
|
unwindQty: bigint | number;
|
|
334
342
|
rpc: KitRpc;
|
|
335
343
|
programId?: AddressLike;
|
|
344
|
+
omlpVaultState?: AddressLike;
|
|
336
345
|
omlpVault?: AddressLike;
|
|
337
346
|
feeWallet?: AddressLike;
|
|
347
|
+
/**
|
|
348
|
+
* When repaying pool loans: [PoolLoan₁, PoolLoan₂, ...] (all writable).
|
|
349
|
+
* omlpVaultState, omlpVault, feeWallet must also be passed.
|
|
350
|
+
* Prefer {@link buildUnwindWriterUnsoldWithLoanRepayment} to build this automatically.
|
|
351
|
+
*/
|
|
338
352
|
remainingAccounts?: RemainingAccountInput[];
|
|
339
353
|
}
|
|
340
354
|
|
|
355
|
+
export interface BuildUnwindWriterUnsoldWithLoanRepaymentParams {
|
|
356
|
+
underlyingAsset: AddressLike;
|
|
357
|
+
optionType: OptionType;
|
|
358
|
+
strikePrice: number;
|
|
359
|
+
expirationDate: bigint | number;
|
|
360
|
+
writer: AddressLike;
|
|
361
|
+
unwindQty: bigint | number;
|
|
362
|
+
rpc: KitRpc;
|
|
363
|
+
programId?: AddressLike;
|
|
364
|
+
/** Override when pool fetch is not used; otherwise resolved from option pool. */
|
|
365
|
+
underlyingMint?: AddressLike;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Builds an unwind_writer_unsold transaction that also repays any active pool loans
|
|
370
|
+
* for the option's underlying vault. When a writer unwinds an unsold short that had
|
|
371
|
+
* borrowed from OMLP, the program repays lenders from the collateral vault (burn,
|
|
372
|
+
* repay, then return collateral to writer) in one instruction.
|
|
373
|
+
*
|
|
374
|
+
* Passes omlpVaultState (Vault PDA), omlpVault, feeWallet as named accounts.
|
|
375
|
+
* remaining_accounts: [PoolLoan₁, PoolLoan₂, ...] only (capped at 20).
|
|
376
|
+
* If no active pool loans exist, still passes vault accounts so the API works for all unwinds.
|
|
377
|
+
*/
|
|
378
|
+
export async function buildUnwindWriterUnsoldWithLoanRepayment(
|
|
379
|
+
params: BuildUnwindWriterUnsoldWithLoanRepaymentParams
|
|
380
|
+
): Promise<BuiltTransaction> {
|
|
381
|
+
const resolved = await resolveOptionAccounts({
|
|
382
|
+
underlyingAsset: params.underlyingAsset,
|
|
383
|
+
optionType: params.optionType,
|
|
384
|
+
strikePrice: params.strikePrice,
|
|
385
|
+
expirationDate: params.expirationDate,
|
|
386
|
+
programId: params.programId,
|
|
387
|
+
rpc: params.rpc,
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
const underlyingMint = params.underlyingMint ?? resolved.underlyingMint;
|
|
391
|
+
invariant(
|
|
392
|
+
!!underlyingMint,
|
|
393
|
+
"underlyingMint is required; ensure rpc is provided and option pool is initialized, or pass underlyingMint."
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
const [vaultPda] = await deriveVaultPda(underlyingMint, params.programId);
|
|
397
|
+
const vaultPdaStr = toAddress(vaultPda);
|
|
398
|
+
|
|
399
|
+
const [loans, vault] = await Promise.all([
|
|
400
|
+
fetchPoolLoansByMaker(params.rpc, params.writer),
|
|
401
|
+
fetchVault(params.rpc, vaultPda),
|
|
402
|
+
]);
|
|
403
|
+
|
|
404
|
+
const vaultLoans = loans
|
|
405
|
+
.filter((item) => toAddress(item.data.vault) === vaultPdaStr)
|
|
406
|
+
.slice(0, MAX_POOL_LOANS_PER_UNWIND);
|
|
407
|
+
|
|
408
|
+
const remainingAccounts: RemainingAccountInput[] = vaultLoans.map((item) => ({
|
|
409
|
+
address: item.address,
|
|
410
|
+
isWritable: true,
|
|
411
|
+
}));
|
|
412
|
+
|
|
413
|
+
const omlpVault = await deriveAssociatedTokenAddress(vaultPda, underlyingMint);
|
|
414
|
+
const feeWallet = vault
|
|
415
|
+
? await deriveAssociatedTokenAddress(vault.feeWallet, underlyingMint)
|
|
416
|
+
: undefined;
|
|
417
|
+
|
|
418
|
+
return buildUnwindWriterUnsoldTransactionWithDerivation({
|
|
419
|
+
underlyingAsset: params.underlyingAsset,
|
|
420
|
+
optionType: params.optionType,
|
|
421
|
+
strikePrice: params.strikePrice,
|
|
422
|
+
expirationDate: params.expirationDate,
|
|
423
|
+
writer: params.writer,
|
|
424
|
+
unwindQty: params.unwindQty,
|
|
425
|
+
rpc: params.rpc,
|
|
426
|
+
programId: params.programId,
|
|
427
|
+
omlpVaultState: vaultPda,
|
|
428
|
+
omlpVault,
|
|
429
|
+
feeWallet,
|
|
430
|
+
remainingAccounts,
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
|
|
341
434
|
export async function buildUnwindWriterUnsoldTransactionWithDerivation(
|
|
342
435
|
params: BuildUnwindWriterUnsoldTransactionWithDerivationParams
|
|
343
436
|
): Promise<BuiltTransaction> {
|
|
@@ -375,6 +468,7 @@ export async function buildUnwindWriterUnsoldTransactionWithDerivation(
|
|
|
375
468
|
unwindQty: params.unwindQty,
|
|
376
469
|
collateralPool: resolved.collateralPool,
|
|
377
470
|
writerPosition: writerPosition[0],
|
|
471
|
+
omlpVaultState: params.omlpVaultState,
|
|
378
472
|
omlpVault: params.omlpVault,
|
|
379
473
|
feeWallet: params.feeWallet,
|
|
380
474
|
remainingAccounts: params.remainingAccounts,
|
package/short/pool.ts
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
getBorrowFromPoolInstructionAsync,
|
|
3
3
|
getRepayPoolLoanInstructionAsync,
|
|
4
4
|
getRepayPoolLoanFromCollateralInstructionAsync,
|
|
5
|
+
getRepayPoolLoanFromWalletInstructionAsync,
|
|
5
6
|
} from "../generated/instructions";
|
|
6
7
|
import type { Instruction } from "@solana/kit";
|
|
7
8
|
import { toAddress } from "../client/program";
|
|
@@ -114,6 +115,39 @@ export async function buildRepayPoolLoanTransaction(
|
|
|
114
115
|
return { instructions: [instruction] };
|
|
115
116
|
}
|
|
116
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Repay a pool loan entirely from maker's wallet (no escrow used).
|
|
120
|
+
* Use when standard repay fails with InsufficientEscrowBalance (stuck loan).
|
|
121
|
+
*/
|
|
122
|
+
export async function buildRepayPoolLoanFromWalletInstruction(
|
|
123
|
+
params: BuildRepayPoolLoanParams
|
|
124
|
+
): Promise<Instruction<string>> {
|
|
125
|
+
return getRepayPoolLoanFromWalletInstructionAsync({
|
|
126
|
+
poolLoan: toAddress(params.poolLoan),
|
|
127
|
+
vault: toAddress(params.vault),
|
|
128
|
+
vaultTokenAccount: toAddress(params.vaultTokenAccount),
|
|
129
|
+
escrowState: toAddress(params.escrowState),
|
|
130
|
+
escrowAuthority: params.escrowAuthority
|
|
131
|
+
? toAddress(params.escrowAuthority)
|
|
132
|
+
: undefined,
|
|
133
|
+
escrowTokenAccount: toAddress(params.escrowTokenAccount),
|
|
134
|
+
makerTokenAccount: toAddress(params.makerTokenAccount),
|
|
135
|
+
feeWalletTokenAccount: toAddress(params.feeWalletTokenAccount),
|
|
136
|
+
maker: toAddress(params.maker) as any,
|
|
137
|
+
tokenProgram: params.tokenProgram ? toAddress(params.tokenProgram) : undefined,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Builds the repay-from-wallet transaction (stuck loan recovery).
|
|
143
|
+
*/
|
|
144
|
+
export async function buildRepayPoolLoanFromWalletTransaction(
|
|
145
|
+
params: BuildRepayPoolLoanParams
|
|
146
|
+
): Promise<BuiltTransaction> {
|
|
147
|
+
const instruction = await buildRepayPoolLoanFromWalletInstruction(params);
|
|
148
|
+
return { instructions: [instruction] };
|
|
149
|
+
}
|
|
150
|
+
|
|
117
151
|
export async function buildRepayPoolLoanFromCollateralInstruction(
|
|
118
152
|
params: BuildRepayPoolLoanFromCollateralParams
|
|
119
153
|
): Promise<Instruction<string>> {
|