@@ -32,6 +32,7 @@ export class SvmCpiEventsClient {
32
32
private programAddress : Address ;
33
33
private programEventAuthority : Address ;
34
34
private idl : Idl ;
35
+ private derivedAddress ?: Address ;
35
36
36
37
/**
37
38
* Private constructor. Use the async create() method to instantiate.
@@ -40,12 +41,14 @@ export class SvmCpiEventsClient {
40
41
rpc : web3 . Rpc < web3 . SolanaRpcApiFromTransport < RpcTransport > > ,
41
42
address : Address ,
42
43
eventAuthority : Address ,
43
- idl : Idl
44
+ idl : Idl ,
45
+ derivedAddress ?: Address
44
46
) {
45
47
this . rpc = rpc ;
46
48
this . programAddress = address ;
47
49
this . programEventAuthority = eventAuthority ;
48
50
this . idl = idl ;
51
+ this . derivedAddress = derivedAddress ;
49
52
}
50
53
51
54
/**
@@ -61,14 +64,16 @@ export class SvmCpiEventsClient {
61
64
public static async createFor (
62
65
rpc : web3 . Rpc < web3 . SolanaRpcApiFromTransport < RpcTransport > > ,
63
66
programId : string ,
64
- idl : Idl
67
+ idl : Idl ,
68
+ pda ?: string
65
69
) : Promise < SvmCpiEventsClient > {
66
70
const address = web3 . address ( programId ) ;
71
+ const derivedAddress = pda ? web3 . address ( pda ) : undefined ;
67
72
const [ eventAuthority ] = await web3 . getProgramDerivedAddress ( {
68
73
programAddress : address ,
69
74
seeds : [ "__event_authority" ] ,
70
75
} ) ;
71
- return new SvmCpiEventsClient ( rpc , address , eventAuthority , idl ) ;
76
+ return new SvmCpiEventsClient ( rpc , address , eventAuthority , idl , derivedAddress ) ;
72
77
}
73
78
74
79
/**
@@ -90,18 +95,39 @@ export class SvmCpiEventsClient {
90
95
return events . filter ( ( event ) => event . name === eventName ) as EventWithData [ ] ;
91
96
}
92
97
98
+ /**
99
+ * Queries events for the provided derived address at instantiation filtered by event name.
100
+ *
101
+ * @param eventName - The name of the event to filter by.
102
+ * @param fromBlock - Optional starting block.
103
+ * @param toBlock - Optional ending block.
104
+ * @param options - Options for fetching signatures.
105
+ * @returns A promise that resolves to an array of events matching the eventName.
106
+ */
107
+ public async queryDerivedAddressEvents (
108
+ eventName : string ,
109
+ fromBlock ?: bigint ,
110
+ toBlock ?: bigint ,
111
+ options : GetSignaturesForAddressConfig = { limit : 1000 , commitment : "confirmed" }
112
+ ) : Promise < EventWithData [ ] > {
113
+ const events = await this . queryAllEvents ( fromBlock , toBlock , options , true ) ;
114
+ return events . filter ( ( event ) => event . name === eventName ) as EventWithData [ ] ;
115
+ }
116
+
93
117
/**
94
118
* Queries all events for a specific program.
95
119
*
96
120
* @param fromBlock - Optional starting block.
97
121
* @param toBlock - Optional ending block.
98
122
* @param options - Options for fetching signatures.
123
+ * @param forDerivedAddress - Whether to query events for the program or the derived address.
99
124
* @returns A promise that resolves to an array of all events with additional metadata.
100
125
*/
101
126
private async queryAllEvents (
102
127
fromBlock ?: bigint ,
103
128
toBlock ?: bigint ,
104
- options : GetSignaturesForAddressConfig = { limit : 1000 , commitment : "confirmed" }
129
+ options : GetSignaturesForAddressConfig = { limit : 1000 , commitment : "confirmed" } ,
130
+ forDerivedAddress : boolean = false
105
131
) : Promise < EventWithData [ ] > {
106
132
const allSignatures : GetSignaturesForAddressTransaction [ ] = [ ] ;
107
133
let hasMoreSignatures = true ;
@@ -110,6 +136,11 @@ export class SvmCpiEventsClient {
110
136
let fromSlot : bigint | undefined ;
111
137
let toSlot : bigint | undefined ;
112
138
139
+ if ( forDerivedAddress && ! this . derivedAddress ) {
140
+ throw new Error ( "Unable to query PDA events. Derived address not set." ) ;
141
+ }
142
+ const addressToQuery = forDerivedAddress ? this . derivedAddress : this . programAddress ;
143
+
113
144
if ( fromBlock ) {
114
145
const slot = await getSlotForBlock ( this . rpc , fromBlock , BigInt ( 0 ) ) ;
115
146
fromSlot = slot ;
@@ -122,7 +153,7 @@ export class SvmCpiEventsClient {
122
153
123
154
while ( hasMoreSignatures ) {
124
155
const signatures : GetSignaturesForAddressApiResponse = await this . rpc
125
- . getSignaturesForAddress ( this . programAddress , currentOptions )
156
+ . getSignaturesForAddress ( addressToQuery ! , currentOptions )
126
157
. send ( ) ;
127
158
// Signatures are sorted by slot in descending order.
128
159
allSignatures . push ( ...signatures ) ;
0 commit comments