@@ -12,6 +12,8 @@ import {
12
12
createTransferInstruction ,
13
13
getAccount ,
14
14
getAssociatedTokenAddress ,
15
+ getMint ,
16
+ type Mint ,
15
17
} from "@solana/spl-token" ;
16
18
import type { AnchorWallet } from "@solana/wallet-adapter-react" ;
17
19
import {
@@ -22,7 +24,12 @@ import {
22
24
TransactionInstruction ,
23
25
} from "@solana/web3.js" ;
24
26
25
- import { GOVERNANCE_ADDRESS , POSITIONS_ACCOUNT_SIZE } from "./constants" ;
27
+ import {
28
+ FRACTION_PRECISION_N ,
29
+ GOVERNANCE_ADDRESS ,
30
+ ONE_YEAR_IN_SECONDS ,
31
+ POSITIONS_ACCOUNT_SIZE ,
32
+ } from "./constants" ;
26
33
import {
27
34
getConfigAddress ,
28
35
getDelegationRecordAddress ,
@@ -36,6 +43,7 @@ import {
36
43
type PoolConfig ,
37
44
type PoolDataAccount ,
38
45
type StakeAccountPositions ,
46
+ type VestingSchedule ,
39
47
} from "./types" ;
40
48
import { convertBigIntToBN , convertBNToBigInt } from "./utils/bn" ;
41
49
import { epochToDate , getCurrentEpoch } from "./utils/clock" ;
@@ -56,7 +64,7 @@ import type { Staking } from "../types/staking";
56
64
57
65
export type PythStakingClientConfig = {
58
66
connection : Connection ;
59
- wallet : AnchorWallet | undefined ;
67
+ wallet ? : AnchorWallet ;
60
68
} ;
61
69
62
70
export class PythStakingClient {
@@ -105,7 +113,9 @@ export class PythStakingClient {
105
113
}
106
114
107
115
/** Gets a users stake accounts */
108
- public async getAllStakeAccountPositions ( ) : Promise < PublicKey [ ] > {
116
+ public async getAllStakeAccountPositions (
117
+ owner ?: PublicKey ,
118
+ ) : Promise < PublicKey [ ] > {
109
119
const positionDataMemcmp = this . stakingProgram . coder . accounts . memcmp (
110
120
"positionData" ,
111
121
) as {
@@ -124,7 +134,7 @@ export class PythStakingClient {
124
134
{
125
135
memcmp : {
126
136
offset : 8 ,
127
- bytes : this . wallet . publicKey . toBase58 ( ) ,
137
+ bytes : owner ?. toBase58 ( ) ?? this . wallet . publicKey . toBase58 ( ) ,
128
138
} ,
129
139
} ,
130
140
] ,
@@ -529,7 +539,10 @@ export class PythStakingClient {
529
539
return sendTransaction ( [ instruction ] , this . connection , this . wallet ) ;
530
540
}
531
541
532
- public async getUnlockSchedule ( stakeAccountPositions : PublicKey ) {
542
+ public async getUnlockSchedule (
543
+ stakeAccountPositions : PublicKey ,
544
+ includePastPeriods = false ,
545
+ ) {
533
546
const stakeAccountMetadataAddress = getStakeAccountMetadataAddress (
534
547
stakeAccountPositions ,
535
548
) ;
@@ -548,7 +561,38 @@ export class PythStakingClient {
548
561
return getUnlockSchedule ( {
549
562
vestingSchedule,
550
563
pythTokenListTime : config . pythTokenListTime ,
564
+ includePastPeriods,
565
+ } ) ;
566
+ }
567
+
568
+ public async getCirculatingSupply ( ) {
569
+ const vestingSchedule : VestingSchedule = {
570
+ periodicVestingAfterListing : {
571
+ initialBalance : 8_500_000_000n * FRACTION_PRECISION_N ,
572
+ numPeriods : 4n ,
573
+ periodDuration : ONE_YEAR_IN_SECONDS ,
574
+ } ,
575
+ } ;
576
+
577
+ const config = await this . getGlobalConfig ( ) ;
578
+
579
+ if ( config . pythTokenListTime === null ) {
580
+ throw new Error ( "Pyth token list time not set in global config" ) ;
581
+ }
582
+
583
+ const unlockSchedule = getUnlockSchedule ( {
584
+ vestingSchedule,
585
+ pythTokenListTime : config . pythTokenListTime ,
586
+ includePastPeriods : false ,
551
587
} ) ;
588
+
589
+ const totalLocked = unlockSchedule . schedule . reduce (
590
+ ( total , unlock ) => total + unlock . amount ,
591
+ 0n ,
592
+ ) ;
593
+
594
+ const mint = await this . getPythTokenMint ( ) ;
595
+ return mint . supply - totalLocked ;
552
596
}
553
597
554
598
async getAdvanceDelegationRecordInstructions (
@@ -705,4 +749,9 @@ export class PythStakingClient {
705
749
undefined ,
706
750
) ;
707
751
}
752
+
753
+ public async getPythTokenMint ( ) : Promise < Mint > {
754
+ const globalConfig = await this . getGlobalConfig ( ) ;
755
+ return getMint ( this . connection , globalConfig . pythTokenMint ) ;
756
+ }
708
757
}
0 commit comments