@epicentral/sos-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +239 -0
- package/accounts/fetchers.ts +140 -0
- package/accounts/list.ts +152 -0
- package/accounts/pdas.ts +308 -0
- package/client/lookup-table.ts +32 -0
- package/client/program.ts +13 -0
- package/client/types.ts +8 -0
- package/generated/accounts/collateralPool.ts +217 -0
- package/generated/accounts/config.ts +156 -0
- package/generated/accounts/dualSourceContract.ts +235 -0
- package/generated/accounts/escrowState.ts +183 -0
- package/generated/accounts/index.ts +24 -0
- package/generated/accounts/lenderPosition.ts +211 -0
- package/generated/accounts/liquidityRouter.ts +223 -0
- package/generated/accounts/makerCollateralShare.ts +229 -0
- package/generated/accounts/makerPoolShare.ts +203 -0
- package/generated/accounts/marketDataAccount.ts +176 -0
- package/generated/accounts/optionAccount.ts +247 -0
- package/generated/accounts/optionPool.ts +253 -0
- package/generated/accounts/poolLoan.ts +220 -0
- package/generated/accounts/positionAccount.ts +187 -0
- package/generated/accounts/priceUpdateV2.ts +163 -0
- package/generated/accounts/vault.ts +304 -0
- package/generated/accounts/writerPosition.ts +297 -0
- package/generated/errors/index.ts +9 -0
- package/generated/errors/optionProgram.ts +392 -0
- package/generated/index.ts +13 -0
- package/generated/instructions/acceptAdmin.ts +230 -0
- package/generated/instructions/autoExerciseAllExpired.ts +523 -0
- package/generated/instructions/autoExerciseExpired.ts +623 -0
- package/generated/instructions/borrowFromPool.ts +554 -0
- package/generated/instructions/buyFromPool.ts +684 -0
- package/generated/instructions/claimPremium.ts +377 -0
- package/generated/instructions/closeLongToPool.ts +716 -0
- package/generated/instructions/closeOption.ts +235 -0
- package/generated/instructions/createEscrowV2.ts +518 -0
- package/generated/instructions/createLiquidityRouter.ts +361 -0
- package/generated/instructions/depositCollateral.ts +624 -0
- package/generated/instructions/depositToPool.ts +497 -0
- package/generated/instructions/depositToPosition.ts +429 -0
- package/generated/instructions/index.ts +45 -0
- package/generated/instructions/initCollateralPool.ts +513 -0
- package/generated/instructions/initConfig.ts +279 -0
- package/generated/instructions/initOptionPool.ts +587 -0
- package/generated/instructions/initializeMarketData.ts +359 -0
- package/generated/instructions/liquidateWriterPosition.ts +592 -0
- package/generated/instructions/omlpCreateVault.ts +547 -0
- package/generated/instructions/omlpTakeOfferWithFailover.ts +606 -0
- package/generated/instructions/omlpUpdateMaxLeverage.ts +304 -0
- package/generated/instructions/omlpUpdateProtocolFee.ts +304 -0
- package/generated/instructions/omlpUpdateSupplyLimit.ts +304 -0
- package/generated/instructions/optionExercise.ts +540 -0
- package/generated/instructions/optionMint.ts +1349 -0
- package/generated/instructions/optionValidate.ts +255 -0
- package/generated/instructions/repayPoolLoan.ts +499 -0
- package/generated/instructions/repayPoolLoanFromCollateral.ts +514 -0
- package/generated/instructions/settleMakerCollateral.ts +472 -0
- package/generated/instructions/syncWriterPosition.ts +206 -0
- package/generated/instructions/transferAdmin.ts +245 -0
- package/generated/instructions/unwindWriterUnsold.ts +668 -0
- package/generated/instructions/updateImpliedVolatility.ts +226 -0
- package/generated/instructions/updateMarketData.ts +315 -0
- package/generated/instructions/withdrawFromPool.ts +429 -0
- package/generated/instructions/withdrawFromPosition.ts +405 -0
- package/generated/instructions/writeToPool.ts +594 -0
- package/generated/programs/index.ts +9 -0
- package/generated/programs/optionProgram.ts +832 -0
- package/generated/shared/index.ts +164 -0
- package/generated/types/borrowedFromSAP1.ts +75 -0
- package/generated/types/borrowedFromSAP2.ts +83 -0
- package/generated/types/failoverTriggered.ts +85 -0
- package/generated/types/impliedVolatilityUpdated.ts +73 -0
- package/generated/types/index.ts +32 -0
- package/generated/types/liquidationExecuted.ts +73 -0
- package/generated/types/liquidityMetrics.ts +69 -0
- package/generated/types/liquidityRouterCreated.ts +79 -0
- package/generated/types/marketDataInitialized.ts +61 -0
- package/generated/types/marketDataUpdated.ts +69 -0
- package/generated/types/optionClosed.ts +56 -0
- package/generated/types/optionExercised.ts +62 -0
- package/generated/types/optionExpired.ts +49 -0
- package/generated/types/optionMinted.ts +78 -0
- package/generated/types/optionType.ts +38 -0
- package/generated/types/optionValidated.ts +82 -0
- package/generated/types/poolLoanCreated.ts +74 -0
- package/generated/types/poolLoanRepaid.ts +74 -0
- package/generated/types/positionDeposited.ts +73 -0
- package/generated/types/positionWithdrawn.ts +81 -0
- package/generated/types/priceFeedMessage.ts +117 -0
- package/generated/types/protocolFeeUpdated.ts +69 -0
- package/generated/types/sap2Provider.ts +38 -0
- package/generated/types/vaultCreated.ts +60 -0
- package/generated/types/verificationLevel.ts +95 -0
- package/index.ts +25 -0
- package/long/builders.ts +126 -0
- package/long/exercise.ts +49 -0
- package/long/quotes.ts +48 -0
- package/omlp/builders.ts +74 -0
- package/omlp/service.ts +94 -0
- package/package.json +22 -0
- package/shared/amounts.ts +32 -0
- package/shared/errors.ts +12 -0
- package/shared/remaining-accounts.ts +41 -0
- package/shared/transactions.ts +49 -0
- package/short/builders.ts +268 -0
- package/short/claim-premium.ts +37 -0
- package/short/close-option.ts +34 -0
- package/short/pool.ts +224 -0
- package/tsconfig.json +12 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Epicentral Labs, DAO LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# SDK (Frontend-First)
|
|
2
|
+
|
|
3
|
+
This SDK is organized by feature and wraps the Codama-generated client for the `option_program`.
|
|
4
|
+
It is Kit-native and uses `@solana/kit` types (`Address`, `Instruction`, `Rpc`) across the public API.
|
|
5
|
+
The package entrypoint is `@epicentral/sos-sdk`.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @solana/kit decimal.js
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
In this repository, the SDK source lives at `epicentral/sos-sdk` and is packaged as
|
|
14
|
+
`@epicentral/sos-sdk`.
|
|
15
|
+
|
|
16
|
+
## Structure
|
|
17
|
+
|
|
18
|
+
- `client/` shared program constants and address helpers for the option program.
|
|
19
|
+
- `accounts/` PDA derivation and account fetch helpers.
|
|
20
|
+
- `long/` LONG buy/close/exercise/quote builders.
|
|
21
|
+
- `short/` SHORT mint/unwind/sync/settle plus premium/pool/loan builders.
|
|
22
|
+
- `omlp/` lender deposit/withdraw instruction builders.
|
|
23
|
+
- `shared/` common amount, error, and remaining account helpers.
|
|
24
|
+
- `generated/` Codama-generated client (bundled; do not edit).
|
|
25
|
+
|
|
26
|
+
## Updating the bundled client
|
|
27
|
+
|
|
28
|
+
The SDK bundles the program client in `generated/`. From the **option-program** repo root:
|
|
29
|
+
|
|
30
|
+
1. Regenerate the client: `yarn generate:client`.
|
|
31
|
+
2. Sync into the SDK and copy to the standalone repo: `yarn sync:sdk`.
|
|
32
|
+
|
|
33
|
+
Or run the full pipeline: `yarn generate:client:with-sdk`. The script copies the client into `epicentral/sos-sdk/generated` and then copies the entire SDK to the standalone repo (default `../sos-sdk`) so you can commit from there. Override the standalone path with `STANDALONE_SDK_PATH=/path/to/sos-sdk yarn sync:sdk`.
|
|
34
|
+
|
|
35
|
+
## Usage model
|
|
36
|
+
|
|
37
|
+
Each flow exposes:
|
|
38
|
+
|
|
39
|
+
- `build*Instruction(params)` for single instruction composition.
|
|
40
|
+
- `build*Transaction(params)` for one-flow `Instruction[]` construction.
|
|
41
|
+
- optional domain services for multi-step flows (no send/confirm).
|
|
42
|
+
|
|
43
|
+
## Core examples
|
|
44
|
+
|
|
45
|
+
### Build + send (app-owned)
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import {
|
|
49
|
+
appendTransactionMessageInstructions,
|
|
50
|
+
createTransactionMessage,
|
|
51
|
+
getSignatureFromTransaction,
|
|
52
|
+
pipe,
|
|
53
|
+
sendAndConfirmTransactionFactory,
|
|
54
|
+
setTransactionMessageFeePayerSigner,
|
|
55
|
+
setTransactionMessageLifetimeUsingBlockhash,
|
|
56
|
+
signTransactionMessageWithSigners,
|
|
57
|
+
} from "@solana/kit";
|
|
58
|
+
import { buildBuyFromPoolTransaction } from "@epicentral/sos-sdk";
|
|
59
|
+
|
|
60
|
+
const built = await buildBuyFromPoolTransaction(params);
|
|
61
|
+
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
|
|
62
|
+
|
|
63
|
+
const txMessage = pipe(
|
|
64
|
+
createTransactionMessage({ version: 0 }),
|
|
65
|
+
(tx) => setTransactionMessageFeePayerSigner(walletSigner, tx),
|
|
66
|
+
(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
|
|
67
|
+
(tx) => appendTransactionMessageInstructions(built.instructions, tx)
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
const signedTx = await signTransactionMessageWithSigners(txMessage);
|
|
71
|
+
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTx, {
|
|
72
|
+
commitment: "confirmed",
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const signature = getSignatureFromTransaction(signedTx);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Build + send (SDK helper)
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import {
|
|
82
|
+
buildBuyFromPoolTransaction,
|
|
83
|
+
sendBuiltTransaction,
|
|
84
|
+
} from "@epicentral/sos-sdk";
|
|
85
|
+
|
|
86
|
+
const built = await buildBuyFromPoolTransaction(params);
|
|
87
|
+
const signature = await sendBuiltTransaction({
|
|
88
|
+
rpc,
|
|
89
|
+
rpcSubscriptions,
|
|
90
|
+
feePayer: walletSigner,
|
|
91
|
+
instructions: built.instructions,
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Open LONG / close LONG
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import {
|
|
99
|
+
buildBuyFromPoolTransaction,
|
|
100
|
+
buildCloseLongToPoolTransaction,
|
|
101
|
+
} from "@epicentral/sos-sdk";
|
|
102
|
+
|
|
103
|
+
const openLong = await buildBuyFromPoolTransaction(openLongParams);
|
|
104
|
+
const closeLong = await buildCloseLongToPoolTransaction(closeLongParams);
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Exercise LONG
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
import { buildOptionExerciseTransaction } from "@epicentral/sos-sdk";
|
|
111
|
+
|
|
112
|
+
const exercise = buildOptionExerciseTransaction({
|
|
113
|
+
optionAccount,
|
|
114
|
+
positionAccount,
|
|
115
|
+
marketData,
|
|
116
|
+
underlyingMint,
|
|
117
|
+
priceUpdate,
|
|
118
|
+
buyerPaymentAccount,
|
|
119
|
+
makerCollateralAccount,
|
|
120
|
+
escrowState,
|
|
121
|
+
escrowTokenAccount,
|
|
122
|
+
escrowAuthority,
|
|
123
|
+
buyer,
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Open SHORT (option mint)
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import { buildOptionMintTransaction, OptionType } from "@epicentral/sos-sdk";
|
|
131
|
+
|
|
132
|
+
const built = await buildOptionMintTransaction({
|
|
133
|
+
optionType: OptionType.Call,
|
|
134
|
+
strikePrice,
|
|
135
|
+
expirationDate,
|
|
136
|
+
quantity,
|
|
137
|
+
underlyingAsset,
|
|
138
|
+
underlyingSymbol,
|
|
139
|
+
makerCollateralAmount,
|
|
140
|
+
borrowedAmount,
|
|
141
|
+
maker,
|
|
142
|
+
makerCollateralAccount,
|
|
143
|
+
underlyingMint,
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Unwind / Sync / Settle SHORT
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import {
|
|
151
|
+
buildSettleMakerCollateralTransaction,
|
|
152
|
+
buildSyncWriterPositionTransaction,
|
|
153
|
+
buildUnwindWriterUnsoldTransaction,
|
|
154
|
+
} from "@epicentral/sos-sdk";
|
|
155
|
+
|
|
156
|
+
const unwind = await buildUnwindWriterUnsoldTransaction(unwindParams);
|
|
157
|
+
const sync = buildSyncWriterPositionTransaction(syncParams);
|
|
158
|
+
const settle = await buildSettleMakerCollateralTransaction(settleParams);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Claim premium / close option
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
import {
|
|
165
|
+
buildClaimPremiumTransaction,
|
|
166
|
+
buildCloseOptionTransaction,
|
|
167
|
+
} from "@epicentral/sos-sdk";
|
|
168
|
+
|
|
169
|
+
const claim = await buildClaimPremiumTransaction({
|
|
170
|
+
optionPool,
|
|
171
|
+
makerPaymentAccount,
|
|
172
|
+
premiumVault,
|
|
173
|
+
maker,
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const close = buildCloseOptionTransaction({
|
|
177
|
+
optionAccount,
|
|
178
|
+
optionMint,
|
|
179
|
+
makerOptionAccount,
|
|
180
|
+
maker,
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Pool liquidity / borrow / repay
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
import {
|
|
188
|
+
buildBorrowFromPoolTransaction,
|
|
189
|
+
buildDepositToPoolTransaction,
|
|
190
|
+
buildRepayPoolLoanTransaction,
|
|
191
|
+
buildWithdrawFromPoolTransaction,
|
|
192
|
+
} from "@epicentral/sos-sdk";
|
|
193
|
+
|
|
194
|
+
const deposit = await buildDepositToPoolTransaction(depositToPoolParams);
|
|
195
|
+
const withdraw = await buildWithdrawFromPoolTransaction(withdrawFromPoolParams);
|
|
196
|
+
const borrow = await buildBorrowFromPoolTransaction(borrowFromPoolParams);
|
|
197
|
+
const repay = await buildRepayPoolLoanTransaction(repayPoolLoanParams);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Repayment source behavior:
|
|
201
|
+
|
|
202
|
+
- `buildRepayPoolLoanTransaction`: principal is repaid from `escrowTokenAccount`; accrued interest + protocol fees are repaid from `makerTokenAccount`.
|
|
203
|
+
- `buildRepayPoolLoanFromCollateralTransaction`: full repayment is sourced from `collateralVault`.
|
|
204
|
+
|
|
205
|
+
### OMLP deposit/withdraw
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
import {
|
|
209
|
+
buildDepositToPositionTransaction,
|
|
210
|
+
buildWithdrawFromPositionTransaction,
|
|
211
|
+
} from "@epicentral/sos-sdk";
|
|
212
|
+
|
|
213
|
+
const deposit = await buildDepositToPositionTransaction(
|
|
214
|
+
{ vault, lenderTokenAccount, vaultTokenAccount, lender, amount }
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
const withdraw = await buildWithdrawFromPositionTransaction(
|
|
218
|
+
{ vault, vaultTokenAccount, lenderTokenAccount, lender, amount }
|
|
219
|
+
);
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Replace Anchor reads with SDK fetchers
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
import { fetchOptionAccount, fetchOptionPool, fetchVault } from "@epicentral/sos-sdk";
|
|
226
|
+
|
|
227
|
+
const option = await fetchOptionAccount(rpc, optionAddress);
|
|
228
|
+
const pool = await fetchOptionPool(rpc, optionPoolAddress);
|
|
229
|
+
const vault = await fetchVault(rpc, vaultAddress);
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Migration notes
|
|
233
|
+
|
|
234
|
+
- This SDK is the only frontend integration surface for this repository.
|
|
235
|
+
- Legacy `frontend/constants`, `frontend/services`, and `frontend/utils` modules were removed.
|
|
236
|
+
- Replace Anchor `program.account.*` reads with SDK fetchers.
|
|
237
|
+
- Replace Anchor `program.methods.*` writes with SDK builders.
|
|
238
|
+
- App code should own message building, signing, send, and confirmation via `@solana/kit`.
|
|
239
|
+
- `long/service.ts` and `short/service.ts` were removed in favor of direct builder calls.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getCollateralPoolDecoder,
|
|
3
|
+
getLenderPositionDecoder,
|
|
4
|
+
getMakerPoolShareDecoder,
|
|
5
|
+
getMarketDataAccountDecoder,
|
|
6
|
+
getOptionAccountDecoder,
|
|
7
|
+
getOptionPoolDecoder,
|
|
8
|
+
getPoolLoanDecoder,
|
|
9
|
+
getPositionAccountDecoder,
|
|
10
|
+
getVaultDecoder,
|
|
11
|
+
getWriterPositionDecoder,
|
|
12
|
+
type CollateralPool,
|
|
13
|
+
type LenderPosition,
|
|
14
|
+
type MakerPoolShare,
|
|
15
|
+
type MarketDataAccount,
|
|
16
|
+
type OptionAccount,
|
|
17
|
+
type OptionPool,
|
|
18
|
+
type PoolLoan,
|
|
19
|
+
type PositionAccount,
|
|
20
|
+
type Vault,
|
|
21
|
+
type WriterPosition,
|
|
22
|
+
} from "../generated/accounts";
|
|
23
|
+
import type { Address } from "@solana/kit";
|
|
24
|
+
import { toAddress } from "../client/program";
|
|
25
|
+
import type { AddressLike, KitRpc } from "../client/types";
|
|
26
|
+
|
|
27
|
+
async function fetchRawAccount(
|
|
28
|
+
rpc: KitRpc,
|
|
29
|
+
address: AddressLike
|
|
30
|
+
): Promise<Uint8Array | null> {
|
|
31
|
+
const response = await rpc.getAccountInfo(toAddress(address), { encoding: "base64" }).send();
|
|
32
|
+
const accountInfo = response.value;
|
|
33
|
+
if (!accountInfo) return null;
|
|
34
|
+
const [data] = accountInfo.data;
|
|
35
|
+
const binary = atob(data);
|
|
36
|
+
const bytes = new Uint8Array(binary.length);
|
|
37
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
38
|
+
return bytes;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function decodeAccount<T>(
|
|
42
|
+
rpc: KitRpc,
|
|
43
|
+
address: AddressLike,
|
|
44
|
+
decoder: { decode: (value: Uint8Array) => T }
|
|
45
|
+
): Promise<T | null> {
|
|
46
|
+
const data = await fetchRawAccount(rpc, address);
|
|
47
|
+
if (!data) return null;
|
|
48
|
+
return decoder.decode(data);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export async function fetchOptionAccount(
|
|
52
|
+
rpc: KitRpc,
|
|
53
|
+
optionAccount: AddressLike
|
|
54
|
+
): Promise<OptionAccount | null> {
|
|
55
|
+
return decodeAccount(rpc, optionAccount, getOptionAccountDecoder());
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export async function fetchOptionPool(
|
|
59
|
+
rpc: KitRpc,
|
|
60
|
+
optionPool: AddressLike
|
|
61
|
+
): Promise<OptionPool | null> {
|
|
62
|
+
return decodeAccount(rpc, optionPool, getOptionPoolDecoder());
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function fetchCollateralPool(
|
|
66
|
+
rpc: KitRpc,
|
|
67
|
+
collateralPool: AddressLike
|
|
68
|
+
): Promise<CollateralPool | null> {
|
|
69
|
+
return decodeAccount(rpc, collateralPool, getCollateralPoolDecoder());
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export async function fetchWriterPosition(
|
|
73
|
+
rpc: KitRpc,
|
|
74
|
+
writerPosition: AddressLike
|
|
75
|
+
): Promise<WriterPosition | null> {
|
|
76
|
+
return decodeAccount(rpc, writerPosition, getWriterPositionDecoder());
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export async function fetchLenderPosition(
|
|
80
|
+
rpc: KitRpc,
|
|
81
|
+
lenderPosition: AddressLike
|
|
82
|
+
): Promise<LenderPosition | null> {
|
|
83
|
+
return decodeAccount(rpc, lenderPosition, getLenderPositionDecoder());
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export async function fetchBuyerPosition(
|
|
87
|
+
rpc: KitRpc,
|
|
88
|
+
buyerPosition: AddressLike
|
|
89
|
+
): Promise<PositionAccount | null> {
|
|
90
|
+
return decodeAccount(rpc, buyerPosition, getPositionAccountDecoder());
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export async function fetchVault(
|
|
94
|
+
rpc: KitRpc,
|
|
95
|
+
vault: AddressLike
|
|
96
|
+
): Promise<Vault | null> {
|
|
97
|
+
return decodeAccount(rpc, vault, getVaultDecoder());
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export async function fetchMarketDataAccount(
|
|
101
|
+
rpc: KitRpc,
|
|
102
|
+
marketData: AddressLike
|
|
103
|
+
): Promise<MarketDataAccount | null> {
|
|
104
|
+
return decodeAccount(rpc, marketData, getMarketDataAccountDecoder());
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export async function fetchMakerPoolShare(
|
|
108
|
+
rpc: KitRpc,
|
|
109
|
+
makerPoolShare: AddressLike
|
|
110
|
+
): Promise<MakerPoolShare | null> {
|
|
111
|
+
return decodeAccount(rpc, makerPoolShare, getMakerPoolShareDecoder());
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export async function fetchPoolLoan(
|
|
115
|
+
rpc: KitRpc,
|
|
116
|
+
poolLoan: AddressLike
|
|
117
|
+
): Promise<PoolLoan | null> {
|
|
118
|
+
return decodeAccount(rpc, poolLoan, getPoolLoanDecoder());
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export async function accountExists(
|
|
122
|
+
rpc: KitRpc,
|
|
123
|
+
address: AddressLike
|
|
124
|
+
): Promise<boolean> {
|
|
125
|
+
const response = await rpc.getAccountInfo(toAddress(address), { encoding: "base64" }).send();
|
|
126
|
+
return response.value !== null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export async function fetchManyAccounts(
|
|
130
|
+
rpc: KitRpc,
|
|
131
|
+
addresses: AddressLike[]
|
|
132
|
+
): Promise<Array<{ address: Address; exists: boolean }>> {
|
|
133
|
+
const keys = addresses.map((value) => toAddress(value));
|
|
134
|
+
const response = await rpc.getMultipleAccounts(keys, { encoding: "base64" }).send();
|
|
135
|
+
const infos = response.value;
|
|
136
|
+
return keys.map((key, index) => ({
|
|
137
|
+
address: key,
|
|
138
|
+
exists: infos[index] !== null,
|
|
139
|
+
}));
|
|
140
|
+
}
|
package/accounts/list.ts
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import bs58 from "bs58";
|
|
2
|
+
import type { Address } from "@solana/kit";
|
|
3
|
+
import {
|
|
4
|
+
MAKER_POOL_SHARE_DISCRIMINATOR,
|
|
5
|
+
OPTION_POOL_DISCRIMINATOR,
|
|
6
|
+
POOL_LOAN_DISCRIMINATOR,
|
|
7
|
+
POSITION_ACCOUNT_DISCRIMINATOR,
|
|
8
|
+
VAULT_DISCRIMINATOR,
|
|
9
|
+
WRITER_POSITION_DISCRIMINATOR,
|
|
10
|
+
getMakerPoolShareDecoder,
|
|
11
|
+
getOptionPoolDecoder,
|
|
12
|
+
getPoolLoanDecoder,
|
|
13
|
+
getPositionAccountDecoder,
|
|
14
|
+
getVaultDecoder,
|
|
15
|
+
getWriterPositionDecoder,
|
|
16
|
+
type MakerPoolShare,
|
|
17
|
+
type OptionPool,
|
|
18
|
+
type PoolLoan,
|
|
19
|
+
type PositionAccount,
|
|
20
|
+
type Vault,
|
|
21
|
+
type WriterPosition,
|
|
22
|
+
} from "../generated/accounts";
|
|
23
|
+
import { PROGRAM_ID, toAddress } from "../client/program";
|
|
24
|
+
import type { AddressLike, KitRpc } from "../client/types";
|
|
25
|
+
|
|
26
|
+
const DISCRIMINATOR_OFFSET = 0n;
|
|
27
|
+
const OWNER_OFFSET = 8n;
|
|
28
|
+
const ACTIVE_POOL_LOAN_STATUS = 1;
|
|
29
|
+
|
|
30
|
+
type ListedAccount<T> = {
|
|
31
|
+
address: Address;
|
|
32
|
+
data: T;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
type ProgramAccountResponse = {
|
|
36
|
+
pubkey: Address;
|
|
37
|
+
account: {
|
|
38
|
+
data: [string, string];
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
function decodeBase64Data(data: string): Uint8Array {
|
|
43
|
+
const binary = atob(data);
|
|
44
|
+
const bytes = new Uint8Array(binary.length);
|
|
45
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
46
|
+
return bytes;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function discriminatorFilter(discriminator: Uint8Array) {
|
|
50
|
+
return {
|
|
51
|
+
memcmp: {
|
|
52
|
+
offset: DISCRIMINATOR_OFFSET,
|
|
53
|
+
encoding: "base58",
|
|
54
|
+
bytes: bs58.encode(discriminator),
|
|
55
|
+
},
|
|
56
|
+
} as const;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function ownerFilter(owner: AddressLike) {
|
|
60
|
+
return {
|
|
61
|
+
memcmp: {
|
|
62
|
+
offset: OWNER_OFFSET,
|
|
63
|
+
encoding: "base58",
|
|
64
|
+
bytes: toAddress(owner),
|
|
65
|
+
},
|
|
66
|
+
} as const;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function fetchAndDecodeProgramAccounts<T>(
|
|
70
|
+
rpc: KitRpc,
|
|
71
|
+
decoder: { decode: (value: Uint8Array) => T },
|
|
72
|
+
filters: ReadonlyArray<unknown>
|
|
73
|
+
): Promise<Array<ListedAccount<T>>> {
|
|
74
|
+
const response = await rpc
|
|
75
|
+
.getProgramAccounts(PROGRAM_ID, {
|
|
76
|
+
encoding: "base64",
|
|
77
|
+
filters: filters as never,
|
|
78
|
+
})
|
|
79
|
+
.send();
|
|
80
|
+
|
|
81
|
+
const rawAccounts = Array.isArray(response)
|
|
82
|
+
? (response as Array<ProgramAccountResponse>)
|
|
83
|
+
: (response as { value: Array<ProgramAccountResponse> }).value;
|
|
84
|
+
|
|
85
|
+
return rawAccounts.map(({ pubkey, account }) => {
|
|
86
|
+
const [base64Data] = account.data;
|
|
87
|
+
return {
|
|
88
|
+
address: pubkey,
|
|
89
|
+
data: decoder.decode(decodeBase64Data(base64Data)),
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export async function fetchMakerPoolSharesByMaker(
|
|
95
|
+
rpc: KitRpc,
|
|
96
|
+
maker: AddressLike
|
|
97
|
+
): Promise<Array<ListedAccount<MakerPoolShare>>> {
|
|
98
|
+
return fetchAndDecodeProgramAccounts(rpc, getMakerPoolShareDecoder(), [
|
|
99
|
+
discriminatorFilter(MAKER_POOL_SHARE_DISCRIMINATOR),
|
|
100
|
+
ownerFilter(maker),
|
|
101
|
+
]);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export async function fetchWriterPositionsByWriter(
|
|
105
|
+
rpc: KitRpc,
|
|
106
|
+
writer: AddressLike
|
|
107
|
+
): Promise<Array<ListedAccount<WriterPosition>>> {
|
|
108
|
+
return fetchAndDecodeProgramAccounts(rpc, getWriterPositionDecoder(), [
|
|
109
|
+
discriminatorFilter(WRITER_POSITION_DISCRIMINATOR),
|
|
110
|
+
ownerFilter(writer),
|
|
111
|
+
]);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export async function fetchPositionAccountsByBuyer(
|
|
115
|
+
rpc: KitRpc,
|
|
116
|
+
buyer: AddressLike
|
|
117
|
+
): Promise<Array<ListedAccount<PositionAccount>>> {
|
|
118
|
+
return fetchAndDecodeProgramAccounts(rpc, getPositionAccountDecoder(), [
|
|
119
|
+
discriminatorFilter(POSITION_ACCOUNT_DISCRIMINATOR),
|
|
120
|
+
ownerFilter(buyer),
|
|
121
|
+
]);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export async function fetchPoolLoansByMaker(
|
|
125
|
+
rpc: KitRpc,
|
|
126
|
+
maker: AddressLike
|
|
127
|
+
): Promise<Array<ListedAccount<PoolLoan>>> {
|
|
128
|
+
const decoded = await fetchAndDecodeProgramAccounts(rpc, getPoolLoanDecoder(), [
|
|
129
|
+
discriminatorFilter(POOL_LOAN_DISCRIMINATOR),
|
|
130
|
+
ownerFilter(maker),
|
|
131
|
+
]);
|
|
132
|
+
return decoded.filter(
|
|
133
|
+
(item: { address: Address; data: PoolLoan }) =>
|
|
134
|
+
item.data.status === ACTIVE_POOL_LOAN_STATUS
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export async function fetchAllOptionPools(
|
|
139
|
+
rpc: KitRpc
|
|
140
|
+
): Promise<Array<ListedAccount<OptionPool>>> {
|
|
141
|
+
return fetchAndDecodeProgramAccounts(rpc, getOptionPoolDecoder(), [
|
|
142
|
+
discriminatorFilter(OPTION_POOL_DISCRIMINATOR),
|
|
143
|
+
]);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export async function fetchAllVaults(
|
|
147
|
+
rpc: KitRpc
|
|
148
|
+
): Promise<Array<ListedAccount<Vault>>> {
|
|
149
|
+
return fetchAndDecodeProgramAccounts(rpc, getVaultDecoder(), [
|
|
150
|
+
discriminatorFilter(VAULT_DISCRIMINATOR),
|
|
151
|
+
]);
|
|
152
|
+
}
|