@exponent-labs/generic-sy-sdk 0.9.21 → 0.9.22
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/package.json +9 -9
- package/src/index.ts +117 -15
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exponent-labs/generic-sy-sdk",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.22",
|
|
4
4
|
"main": "build/index.js",
|
|
5
5
|
"types": "build/index.d.ts",
|
|
6
6
|
"license": "AGPL-3.0",
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
"@coral-xyz/anchor": "^0.31.0",
|
|
13
13
|
"@solana/spl-stake-pool": "1.1.8",
|
|
14
14
|
"@solana/spl-token": "0.4.6",
|
|
15
|
-
"@exponent-labs/exponent-admin-pda": "0.9.
|
|
16
|
-
"@exponent-labs/exponent-fetcher": "0.9.
|
|
17
|
-
"@exponent-labs/exponent-tranching-idl": "0.9.
|
|
18
|
-
"@exponent-labs/exponent-types": "0.9.
|
|
19
|
-
"@exponent-labs/fragmetric-pda": "0.9.
|
|
20
|
-
"@exponent-labs/generic-sy-idl": "0.9.
|
|
21
|
-
"@exponent-labs/generic-sy-pda": "0.9.
|
|
22
|
-
"@exponent-labs/precise-number": "0.9.
|
|
15
|
+
"@exponent-labs/exponent-admin-pda": "0.9.22",
|
|
16
|
+
"@exponent-labs/exponent-fetcher": "0.9.22",
|
|
17
|
+
"@exponent-labs/exponent-tranching-idl": "0.9.22",
|
|
18
|
+
"@exponent-labs/exponent-types": "0.9.22",
|
|
19
|
+
"@exponent-labs/fragmetric-pda": "0.9.22",
|
|
20
|
+
"@exponent-labs/generic-sy-idl": "0.9.22",
|
|
21
|
+
"@exponent-labs/generic-sy-pda": "0.9.22",
|
|
22
|
+
"@exponent-labs/precise-number": "0.9.22"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"typescript": "5.4.5"
|
package/src/index.ts
CHANGED
|
@@ -47,6 +47,67 @@ import { fetchGlowVaultRate } from "./interfaces/glowVault"
|
|
|
47
47
|
import { SyInitializeConfig, SyTokenMetadata } from "./types"
|
|
48
48
|
import { MyWallet } from "./utils"
|
|
49
49
|
|
|
50
|
+
const GET_STATE_DISCRIMINATOR = Buffer.from([7])
|
|
51
|
+
|
|
52
|
+
async function fetchOnChainSyRate({
|
|
53
|
+
connection,
|
|
54
|
+
programId,
|
|
55
|
+
meta,
|
|
56
|
+
mintSy,
|
|
57
|
+
tokenSyEscrow,
|
|
58
|
+
remainingAccounts,
|
|
59
|
+
}: {
|
|
60
|
+
connection: web3.Connection
|
|
61
|
+
programId: web3.PublicKey
|
|
62
|
+
meta: web3.PublicKey
|
|
63
|
+
mintSy: web3.PublicKey
|
|
64
|
+
tokenSyEscrow: web3.PublicKey
|
|
65
|
+
remainingAccounts: web3.AccountMeta[]
|
|
66
|
+
}): Promise<number> {
|
|
67
|
+
const instruction = new web3.TransactionInstruction({
|
|
68
|
+
programId,
|
|
69
|
+
keys: [
|
|
70
|
+
{ pubkey: meta, isSigner: false, isWritable: true },
|
|
71
|
+
{ pubkey: mintSy, isSigner: false, isWritable: false },
|
|
72
|
+
{ pubkey: tokenSyEscrow, isSigner: false, isWritable: false },
|
|
73
|
+
...remainingAccounts,
|
|
74
|
+
],
|
|
75
|
+
data: GET_STATE_DISCRIMINATOR,
|
|
76
|
+
})
|
|
77
|
+
const [feePayer, { blockhash }] = await Promise.all([
|
|
78
|
+
connection.getSlotLeader("confirmed"),
|
|
79
|
+
connection.getLatestBlockhash("confirmed"),
|
|
80
|
+
])
|
|
81
|
+
const message = new web3.TransactionMessage({
|
|
82
|
+
payerKey: new web3.PublicKey(feePayer),
|
|
83
|
+
recentBlockhash: blockhash,
|
|
84
|
+
instructions: [instruction],
|
|
85
|
+
}).compileToV0Message()
|
|
86
|
+
const simulation = await connection.simulateTransaction(new web3.VersionedTransaction(message), {
|
|
87
|
+
commitment: "confirmed",
|
|
88
|
+
replaceRecentBlockhash: true,
|
|
89
|
+
sigVerify: false,
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
if (simulation.value.err) {
|
|
93
|
+
const logs = simulation.value.logs?.join("\n") ?? "No simulation logs"
|
|
94
|
+
throw new Error(`Generic Standard get_state simulation failed: ${JSON.stringify(simulation.value.err)}\n${logs}`)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const returnData = simulation.value.returnData
|
|
98
|
+
if (!returnData || returnData.programId !== programId.toBase58()) {
|
|
99
|
+
throw new Error("Generic Standard get_state returned invalid program data")
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const data = Buffer.from(returnData.data[0], "base64")
|
|
103
|
+
if (data.length < 32) {
|
|
104
|
+
throw new Error("Generic Standard get_state return data is too short")
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const exchangeRate = Array.from({ length: 4 }, (_, index) => new BN(data.subarray(index * 8, (index + 1) * 8), "le"))
|
|
108
|
+
return Number(PreciseNumber.fromRaw(exchangeRate).valueString)
|
|
109
|
+
}
|
|
110
|
+
|
|
50
111
|
/**
|
|
51
112
|
* Create a custom updateStakePoolBalance instruction using dynamic program ID
|
|
52
113
|
*/
|
|
@@ -126,6 +187,7 @@ export enum InterfaceType {
|
|
|
126
187
|
SolsticeGlamVault = 18,
|
|
127
188
|
ExponentTranching = 19,
|
|
128
189
|
GlowVault = 20,
|
|
190
|
+
LoopscaleVaultLp = 21,
|
|
129
191
|
}
|
|
130
192
|
|
|
131
193
|
export function getInterfaceTypeIndex(interfaceType: InterfaceTypeGeneric): InterfaceType {
|
|
@@ -150,6 +212,7 @@ export function getInterfaceTypeIndex(interfaceType: InterfaceTypeGeneric): Inte
|
|
|
150
212
|
if ("solsticeGlamVault" in interfaceType) return InterfaceType.SolsticeGlamVault
|
|
151
213
|
if ("exponentTranching" in interfaceType) return InterfaceType.ExponentTranching
|
|
152
214
|
if ("glowVault" in interfaceType) return InterfaceType.GlowVault
|
|
215
|
+
if ("loopscaleVaultLp" in interfaceType) return InterfaceType.LoopscaleVaultLp
|
|
153
216
|
|
|
154
217
|
throw new Error("Unsupported interface type")
|
|
155
218
|
}
|
|
@@ -218,6 +281,8 @@ export function getInterfaceTypeObj(
|
|
|
218
281
|
return { exponentTranching: {} }
|
|
219
282
|
case InterfaceType.GlowVault:
|
|
220
283
|
return { glowVault: { padding: [] } }
|
|
284
|
+
case InterfaceType.LoopscaleVaultLp:
|
|
285
|
+
return { loopscaleVaultLp: { padding: [] } }
|
|
221
286
|
default:
|
|
222
287
|
throw new Error(`Unsupported interface type: ${interfaceType}`)
|
|
223
288
|
}
|
|
@@ -281,6 +346,9 @@ export function getInterfaceTypeFromString(interfaceType: string): InterfaceType
|
|
|
281
346
|
return { exponentTranching: {} }
|
|
282
347
|
case "glow-vault":
|
|
283
348
|
return { glowVault: { padding: [] } }
|
|
349
|
+
case "loopscale-vault":
|
|
350
|
+
case "loopscale-vault-lp":
|
|
351
|
+
return { loopscaleVaultLp: { padding: [] } }
|
|
284
352
|
default:
|
|
285
353
|
throw new Error(`Unsupported interface type: ${interfaceType}`)
|
|
286
354
|
}
|
|
@@ -313,14 +381,22 @@ export class GenericSySdk {
|
|
|
313
381
|
this.syPda = new GenericSyPda(programId, interfaceIndex)
|
|
314
382
|
}
|
|
315
383
|
|
|
316
|
-
private static async calculateSyRate(
|
|
317
|
-
account
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
384
|
+
private static async calculateSyRate({
|
|
385
|
+
account,
|
|
386
|
+
cnx,
|
|
387
|
+
syMetaAddress,
|
|
388
|
+
genericStandardProgramId,
|
|
389
|
+
}: {
|
|
390
|
+
account: GenericSyMetaAccount
|
|
391
|
+
cnx: web3.Connection
|
|
392
|
+
syMetaAddress: web3.PublicKey
|
|
393
|
+
genericStandardProgramId: web3.PublicKey
|
|
394
|
+
}): Promise<{
|
|
321
395
|
syRate: number
|
|
322
396
|
additionalData?: AdditionalDataGeneric
|
|
323
397
|
}> {
|
|
398
|
+
const interfaceType = getGenericSyMetaInterfaceType(account)
|
|
399
|
+
|
|
324
400
|
if ("pyth" in interfaceType) {
|
|
325
401
|
const syRate = Number(PreciseNumber.fromRaw(account.index[0]).valueString)
|
|
326
402
|
return { syRate: syRate }
|
|
@@ -554,6 +630,28 @@ export class GenericSySdk {
|
|
|
554
630
|
expectedShareMint: account.yieldBearingMint,
|
|
555
631
|
})
|
|
556
632
|
return { syRate }
|
|
633
|
+
} else if ("loopscaleVaultLp" in interfaceType) {
|
|
634
|
+
if (account.interfaceAccounts.length !== 3) {
|
|
635
|
+
throw new Error("Loopscale Vault LP interface requires exactly three accounts")
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
const syRate = await fetchOnChainSyRate({
|
|
639
|
+
connection: cnx,
|
|
640
|
+
programId: genericStandardProgramId,
|
|
641
|
+
meta: syMetaAddress,
|
|
642
|
+
mintSy: account.mintSy,
|
|
643
|
+
tokenSyEscrow: account.tokenSyEscrow,
|
|
644
|
+
remainingAccounts: account.interfaceAccounts
|
|
645
|
+
.map((pubkey) => ({ pubkey, isSigner: false, isWritable: false }))
|
|
646
|
+
.concat(
|
|
647
|
+
account.emissions.map((emission) => ({
|
|
648
|
+
pubkey: emission.escrowAccount,
|
|
649
|
+
isSigner: false,
|
|
650
|
+
isWritable: false,
|
|
651
|
+
})),
|
|
652
|
+
),
|
|
653
|
+
})
|
|
654
|
+
return { syRate }
|
|
557
655
|
} else {
|
|
558
656
|
return { syRate: 1 }
|
|
559
657
|
}
|
|
@@ -581,11 +679,12 @@ export class GenericSySdk {
|
|
|
581
679
|
yieldBearingMint,
|
|
582
680
|
})
|
|
583
681
|
|
|
584
|
-
const { syRate, additionalData } = await GenericSySdk.calculateSyRate(
|
|
682
|
+
const { syRate, additionalData } = await GenericSySdk.calculateSyRate({
|
|
585
683
|
account,
|
|
586
|
-
getGenericSyMetaInterfaceType(account),
|
|
587
684
|
cnx,
|
|
588
|
-
|
|
685
|
+
syMetaAddress: selfAddress,
|
|
686
|
+
genericStandardProgramId,
|
|
687
|
+
})
|
|
589
688
|
|
|
590
689
|
const state: GenericSyState = {
|
|
591
690
|
selfAddress,
|
|
@@ -614,11 +713,12 @@ export class GenericSySdk {
|
|
|
614
713
|
const account = await fetcher.fetchGenericSyMeta(syMetaAddress)
|
|
615
714
|
const tokenProgramBase = (await cnx.getAccountInfo(account.yieldBearingMint))?.owner
|
|
616
715
|
|
|
617
|
-
const { syRate, additionalData } = await GenericSySdk.calculateSyRate(
|
|
716
|
+
const { syRate, additionalData } = await GenericSySdk.calculateSyRate({
|
|
618
717
|
account,
|
|
619
|
-
getGenericSyMetaInterfaceType(account),
|
|
620
718
|
cnx,
|
|
621
|
-
|
|
719
|
+
syMetaAddress,
|
|
720
|
+
genericStandardProgramId,
|
|
721
|
+
})
|
|
622
722
|
|
|
623
723
|
const state: GenericSyState = {
|
|
624
724
|
selfAddress: syMetaAddress,
|
|
@@ -633,14 +733,16 @@ export class GenericSySdk {
|
|
|
633
733
|
|
|
634
734
|
/** Reload the state of the account */
|
|
635
735
|
async reload(cnx: web3.Connection) {
|
|
636
|
-
const
|
|
736
|
+
const genericStandardProgramId = this.syPda.programId
|
|
737
|
+
const fetcher = new ExponentFetcher({ connection: cnx, genericStandardProgramId })
|
|
637
738
|
const account = await fetcher.fetchGenericSyMeta(this.state.selfAddress)
|
|
638
739
|
this.state.account = account
|
|
639
|
-
const { syRate, additionalData } = await GenericSySdk.calculateSyRate(
|
|
740
|
+
const { syRate, additionalData } = await GenericSySdk.calculateSyRate({
|
|
640
741
|
account,
|
|
641
|
-
getGenericSyMetaInterfaceType(account),
|
|
642
742
|
cnx,
|
|
643
|
-
|
|
743
|
+
syMetaAddress: this.state.selfAddress,
|
|
744
|
+
genericStandardProgramId,
|
|
745
|
+
})
|
|
644
746
|
this.state.syRate = syRate
|
|
645
747
|
this.state.additionalData = additionalData
|
|
646
748
|
}
|