solotto 1.0.7 → 1.0.8

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.
Files changed (4) hide show
  1. package/README.md +70 -70
  2. package/package.json +1 -1
  3. package/solotto.d.ts +44 -44
  4. package/solotto.js +143 -144
package/README.md CHANGED
@@ -19,11 +19,11 @@ A JavaScript SDK for interacting with the Solotto on-chain lottery program on So
19
19
  - [RandomDraw](#randomdraw)
20
20
  - [LockLottery](#locklottery)
21
21
  - [ClaimExpired](#claimexpired)
22
- - [Boost](#boost)
23
- - [GetBoosters](#getboosters)
24
22
  - [Lottery](#lottery-api)
25
23
  - [BuyTickets](#buytickets)
26
24
  - [ClaimTicket](#claimticket)
25
+ - [Boost](#boost)
26
+ - [GetBoosters](#getboosters)
27
27
  - [GetLottery](#getlottery)
28
28
  - [GetTicket](#getticket)
29
29
  - [GetTickets](#gettickets)
@@ -72,8 +72,8 @@ Solotto is organized into three exported classes, each handling a different laye
72
72
 
73
73
  | Class | Role |
74
74
  |---|---|
75
- | **`LotteryManager`** | Admin operations — initialize lotteries, trigger draws, lock/unlock ticket sales. |
76
- | **`Lottery`** | Player & read operations — buy tickets, claim prizes, query lottery/ticket state, watch draws via WebSocket. |
75
+ | **`LotteryManager`** | Admin operations — initialize lotteries, trigger draws, lock/unlock ticket sales, reclaim expired prizes. |
76
+ | **`Lottery`** | Player & read operations — buy tickets, claim prizes, boost prize pools, query lottery/ticket/booster state, watch draws via WebSocket. |
77
77
  | **`LotteryNetwork`** | Low-level transaction utilities — build, simulate, send, and confirm transactions with automatic compute budget and priority fee estimation. |
78
78
 
79
79
  ---
@@ -219,16 +219,77 @@ const result = await manager.ClaimExpired(authority, lotteryId, encoded);
219
219
 
220
220
  ---
221
221
 
222
+ ### Lottery API
223
+
224
+ #### BuyTickets
225
+
226
+ Purchases one or more tickets for a lottery. Supports buying up to 4 tickets in a single transaction.
227
+
228
+ ```js
229
+ const lottery = new Lottery(connection, false, programId);
230
+
231
+ const result = await lottery.BuyTickets(buyer, authority, lotteryId, amount, encoded);
232
+ ```
233
+
234
+ | Parameter | Type | Default | Description |
235
+ |---|---|---|---|
236
+ | `buyer` | `Keypair` | — | The keypair of the ticket buyer. |
237
+ | `authority` | `Keypair \| {publicKey}` | — | The lottery authority (only `publicKey` is needed). |
238
+ | `lotteryId` | `Number` | — | The lottery ID to buy tickets for. |
239
+ | `amount` | `Number` | `1` | Number of tickets to purchase (1–4). |
240
+ | `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
241
+
242
+ **Returns:** `"finalized"` on success, `"Lottery is not active, no tickets can be sold"` if the lottery is inactive, or the transaction object when encoded.
243
+
244
+ **Example:**
245
+
246
+ ```js
247
+ import { Connection, PublicKey, Keypair } from "@solana/web3.js";
248
+ import { Lottery } from "solotto";
249
+
250
+ const connection = new Connection("https://api.mainnet-beta.solana.com");
251
+ const programId = new PublicKey("YOUR_PROGRAM_ID");
252
+ const lottery = new Lottery(connection, false, programId);
253
+
254
+ const buyer = Keypair.generate();
255
+ const authority = { publicKey: new PublicKey("LOTTERY_AUTHORITY_PUBKEY") };
256
+
257
+ // Buy 2 tickets for lottery #1
258
+ const result = await lottery.BuyTickets(buyer, authority, 1, 2);
259
+ console.log(result); // "finalized"
260
+ ```
261
+
262
+ ---
263
+
264
+ #### ClaimTicket
265
+
266
+ Claims the prize for the winning ticket. Must be called by the ticket owner.
267
+
268
+ ```js
269
+ const result = await lottery.ClaimTicket(authority, lotteryId, winner, encoded);
270
+ ```
271
+
272
+ | Parameter | Type | Default | Description |
273
+ |---|---|---|---|
274
+ | `authority` | `{publicKey}` | — | The lottery authority (only `publicKey` is needed). |
275
+ | `lotteryId` | `Number` | — | The lottery ID. |
276
+ | `winner` | `Keypair` | — | The keypair of the winning ticket's owner. |
277
+ | `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
278
+
279
+ **Returns:** `"finalized"` on success, the simulation log array (`string[]`) if the transaction fails simulation, or the transaction object when encoded.
280
+
281
+ ---
282
+
222
283
  #### Boost
223
284
 
224
285
  Boosts a lottery's prize pool by transferring SOL from any wallet. Can be called by anyone, not just the authority. Optionally attaches a memo message to the transaction.
225
286
 
226
287
  ```js
227
288
  // Boost lottery #1 with 0.5 SOL
228
- const result = await manager.Boost(authority, lotteryId, booster, 0.5);
289
+ const result = await lottery.Boost(authority, lotteryId, booster, 0.5);
229
290
 
230
291
  // Boost with a memo message
231
- const result = await manager.Boost(authority, lotteryId, booster, 1.0, "Good luck everyone!");
292
+ const result = await lottery.Boost(authority, lotteryId, booster, 1.0, "Good luck everyone!");
232
293
  ```
233
294
 
234
295
  | Parameter | Type | Default | Description |
@@ -252,13 +313,13 @@ Retrieves boost history by scanning on-chain program logs for boost transactions
252
313
 
253
314
  ```js
254
315
  // Get all boosters for a specific lottery
255
- const boosters = await manager.GetBoosters(authority, lotteryId);
316
+ const boosters = await lottery.GetBoosters(authority, lotteryId);
256
317
 
257
318
  // Get all boosters across all lotteries (up to 500 transactions)
258
- const allBoosters = await manager.GetBoosters(false, false, false, 500);
319
+ const allBoosters = await lottery.GetBoosters(false, false, false, 500);
259
320
 
260
321
  // Get boosters grouped by wallet address
261
- const grouped = await manager.GetBoosters(authority, lotteryId, true);
322
+ const grouped = await lottery.GetBoosters(authority, lotteryId, true);
262
323
  ```
263
324
 
264
325
  | Parameter | Type | Default | Description |
@@ -302,67 +363,6 @@ const grouped = await manager.GetBoosters(authority, lotteryId, true);
302
363
 
303
364
  ---
304
365
 
305
- ### Lottery API
306
-
307
- #### BuyTickets
308
-
309
- Purchases one or more tickets for a lottery. Supports buying up to 4 tickets in a single transaction.
310
-
311
- ```js
312
- const lottery = new Lottery(connection, false, programId);
313
-
314
- const result = await lottery.BuyTickets(buyer, authority, lotteryId, amount, encoded);
315
- ```
316
-
317
- | Parameter | Type | Default | Description |
318
- |---|---|---|---|
319
- | `buyer` | `Keypair` | — | The keypair of the ticket buyer. |
320
- | `authority` | `Keypair \| {publicKey}` | — | The lottery authority (only `publicKey` is needed). |
321
- | `lotteryId` | `Number` | — | The lottery ID to buy tickets for. |
322
- | `amount` | `Number` | `1` | Number of tickets to purchase (1–4). |
323
- | `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
324
-
325
- **Returns:** `"finalized"` on success, `"Lottery is not active, no tickets can be sold"` if the lottery is inactive, or the transaction object when encoded.
326
-
327
- **Example:**
328
-
329
- ```js
330
- import { Connection, PublicKey, Keypair } from "@solana/web3.js";
331
- import { Lottery } from "solotto";
332
-
333
- const connection = new Connection("https://api.mainnet-beta.solana.com");
334
- const programId = new PublicKey("YOUR_PROGRAM_ID");
335
- const lottery = new Lottery(connection, false, programId);
336
-
337
- const buyer = Keypair.generate();
338
- const authority = { publicKey: new PublicKey("LOTTERY_AUTHORITY_PUBKEY") };
339
-
340
- // Buy 2 tickets for lottery #1
341
- const result = await lottery.BuyTickets(buyer, authority, 1, 2);
342
- console.log(result); // "finalized"
343
- ```
344
-
345
- ---
346
-
347
- #### ClaimTicket
348
-
349
- Claims the prize for the winning ticket. Must be called by the ticket owner.
350
-
351
- ```js
352
- const result = await lottery.ClaimTicket(authority, lotteryId, winner, encoded);
353
- ```
354
-
355
- | Parameter | Type | Default | Description |
356
- |---|---|---|---|
357
- | `authority` | `{publicKey}` | — | The lottery authority (only `publicKey` is needed). |
358
- | `lotteryId` | `Number` | — | The lottery ID. |
359
- | `winner` | `Keypair` | — | The keypair of the winning ticket's owner. |
360
- | `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
361
-
362
- **Returns:** `"finalized"` on success, the simulation log array (`string[]`) if the transaction fails simulation, or the transaction object when encoded.
363
-
364
- ---
365
-
366
366
  #### GetLottery
367
367
 
368
368
  Fetches the full on-chain state of a lottery.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solotto",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Solana lottery client",
5
5
  "type": "module",
6
6
  "types": "./solotto.d.ts",
package/solotto.d.ts CHANGED
@@ -290,6 +290,50 @@ declare module "solotto" {
290
290
  buyer?: HasPublicKey | false
291
291
  ): Promise<TicketListResult>;
292
292
 
293
+ /**
294
+ * Boost a lottery's prize pool by transferring SOL from any wallet.
295
+ * @param authority - The lottery authority (only `publicKey` needed).
296
+ * @param lotteryId - Lottery numeric identifier.
297
+ * @param booster - The keypair of the wallet sending the boost.
298
+ * @param amount - Amount of SOL to boost (e.g. `0.5` for 0.5 SOL).
299
+ * @param message - Optional memo string attached to the transaction.
300
+ * @param encoded - If `true`, return a base64-encoded transaction.
301
+ */
302
+ Boost(
303
+ authority: HasPublicKey,
304
+ lotteryId: number,
305
+ booster: Keypair,
306
+ amount: number,
307
+ message?: string | false,
308
+ encoded?: boolean
309
+ ): Promise<string | TxResult | undefined>;
310
+
311
+ /**
312
+ * Retrieve boost history from on-chain program logs.
313
+ * @param authority - Filter by lottery authority, or `false` for all.
314
+ * @param lotteryId - Filter by lottery ID, or `false` for all.
315
+ * @param group - If `true`, group results by booster wallet address.
316
+ * @param limit - Maximum number of recent transactions to scan (max 1000).
317
+ */
318
+ GetBoosters(
319
+ authority?: HasPublicKey | false,
320
+ lotteryId?: number | false,
321
+ group?: false,
322
+ limit?: number
323
+ ): Promise<BoosterRecord[]>;
324
+ GetBoosters(
325
+ authority: HasPublicKey | false,
326
+ lotteryId: number | false,
327
+ group: true,
328
+ limit?: number
329
+ ): Promise<GroupedBoostersResult>;
330
+ GetBoosters(
331
+ authority?: HasPublicKey | false,
332
+ lotteryId?: number | false,
333
+ group?: boolean,
334
+ limit?: number
335
+ ): Promise<BoosterRecord[] | GroupedBoostersResult>;
336
+
293
337
  /** Derive the lottery PDA. */
294
338
  DeriveLotteryPDA(
295
339
  authority: PublicKey,
@@ -367,49 +411,5 @@ declare module "solotto" {
367
411
  lotteryId: number,
368
412
  encoded?: boolean
369
413
  ): Promise<LotteryState | string | TxResult | undefined>;
370
-
371
- /**
372
- * Boost a lottery's prize pool by transferring SOL from any wallet.
373
- * @param authority - The lottery authority (only `publicKey` needed).
374
- * @param lotteryId - Lottery numeric identifier.
375
- * @param booster - The keypair of the wallet sending the boost.
376
- * @param amount - Amount of SOL to boost (e.g. `0.5` for 0.5 SOL).
377
- * @param message - Optional memo string attached to the transaction.
378
- * @param encoded - If `true`, return a base64-encoded transaction.
379
- */
380
- Boost(
381
- authority: HasPublicKey,
382
- lotteryId: number,
383
- booster: Keypair,
384
- amount: number,
385
- message?: string | false,
386
- encoded?: boolean
387
- ): Promise<string | TxResult | undefined>;
388
-
389
- /**
390
- * Retrieve boost history from on-chain transaction memos.
391
- * @param authority - Filter by lottery authority, or `false` for all.
392
- * @param lotteryId - Filter by lottery ID, or `false` for all.
393
- * @param group - If `true`, group results by booster wallet address.
394
- * @param limit - Maximum number of recent transactions to scan (max 1000).
395
- */
396
- GetBoosters(
397
- authority?: HasPublicKey | false,
398
- lotteryId?: number | false,
399
- group?: false,
400
- limit?: number
401
- ): Promise<BoosterRecord[]>;
402
- GetBoosters(
403
- authority: HasPublicKey | false,
404
- lotteryId: number | false,
405
- group: true,
406
- limit?: number
407
- ): Promise<GroupedBoostersResult>;
408
- GetBoosters(
409
- authority?: HasPublicKey | false,
410
- lotteryId?: number | false,
411
- group?: boolean,
412
- limit?: number
413
- ): Promise<BoosterRecord[] | GroupedBoostersResult>;
414
414
  }
415
415
  }
package/solotto.js CHANGED
@@ -574,6 +574,149 @@ class Lottery extends EventEmitter {
574
574
  return PublicKey.findProgramAddressSync([Buffer.from("prize-pool")], this.program);
575
575
  }
576
576
 
577
+ /**
578
+ * @param {Keypair} authority - Keypair
579
+ * @param {String} lotteryId - The lottery id
580
+ * @param {Keypair} booster - The booster's keypair
581
+ * @param {Number} amount - The amount of sol to boost
582
+ * @param {Boolean} encoded - true returns encoded transaction
583
+ */
584
+ async Boost(authority, lotteryId, booster, amount, message = false, encoded = false) {
585
+ try{
586
+ async function boostData(lotId, amount) {
587
+ const lamports = parseInt(amount * LAMPORTS_PER_SOL);
588
+ const buffer = Buffer.alloc(17); // 1 byte discriminator + 1 bytes price + 8 bytes id
589
+ buffer.writeUInt8(INSTRUCTIONS.BOOST_LOTTERY, 0); // boostLottery discriminator
590
+ buffer.writeBigUInt64LE(BigInt(lotId), 1);
591
+ buffer.writeBigUInt64LE(BigInt(lamports), 9);
592
+ return buffer;
593
+ }
594
+ if(message){message = ":booster:"+message;}
595
+ const network = new LotteryNetwork(this.connection);
596
+ const [lotteryPDA] = await this.DeriveLotteryPDA(authority.publicKey, lotteryId);
597
+ const LOTTO = await this.GetLottery(authority, lotteryId);
598
+ const keys = [
599
+ { pubkey: booster.publicKey, isSigner: true, isWritable: true },
600
+ { pubkey: lotteryPDA, isSigner: false, isWritable: true },
601
+ { pubkey: new PublicKey(LOTTO.prizePoolAddress), isSigner: false, isWritable: true },
602
+ { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
603
+ ];
604
+ const ix = new TransactionInstruction(
605
+ {programId: this.program, keys, data: await boostData(lotteryId, amount)}
606
+ );
607
+ const _tx_ = {};
608
+ _tx_.account = booster.publicKey.toString(); // string : required
609
+ _tx_.instructions = [ix]; // array : required
610
+ _tx_.signers = false; // array : default false
611
+ _tx_.table = false; // array : default false
612
+ _tx_.tolerance = 1.2; // int : default 1.1
613
+ _tx_.compute = true; // bool : default true
614
+ _tx_.fees = true; // bool : default true
615
+ _tx_.priority = "Low"; // string : default Low
616
+ _tx_.memo = message;
617
+ if(encoded){
618
+ _tx_.serialize = true;
619
+ _tx_.encode = true;
620
+ }
621
+ else{
622
+ _tx_.serialize = false;
623
+ _tx_.encode = false;
624
+ }
625
+ const tx = await network.Tx(_tx_);
626
+ if(tx.logs && tx.logs.includes("Program log: Lottery draw has been initiated, cannot boost prize pool")){
627
+ return "Draw initiated, cannot boost this prize pool";
628
+ }
629
+ if(tx.status !== "ok"){return tx;}
630
+ if(booster.secretKey && !encoded){
631
+ tx.transaction.sign([booster]);
632
+ const sig = await network.Send(tx.transaction);
633
+ console.log("Signature:", sig);
634
+ const status = await network.Status(sig);
635
+ if(status == "finalized"){
636
+ return "boosted";
637
+ }
638
+ else{return status;}
639
+ }
640
+ else{return tx;}
641
+ }
642
+ catch (error) {
643
+ console.log(error);
644
+ }
645
+ }
646
+
647
+ /**
648
+ * @param {Keypair} authority - Keypair
649
+ * @param {Number} lotteryId - The lottery id
650
+ * @param {Boolean} group - if true, groups results by booster wallet address
651
+ * @param {Number} limit - the results to request (max 1000)
652
+ * @returns {Array|Object} - Array of booster objects or grouped booster objects if group=true
653
+ */
654
+ async GetBoosters(authority=false, lotteryId=false, group=false, limit=1000) {
655
+ try{
656
+ const initial = [];
657
+ const result = [];
658
+ const signatures = await this.connection.getSignaturesForAddress(this.program, {limit: limit,});
659
+ for await (const row of signatures) {
660
+ if(!row.err && row.confirmationStatus=="finalized" && row.memo && row.memo.includes(":booster:")){
661
+ initial.push(row);
662
+ }
663
+ }
664
+ for await (const init of initial) {
665
+ const tx = await this.connection.getTransaction(init.signature,{maxSupportedTransactionVersion:0});
666
+ const logs = tx.meta.logMessages;
667
+ const item = {};
668
+ let isBooster = false;
669
+ for await (const log of logs){if(log.includes("Program log: Boosted by")){isBooster=true;}}
670
+ if(!isBooster){continue;}
671
+ for await (const log of logs) {
672
+ if(log.includes("Program log: Boosted by ")){
673
+ item.booster = log.replace("Program log: Boosted by ","").trim();
674
+ }
675
+ else if(log.includes("Program log: Lottery ID ")){
676
+ item.lotteryId = Number(log.replace("Program log: Lottery ID ","").trim());
677
+ }
678
+ else if(log.includes("Program log: Boost amount: ")){
679
+ const data = log.replace("Program log: Boost amount: ","").trim();
680
+ item.amount = parseFloat(data.split(" SOL ")[0]);
681
+ }
682
+ else if(log.includes("Program log: Memo ")){
683
+ const parts = log.split(":booster:");
684
+ item.message = parts[1].slice(0, -1).trim();
685
+ }
686
+ else if(log.includes("Program log: Authority ")){
687
+ item.authority = log.replace("Program log: Authority ","").trim();
688
+ }
689
+ }
690
+ // Apply filters with safety checks
691
+ const matchesAuthority = authority ? (item.authority && authority.publicKey.toString() === item.authority) : true;
692
+ const matchesLotteryId = lotteryId ? (item.lotteryId !== undefined && lotteryId.toString() === item.lotteryId.toString()) : true;
693
+ if(matchesAuthority && matchesLotteryId && item.amount >= 0.0001){
694
+ item.signature = init.signature;
695
+ result.push(item);
696
+ }
697
+ }
698
+ // Group by booster if requested
699
+ if (group) {
700
+ const grouped = {};
701
+ result.forEach(item => {
702
+ if (!grouped[item.booster]) {
703
+ grouped[item.booster] = {
704
+ boost: [],
705
+ total: 0,
706
+ count: 0
707
+ };
708
+ }
709
+ grouped[item.booster].boost.push(item);
710
+ grouped[item.booster].total += item.amount;
711
+ grouped[item.booster].count = grouped[item.booster].boost.length;
712
+ });
713
+ return grouped;
714
+ }
715
+ return result;
716
+ }
717
+ catch (error) {return error;}
718
+ }
719
+
577
720
  }
578
721
 
579
722
  class LotteryManager {
@@ -823,150 +966,6 @@ class LotteryManager {
823
966
  }
824
967
  }
825
968
 
826
- /**
827
- * @param {Keypair} authority - Keypair
828
- * @param {String} lotteryId - The lottery id
829
- * @param {Keypair} booster - The booster's keypair
830
- * @param {Number} amount - The amount of sol to boost
831
- * @param {Boolean} encoded - true returns encoded transaction
832
- */
833
- async Boost(authority, lotteryId, booster, amount, message = false, encoded = false) {
834
- try{
835
- async function boostData(lotId, amount) {
836
- const lamports = parseInt(amount * LAMPORTS_PER_SOL);
837
- const buffer = Buffer.alloc(17); // 1 byte discriminator + 1 bytes price + 8 bytes id
838
- buffer.writeUInt8(INSTRUCTIONS.BOOST_LOTTERY, 0); // boostLottery discriminator
839
- buffer.writeBigUInt64LE(BigInt(lotId), 1);
840
- buffer.writeBigUInt64LE(BigInt(lamports), 9);
841
- return buffer;
842
- }
843
- if(message){message = ":booster:"+message;}
844
- const lottery = new Lottery(this.connection, false, this.program);
845
- const network = new LotteryNetwork(this.connection);
846
- const [lotteryPDA] = await lottery.DeriveLotteryPDA(authority.publicKey, lotteryId);
847
- const LOTTO = await lottery.GetLottery(authority, lotteryId);
848
- const keys = [
849
- { pubkey: booster.publicKey, isSigner: true, isWritable: true },
850
- { pubkey: lotteryPDA, isSigner: false, isWritable: true },
851
- { pubkey: new PublicKey(LOTTO.prizePoolAddress), isSigner: false, isWritable: true },
852
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
853
- ];
854
- const ix = new TransactionInstruction(
855
- {programId: this.program, keys, data: await boostData(lotteryId, amount)}
856
- );
857
- const _tx_ = {};
858
- _tx_.account = booster.publicKey.toString(); // string : required
859
- _tx_.instructions = [ix]; // array : required
860
- _tx_.signers = false; // array : default false
861
- _tx_.table = false; // array : default false
862
- _tx_.tolerance = 1.2; // int : default 1.1
863
- _tx_.compute = true; // bool : default true
864
- _tx_.fees = true; // bool : default true
865
- _tx_.priority = "Low"; // string : default Low
866
- _tx_.memo = message;
867
- if(encoded){
868
- _tx_.serialize = true;
869
- _tx_.encode = true;
870
- }
871
- else{
872
- _tx_.serialize = false;
873
- _tx_.encode = false;
874
- }
875
- const tx = await network.Tx(_tx_);
876
- if(tx.logs && tx.logs.includes("Program log: Lottery draw has been initiated, cannot boost prize pool")){
877
- return "Draw initiated, cannot boost this prize pool";
878
- }
879
- if(tx.status !== "ok"){return tx;}
880
- if(booster.secretKey && !encoded){
881
- tx.transaction.sign([booster]);
882
- const sig = await network.Send(tx.transaction);
883
- console.log("Signature:", sig);
884
- const status = await network.Status(sig);
885
- if(status == "finalized"){
886
- return "boosted";
887
- }
888
- else{return status;}
889
- }
890
- else{return tx;}
891
- }
892
- catch (error) {
893
- console.log(error);
894
- }
895
- }
896
-
897
- /**
898
- * @param {Keypair} authority - Keypair
899
- * @param {Number} lotteryId - The lottery id
900
- * @param {Boolean} group - if true, groups results by booster wallet address
901
- * @param {Number} limit - the results to request (max 1000)
902
- * @returns {Array|Object} - Array of booster objects or grouped booster objects if group=true
903
- */
904
- async GetBoosters(authority=false, lotteryId=false, group=false, limit=1000) {
905
- try{
906
- const initial = [];
907
- const result = [];
908
- const signatures = await this.connection.getSignaturesForAddress(this.program, {limit: limit,});
909
- for await (const row of signatures) {
910
- if(!row.err && row.confirmationStatus=="finalized" && row.memo && row.memo.includes(":booster:")){
911
- initial.push(row);
912
- }
913
- }
914
- for await (const init of initial) {
915
- const tx = await this.connection.getTransaction(init.signature,{maxSupportedTransactionVersion:0});
916
- const logs = tx.meta.logMessages;
917
- const item = {};
918
- let isBooster = false;
919
- for await (const log of logs){if(log.includes("Program log: Boosted by")){isBooster=true;}}
920
- if(!isBooster){continue;}
921
- for await (const log of logs) {
922
- if(log.includes("Program log: Boosted by ")){
923
- item.booster = log.replace("Program log: Boosted by ","").trim();
924
- }
925
- else if(log.includes("Program log: Lottery ID ")){
926
- item.lotteryId = Number(log.replace("Program log: Lottery ID ","").trim());
927
- }
928
- else if(log.includes("Program log: Boost amount: ")){
929
- const data = log.replace("Program log: Boost amount: ","").trim();
930
- item.amount = parseFloat(data.split(" SOL ")[0]);
931
- }
932
- else if(log.includes("Program log: Memo ")){
933
- const parts = log.split(":booster:");
934
- item.message = parts[1].slice(0, -1).trim();
935
- }
936
- else if(log.includes("Program log: Authority ")){
937
- item.authority = log.replace("Program log: Authority ","").trim();
938
- }
939
- }
940
- // Apply filters with safety checks
941
- const matchesAuthority = authority ? (item.authority && authority.publicKey.toString() === item.authority) : true;
942
- const matchesLotteryId = lotteryId ? (item.lotteryId !== undefined && lotteryId.toString() === item.lotteryId.toString()) : true;
943
- if(matchesAuthority && matchesLotteryId && item.amount >= 0.0001){
944
- item.signature = init.signature;
945
- result.push(item);
946
- }
947
- }
948
- // Group by booster if requested
949
- if (group) {
950
- const grouped = {};
951
- result.forEach(item => {
952
- if (!grouped[item.booster]) {
953
- grouped[item.booster] = {
954
- boost: [],
955
- total: 0,
956
- count: 0
957
- };
958
- }
959
- grouped[item.booster].boost.push(item);
960
- grouped[item.booster].total += item.amount;
961
- grouped[item.booster].count = grouped[item.booster].boost.length;
962
- });
963
- return grouped;
964
- }
965
- return result;
966
- }
967
- catch (error) {return error;}
968
- }
969
-
970
969
  }
971
970
 
972
971
  export {