@epicentral/sos-sdk 0.10.0-beta → 0.10.2-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/accounts/fetchers.ts +79 -9
- package/accounts/list.ts +12 -6
- package/accounts/resolve-option.ts +60 -19
- package/generated/instructions/index.ts +1 -0
- package/generated/instructions/migrateCollateralPoolV1ToV2.ts +239 -0
- package/generated/programs/optionProgram.ts +24 -0
- package/package.json +1 -1
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
|
|
|
@@ -23,6 +23,7 @@ export * from "./initializeMarketData";
|
|
|
23
23
|
export * from "./initOptionPool";
|
|
24
24
|
export * from "./liquidateWriterPosition";
|
|
25
25
|
export * from "./liquidateWriterPositionRescue";
|
|
26
|
+
export * from "./migrateCollateralPoolV1ToV2";
|
|
26
27
|
export * from "./omlpCreateVault";
|
|
27
28
|
export * from "./omlpUpdateFeeWallet";
|
|
28
29
|
export * from "./omlpUpdateInterestModel";
|
|
@@ -0,0 +1,239 @@
|
|
|
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
|
+
getBytesDecoder,
|
|
14
|
+
getBytesEncoder,
|
|
15
|
+
getStructDecoder,
|
|
16
|
+
getStructEncoder,
|
|
17
|
+
transformEncoder,
|
|
18
|
+
type AccountMeta,
|
|
19
|
+
type AccountSignerMeta,
|
|
20
|
+
type Address,
|
|
21
|
+
type FixedSizeCodec,
|
|
22
|
+
type FixedSizeDecoder,
|
|
23
|
+
type FixedSizeEncoder,
|
|
24
|
+
type Instruction,
|
|
25
|
+
type InstructionWithAccounts,
|
|
26
|
+
type InstructionWithData,
|
|
27
|
+
type ReadonlyAccount,
|
|
28
|
+
type ReadonlyUint8Array,
|
|
29
|
+
type TransactionSigner,
|
|
30
|
+
type WritableAccount,
|
|
31
|
+
type WritableSignerAccount,
|
|
32
|
+
} from "@solana/kit";
|
|
33
|
+
import { OPTION_PROGRAM_PROGRAM_ADDRESS } from "../programs";
|
|
34
|
+
import { getAccountMetaFactory, type ResolvedAccount } from "../shared";
|
|
35
|
+
|
|
36
|
+
export const MIGRATE_COLLATERAL_POOL_V1_TO_V2_DISCRIMINATOR = new Uint8Array([
|
|
37
|
+
7, 151, 240, 114, 7, 75, 88, 10,
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
export function getMigrateCollateralPoolV1ToV2DiscriminatorBytes() {
|
|
41
|
+
return fixEncoderSize(getBytesEncoder(), 8).encode(
|
|
42
|
+
MIGRATE_COLLATERAL_POOL_V1_TO_V2_DISCRIMINATOR,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type MigrateCollateralPoolV1ToV2Instruction<
|
|
47
|
+
TProgram extends string = typeof OPTION_PROGRAM_PROGRAM_ADDRESS,
|
|
48
|
+
TAccountCollateralPool extends string | AccountMeta<string> = string,
|
|
49
|
+
TAccountOptionAccount extends string | AccountMeta<string> = string,
|
|
50
|
+
TAccountVault extends string | AccountMeta<string> = string,
|
|
51
|
+
TAccountKeeper extends string | AccountMeta<string> = string,
|
|
52
|
+
TAccountSystemProgram extends string | AccountMeta<string> =
|
|
53
|
+
"11111111111111111111111111111111",
|
|
54
|
+
TRemainingAccounts extends readonly AccountMeta<string>[] = [],
|
|
55
|
+
> = Instruction<TProgram> &
|
|
56
|
+
InstructionWithData<ReadonlyUint8Array> &
|
|
57
|
+
InstructionWithAccounts<
|
|
58
|
+
[
|
|
59
|
+
TAccountCollateralPool extends string
|
|
60
|
+
? WritableAccount<TAccountCollateralPool>
|
|
61
|
+
: TAccountCollateralPool,
|
|
62
|
+
TAccountOptionAccount extends string
|
|
63
|
+
? ReadonlyAccount<TAccountOptionAccount>
|
|
64
|
+
: TAccountOptionAccount,
|
|
65
|
+
TAccountVault extends string
|
|
66
|
+
? ReadonlyAccount<TAccountVault>
|
|
67
|
+
: TAccountVault,
|
|
68
|
+
TAccountKeeper extends string
|
|
69
|
+
? WritableSignerAccount<TAccountKeeper> &
|
|
70
|
+
AccountSignerMeta<TAccountKeeper>
|
|
71
|
+
: TAccountKeeper,
|
|
72
|
+
TAccountSystemProgram extends string
|
|
73
|
+
? ReadonlyAccount<TAccountSystemProgram>
|
|
74
|
+
: TAccountSystemProgram,
|
|
75
|
+
...TRemainingAccounts,
|
|
76
|
+
]
|
|
77
|
+
>;
|
|
78
|
+
|
|
79
|
+
export type MigrateCollateralPoolV1ToV2InstructionData = {
|
|
80
|
+
discriminator: ReadonlyUint8Array;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export type MigrateCollateralPoolV1ToV2InstructionDataArgs = {};
|
|
84
|
+
|
|
85
|
+
export function getMigrateCollateralPoolV1ToV2InstructionDataEncoder(): FixedSizeEncoder<MigrateCollateralPoolV1ToV2InstructionDataArgs> {
|
|
86
|
+
return transformEncoder(
|
|
87
|
+
getStructEncoder([["discriminator", fixEncoderSize(getBytesEncoder(), 8)]]),
|
|
88
|
+
(value) => ({
|
|
89
|
+
...value,
|
|
90
|
+
discriminator: MIGRATE_COLLATERAL_POOL_V1_TO_V2_DISCRIMINATOR,
|
|
91
|
+
}),
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function getMigrateCollateralPoolV1ToV2InstructionDataDecoder(): FixedSizeDecoder<MigrateCollateralPoolV1ToV2InstructionData> {
|
|
96
|
+
return getStructDecoder([
|
|
97
|
+
["discriminator", fixDecoderSize(getBytesDecoder(), 8)],
|
|
98
|
+
]);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function getMigrateCollateralPoolV1ToV2InstructionDataCodec(): FixedSizeCodec<
|
|
102
|
+
MigrateCollateralPoolV1ToV2InstructionDataArgs,
|
|
103
|
+
MigrateCollateralPoolV1ToV2InstructionData
|
|
104
|
+
> {
|
|
105
|
+
return combineCodec(
|
|
106
|
+
getMigrateCollateralPoolV1ToV2InstructionDataEncoder(),
|
|
107
|
+
getMigrateCollateralPoolV1ToV2InstructionDataDecoder(),
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export type MigrateCollateralPoolV1ToV2Input<
|
|
112
|
+
TAccountCollateralPool extends string = string,
|
|
113
|
+
TAccountOptionAccount extends string = string,
|
|
114
|
+
TAccountVault extends string = string,
|
|
115
|
+
TAccountKeeper extends string = string,
|
|
116
|
+
TAccountSystemProgram extends string = string,
|
|
117
|
+
> = {
|
|
118
|
+
collateralPool: Address<TAccountCollateralPool>;
|
|
119
|
+
optionAccount: Address<TAccountOptionAccount>;
|
|
120
|
+
vault: Address<TAccountVault>;
|
|
121
|
+
keeper: TransactionSigner<TAccountKeeper>;
|
|
122
|
+
systemProgram?: Address<TAccountSystemProgram>;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export function getMigrateCollateralPoolV1ToV2Instruction<
|
|
126
|
+
TAccountCollateralPool extends string,
|
|
127
|
+
TAccountOptionAccount extends string,
|
|
128
|
+
TAccountVault extends string,
|
|
129
|
+
TAccountKeeper extends string,
|
|
130
|
+
TAccountSystemProgram extends string,
|
|
131
|
+
TProgramAddress extends Address = typeof OPTION_PROGRAM_PROGRAM_ADDRESS,
|
|
132
|
+
>(
|
|
133
|
+
input: MigrateCollateralPoolV1ToV2Input<
|
|
134
|
+
TAccountCollateralPool,
|
|
135
|
+
TAccountOptionAccount,
|
|
136
|
+
TAccountVault,
|
|
137
|
+
TAccountKeeper,
|
|
138
|
+
TAccountSystemProgram
|
|
139
|
+
>,
|
|
140
|
+
config?: { programAddress?: TProgramAddress },
|
|
141
|
+
): MigrateCollateralPoolV1ToV2Instruction<
|
|
142
|
+
TProgramAddress,
|
|
143
|
+
TAccountCollateralPool,
|
|
144
|
+
TAccountOptionAccount,
|
|
145
|
+
TAccountVault,
|
|
146
|
+
TAccountKeeper,
|
|
147
|
+
TAccountSystemProgram
|
|
148
|
+
> {
|
|
149
|
+
// Program address.
|
|
150
|
+
const programAddress =
|
|
151
|
+
config?.programAddress ?? OPTION_PROGRAM_PROGRAM_ADDRESS;
|
|
152
|
+
|
|
153
|
+
// Original accounts.
|
|
154
|
+
const originalAccounts = {
|
|
155
|
+
collateralPool: { value: input.collateralPool ?? null, isWritable: true },
|
|
156
|
+
optionAccount: { value: input.optionAccount ?? null, isWritable: false },
|
|
157
|
+
vault: { value: input.vault ?? null, isWritable: false },
|
|
158
|
+
keeper: { value: input.keeper ?? null, isWritable: true },
|
|
159
|
+
systemProgram: { value: input.systemProgram ?? null, isWritable: false },
|
|
160
|
+
};
|
|
161
|
+
const accounts = originalAccounts as Record<
|
|
162
|
+
keyof typeof originalAccounts,
|
|
163
|
+
ResolvedAccount
|
|
164
|
+
>;
|
|
165
|
+
|
|
166
|
+
// Resolve default values.
|
|
167
|
+
if (!accounts.systemProgram.value) {
|
|
168
|
+
accounts.systemProgram.value =
|
|
169
|
+
"11111111111111111111111111111111" as Address<"11111111111111111111111111111111">;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const getAccountMeta = getAccountMetaFactory(programAddress, "programId");
|
|
173
|
+
return Object.freeze({
|
|
174
|
+
accounts: [
|
|
175
|
+
getAccountMeta(accounts.collateralPool),
|
|
176
|
+
getAccountMeta(accounts.optionAccount),
|
|
177
|
+
getAccountMeta(accounts.vault),
|
|
178
|
+
getAccountMeta(accounts.keeper),
|
|
179
|
+
getAccountMeta(accounts.systemProgram),
|
|
180
|
+
],
|
|
181
|
+
data: getMigrateCollateralPoolV1ToV2InstructionDataEncoder().encode({}),
|
|
182
|
+
programAddress,
|
|
183
|
+
} as MigrateCollateralPoolV1ToV2Instruction<
|
|
184
|
+
TProgramAddress,
|
|
185
|
+
TAccountCollateralPool,
|
|
186
|
+
TAccountOptionAccount,
|
|
187
|
+
TAccountVault,
|
|
188
|
+
TAccountKeeper,
|
|
189
|
+
TAccountSystemProgram
|
|
190
|
+
>);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export type ParsedMigrateCollateralPoolV1ToV2Instruction<
|
|
194
|
+
TProgram extends string = typeof OPTION_PROGRAM_PROGRAM_ADDRESS,
|
|
195
|
+
TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[],
|
|
196
|
+
> = {
|
|
197
|
+
programAddress: Address<TProgram>;
|
|
198
|
+
accounts: {
|
|
199
|
+
collateralPool: TAccountMetas[0];
|
|
200
|
+
optionAccount: TAccountMetas[1];
|
|
201
|
+
vault: TAccountMetas[2];
|
|
202
|
+
keeper: TAccountMetas[3];
|
|
203
|
+
systemProgram: TAccountMetas[4];
|
|
204
|
+
};
|
|
205
|
+
data: MigrateCollateralPoolV1ToV2InstructionData;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export function parseMigrateCollateralPoolV1ToV2Instruction<
|
|
209
|
+
TProgram extends string,
|
|
210
|
+
TAccountMetas extends readonly AccountMeta[],
|
|
211
|
+
>(
|
|
212
|
+
instruction: Instruction<TProgram> &
|
|
213
|
+
InstructionWithAccounts<TAccountMetas> &
|
|
214
|
+
InstructionWithData<ReadonlyUint8Array>,
|
|
215
|
+
): ParsedMigrateCollateralPoolV1ToV2Instruction<TProgram, TAccountMetas> {
|
|
216
|
+
if (instruction.accounts.length < 5) {
|
|
217
|
+
// TODO: Coded error.
|
|
218
|
+
throw new Error("Not enough accounts");
|
|
219
|
+
}
|
|
220
|
+
let accountIndex = 0;
|
|
221
|
+
const getNextAccount = () => {
|
|
222
|
+
const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!;
|
|
223
|
+
accountIndex += 1;
|
|
224
|
+
return accountMeta;
|
|
225
|
+
};
|
|
226
|
+
return {
|
|
227
|
+
programAddress: instruction.programAddress,
|
|
228
|
+
accounts: {
|
|
229
|
+
collateralPool: getNextAccount(),
|
|
230
|
+
optionAccount: getNextAccount(),
|
|
231
|
+
vault: getNextAccount(),
|
|
232
|
+
keeper: getNextAccount(),
|
|
233
|
+
systemProgram: getNextAccount(),
|
|
234
|
+
},
|
|
235
|
+
data: getMigrateCollateralPoolV1ToV2InstructionDataDecoder().decode(
|
|
236
|
+
instruction.data,
|
|
237
|
+
),
|
|
238
|
+
};
|
|
239
|
+
}
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
parseInitOptionPoolInstruction,
|
|
35
35
|
parseLiquidateWriterPositionInstruction,
|
|
36
36
|
parseLiquidateWriterPositionRescueInstruction,
|
|
37
|
+
parseMigrateCollateralPoolV1ToV2Instruction,
|
|
37
38
|
parseOmlpCreateVaultInstruction,
|
|
38
39
|
parseOmlpUpdateFeeWalletInstruction,
|
|
39
40
|
parseOmlpUpdateInterestModelInstruction,
|
|
@@ -74,6 +75,7 @@ import {
|
|
|
74
75
|
type ParsedInitOptionPoolInstruction,
|
|
75
76
|
type ParsedLiquidateWriterPositionInstruction,
|
|
76
77
|
type ParsedLiquidateWriterPositionRescueInstruction,
|
|
78
|
+
type ParsedMigrateCollateralPoolV1ToV2Instruction,
|
|
77
79
|
type ParsedOmlpCreateVaultInstruction,
|
|
78
80
|
type ParsedOmlpUpdateFeeWalletInstruction,
|
|
79
81
|
type ParsedOmlpUpdateInterestModelInstruction,
|
|
@@ -276,6 +278,7 @@ export enum OptionProgramInstruction {
|
|
|
276
278
|
InitializeMarketData,
|
|
277
279
|
LiquidateWriterPosition,
|
|
278
280
|
LiquidateWriterPositionRescue,
|
|
281
|
+
MigrateCollateralPoolV1ToV2,
|
|
279
282
|
OmlpCreateVault,
|
|
280
283
|
OmlpUpdateFeeWallet,
|
|
281
284
|
OmlpUpdateInterestModel,
|
|
@@ -492,6 +495,17 @@ export function identifyOptionProgramInstruction(
|
|
|
492
495
|
) {
|
|
493
496
|
return OptionProgramInstruction.LiquidateWriterPositionRescue;
|
|
494
497
|
}
|
|
498
|
+
if (
|
|
499
|
+
containsBytes(
|
|
500
|
+
data,
|
|
501
|
+
fixEncoderSize(getBytesEncoder(), 8).encode(
|
|
502
|
+
new Uint8Array([7, 151, 240, 114, 7, 75, 88, 10]),
|
|
503
|
+
),
|
|
504
|
+
0,
|
|
505
|
+
)
|
|
506
|
+
) {
|
|
507
|
+
return OptionProgramInstruction.MigrateCollateralPoolV1ToV2;
|
|
508
|
+
}
|
|
495
509
|
if (
|
|
496
510
|
containsBytes(
|
|
497
511
|
data,
|
|
@@ -804,6 +818,9 @@ export type ParsedOptionProgramInstruction<
|
|
|
804
818
|
| ({
|
|
805
819
|
instructionType: OptionProgramInstruction.LiquidateWriterPositionRescue;
|
|
806
820
|
} & ParsedLiquidateWriterPositionRescueInstruction<TProgram>)
|
|
821
|
+
| ({
|
|
822
|
+
instructionType: OptionProgramInstruction.MigrateCollateralPoolV1ToV2;
|
|
823
|
+
} & ParsedMigrateCollateralPoolV1ToV2Instruction<TProgram>)
|
|
807
824
|
| ({
|
|
808
825
|
instructionType: OptionProgramInstruction.OmlpCreateVault;
|
|
809
826
|
} & ParsedOmlpCreateVaultInstruction<TProgram>)
|
|
@@ -998,6 +1015,13 @@ export function parseOptionProgramInstruction<TProgram extends string>(
|
|
|
998
1015
|
...parseLiquidateWriterPositionRescueInstruction(instruction),
|
|
999
1016
|
};
|
|
1000
1017
|
}
|
|
1018
|
+
case OptionProgramInstruction.MigrateCollateralPoolV1ToV2: {
|
|
1019
|
+
assertIsInstructionWithAccounts(instruction);
|
|
1020
|
+
return {
|
|
1021
|
+
instructionType: OptionProgramInstruction.MigrateCollateralPoolV1ToV2,
|
|
1022
|
+
...parseMigrateCollateralPoolV1ToV2Instruction(instruction),
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1001
1025
|
case OptionProgramInstruction.OmlpCreateVault: {
|
|
1002
1026
|
assertIsInstructionWithAccounts(instruction);
|
|
1003
1027
|
return {
|
package/package.json
CHANGED