solotto 1.0.6 → 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 +78 -77
  2. package/package.json +1 -1
  3. package/solotto.d.ts +48 -46
  4. package/solotto.js +143 -131
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 |
@@ -242,23 +303,23 @@ const result = await manager.Boost(authority, lotteryId, booster, 1.0, "Good luc
242
303
 
243
304
  **Returns:** `"boosted"` on success, `"Draw initiated, cannot boost this prize pool"` if the draw has already started, or the transaction object when encoded.
244
305
 
245
- > **Note:** When a `message` is provided, the SDK automatically prepends a structured memo in the format `:booster:authority,lotteryId,booster,amount:booster:` before your message. This structured prefix is used by `GetBoosters` to index boost history from on-chain transaction memos.
306
+ > **Note:** When a `message` is provided, the SDK prepends `:booster:` to the memo string. This tag is used by `GetBoosters` to identify boost transactions when scanning on-chain history.
246
307
 
247
308
  ---
248
309
 
249
310
  #### GetBoosters
250
311
 
251
- Retrieves boost history by scanning on-chain transaction memos. Can filter by authority, lottery ID, or both, and optionally group results by booster wallet address.
312
+ Retrieves boost history by scanning on-chain program logs for boost transactions. Filters out errored and non-finalized transactions, and only includes boosts of at least 0.0001 SOL. Can filter by authority, lottery ID, or both, and optionally group results by booster wallet address.
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 |
@@ -273,10 +334,11 @@ const grouped = await manager.GetBoosters(authority, lotteryId, true);
273
334
  ```js
274
335
  [
275
336
  {
276
- lotteryId: 1,
277
- authority: "Pubkey...",
278
- booster: "Pubkey...",
279
- amount: 0.5,
337
+ booster: "Pubkey...", // Booster wallet public key
338
+ lotteryId: 1, // Lottery ID
339
+ authority: "Pubkey...", // Lottery authority public key
340
+ amount: 0.5, // Boost amount in SOL
341
+ message: "Good luck!", // Optional memo message (empty string if none)
280
342
  signature: "TxSignature...",
281
343
  },
282
344
  // ...
@@ -289,7 +351,7 @@ const grouped = await manager.GetBoosters(authority, lotteryId, true);
289
351
  {
290
352
  "BoosterPubkey...": {
291
353
  boost: [
292
- { lotteryId: 1, authority: "Pubkey...", booster: "Pubkey...", amount: 0.5, signature: "TxSig..." },
354
+ { booster: "Pubkey...", lotteryId: 1, authority: "Pubkey...", amount: 0.5, message: "...", signature: "TxSig..." },
293
355
  // ...
294
356
  ],
295
357
  total: 1.5, // Sum of all boost amounts in SOL
@@ -301,67 +363,6 @@ const grouped = await manager.GetBoosters(authority, lotteryId, true);
301
363
 
302
364
  ---
303
365
 
304
- ### Lottery API
305
-
306
- #### BuyTickets
307
-
308
- Purchases one or more tickets for a lottery. Supports buying up to 4 tickets in a single transaction.
309
-
310
- ```js
311
- const lottery = new Lottery(connection, false, programId);
312
-
313
- const result = await lottery.BuyTickets(buyer, authority, lotteryId, amount, encoded);
314
- ```
315
-
316
- | Parameter | Type | Default | Description |
317
- |---|---|---|---|
318
- | `buyer` | `Keypair` | — | The keypair of the ticket buyer. |
319
- | `authority` | `Keypair \| {publicKey}` | — | The lottery authority (only `publicKey` is needed). |
320
- | `lotteryId` | `Number` | — | The lottery ID to buy tickets for. |
321
- | `amount` | `Number` | `1` | Number of tickets to purchase (1–4). |
322
- | `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
323
-
324
- **Returns:** `"finalized"` on success, `"Lottery is not active, no tickets can be sold"` if the lottery is inactive, or the transaction object when encoded.
325
-
326
- **Example:**
327
-
328
- ```js
329
- import { Connection, PublicKey, Keypair } from "@solana/web3.js";
330
- import { Lottery } from "solotto";
331
-
332
- const connection = new Connection("https://api.mainnet-beta.solana.com");
333
- const programId = new PublicKey("YOUR_PROGRAM_ID");
334
- const lottery = new Lottery(connection, false, programId);
335
-
336
- const buyer = Keypair.generate();
337
- const authority = { publicKey: new PublicKey("LOTTERY_AUTHORITY_PUBKEY") };
338
-
339
- // Buy 2 tickets for lottery #1
340
- const result = await lottery.BuyTickets(buyer, authority, 1, 2);
341
- console.log(result); // "finalized"
342
- ```
343
-
344
- ---
345
-
346
- #### ClaimTicket
347
-
348
- Claims the prize for the winning ticket. Must be called by the ticket owner.
349
-
350
- ```js
351
- const result = await lottery.ClaimTicket(authority, lotteryId, winner, encoded);
352
- ```
353
-
354
- | Parameter | Type | Default | Description |
355
- |---|---|---|---|
356
- | `authority` | `{publicKey}` | — | The lottery authority (only `publicKey` is needed). |
357
- | `lotteryId` | `Number` | — | The lottery ID. |
358
- | `winner` | `Keypair` | — | The keypair of the winning ticket's owner. |
359
- | `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
360
-
361
- **Returns:** `"finalized"` on success, the simulation log array (`string[]`) if the transaction fails simulation, or the transaction object when encoded.
362
-
363
- ---
364
-
365
366
  #### GetLottery
366
367
 
367
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.6",
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
@@ -141,14 +141,16 @@ declare module "solotto" {
141
141
  // ── Booster Types ──────────────────────────────────────────────────
142
142
 
143
143
  interface BoosterRecord {
144
+ /** Booster wallet public key. */
145
+ booster: string;
144
146
  /** Lottery numeric identifier. */
145
147
  lotteryId: number;
146
148
  /** Lottery authority public key. */
147
149
  authority: string;
148
- /** Booster wallet public key. */
149
- booster: string;
150
150
  /** Boost amount in SOL. */
151
151
  amount: number;
152
+ /** Optional memo message from the booster. */
153
+ message: string;
152
154
  /** Transaction signature. */
153
155
  signature: string;
154
156
  }
@@ -288,6 +290,50 @@ declare module "solotto" {
288
290
  buyer?: HasPublicKey | false
289
291
  ): Promise<TicketListResult>;
290
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
+
291
337
  /** Derive the lottery PDA. */
292
338
  DeriveLotteryPDA(
293
339
  authority: PublicKey,
@@ -365,49 +411,5 @@ declare module "solotto" {
365
411
  lotteryId: number,
366
412
  encoded?: boolean
367
413
  ): Promise<LotteryState | string | TxResult | undefined>;
368
-
369
- /**
370
- * Boost a lottery's prize pool by transferring SOL from any wallet.
371
- * @param authority - The lottery authority (only `publicKey` needed).
372
- * @param lotteryId - Lottery numeric identifier.
373
- * @param booster - The keypair of the wallet sending the boost.
374
- * @param amount - Amount of SOL to boost (e.g. `0.5` for 0.5 SOL).
375
- * @param message - Optional memo string attached to the transaction.
376
- * @param encoded - If `true`, return a base64-encoded transaction.
377
- */
378
- Boost(
379
- authority: HasPublicKey,
380
- lotteryId: number,
381
- booster: Keypair,
382
- amount: number,
383
- message?: string | false,
384
- encoded?: boolean
385
- ): Promise<string | TxResult | undefined>;
386
-
387
- /**
388
- * Retrieve boost history from on-chain transaction memos.
389
- * @param authority - Filter by lottery authority, or `false` for all.
390
- * @param lotteryId - Filter by lottery ID, or `false` for all.
391
- * @param group - If `true`, group results by booster wallet address.
392
- * @param limit - Maximum number of recent transactions to scan (max 1000).
393
- */
394
- GetBoosters(
395
- authority?: HasPublicKey | false,
396
- lotteryId?: number | false,
397
- group?: false,
398
- limit?: number
399
- ): Promise<BoosterRecord[]>;
400
- GetBoosters(
401
- authority: HasPublicKey | false,
402
- lotteryId: number | false,
403
- group: true,
404
- limit?: number
405
- ): Promise<GroupedBoostersResult>;
406
- GetBoosters(
407
- authority?: HasPublicKey | false,
408
- lotteryId?: number | false,
409
- group?: boolean,
410
- limit?: number
411
- ): Promise<BoosterRecord[] | GroupedBoostersResult>;
412
414
  }
413
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,137 +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){
844
- message = ":booster:"+authority.publicKey.toString()+","+lotteryId+","+booster.publicKey.toString()+","+amount+":booster:"+message;
845
- }
846
- const lottery = new Lottery(this.connection, false, this.program);
847
- const network = new LotteryNetwork(this.connection);
848
- const [lotteryPDA] = await lottery.DeriveLotteryPDA(authority.publicKey, lotteryId);
849
- const LOTTO = await lottery.GetLottery(authority, lotteryId);
850
- const keys = [
851
- { pubkey: booster.publicKey, isSigner: true, isWritable: true },
852
- { pubkey: lotteryPDA, isSigner: false, isWritable: true },
853
- { pubkey: new PublicKey(LOTTO.prizePoolAddress), isSigner: false, isWritable: true },
854
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
855
- ];
856
- const ix = new TransactionInstruction(
857
- {programId: this.program, keys, data: await boostData(lotteryId, amount)}
858
- );
859
- const _tx_ = {};
860
- _tx_.account = booster.publicKey.toString(); // string : required
861
- _tx_.instructions = [ix]; // array : required
862
- _tx_.signers = false; // array : default false
863
- _tx_.table = false; // array : default false
864
- _tx_.tolerance = 1.2; // int : default 1.1
865
- _tx_.compute = true; // bool : default true
866
- _tx_.fees = true; // bool : default true
867
- _tx_.priority = "Low"; // string : default Low
868
- _tx_.memo = message;
869
- if(encoded){
870
- _tx_.serialize = true;
871
- _tx_.encode = true;
872
- }
873
- else{
874
- _tx_.serialize = false;
875
- _tx_.encode = false;
876
- }
877
- const tx = await network.Tx(_tx_);
878
- if(tx.logs && tx.logs.includes("Program log: Lottery draw has been initiated, cannot boost prize pool")){
879
- return "Draw initiated, cannot boost this prize pool";
880
- }
881
- if(tx.status !== "ok"){return tx;}
882
- if(booster.secretKey && !encoded){
883
- tx.transaction.sign([booster]);
884
- const sig = await network.Send(tx.transaction);
885
- console.log("Signature:", sig);
886
- const status = await network.Status(sig);
887
- if(status == "finalized"){
888
- return "boosted";
889
- }
890
- else{return status;}
891
- }
892
- else{return tx;}
893
- }
894
- catch (error) {
895
- console.log(error);
896
- }
897
- }
898
-
899
- /**
900
- * @param {Keypair} authority - Keypair
901
- * @param {String} lotteryId - The lottery id
902
- * @param {Boolean} group - if true, groups results by booster wallet address
903
- * @param {Number} limit - the results to request (max 1000)
904
- * @returns {Array|Object} - Array of booster objects or Object grouped by booster address
905
- * Booster objects are returned if the transaction memo includes ":booster:" and matches the authority and lotteryId (if provided)
906
- * Booster memo format: ":booster:authorityPublicKey,lotteryId,boosterPublicKey,amount:booster:optionalMessage"
907
- * Example return object: { authority: "authorityPublicKey", lotteryId: "1", booster: "boosterPublicKey", amount: 1.5, signature: "transactionSignature" }
908
- * If authority is provided, only boosters from that authority are returned
909
- * If lotteryId is provided, only boosters for that lotteryId are returned
910
- * If both authority and lotteryId are provided, only boosters matching both are returned
911
- * If neither is provided, all boosters are returned up to the specified limit
912
- * If group is true, returns object with booster addresses as keys, each containing array of boost objects and total amount
913
- * Example grouped return: { "boosterPublicKey": { boost: [...], total: 5.5 } }
914
- */
915
- async GetBoosters(authority=false, lotteryId=false, group=false, limit=1000) {
916
- try{
917
- const result = [];
918
- const signatures = await this.connection.getSignaturesForAddress(this.program, {limit: limit,});
919
- for await (const row of signatures) {
920
- if(row.memo && row.memo.includes(":booster:")){
921
- const memo = row.memo.split(":booster:")[1];
922
- const [auth, lotId, booster, amount] = memo.split(",");
923
- if((authority ? authority.publicKey.toString() === auth : true) &&
924
- (lotteryId ? lotteryId.toString() === lotId : true)
925
- ){
926
- result.push({
927
- lotteryId: Number(lotId),
928
- authority: auth,
929
- booster: booster,
930
- amount: parseFloat(amount),
931
- signature: row.signature
932
- });
933
- }
934
- }
935
- }
936
- if (group) {
937
- const grouped = {};
938
- result.forEach(item => {
939
- if (!grouped[item.booster]) {
940
- grouped[item.booster] = {
941
- boost: [],
942
- total: 0
943
- }
944
- }
945
- grouped[item.booster].boost.push(item);
946
- grouped[item.booster].total += item.amount;
947
- grouped[item.booster].count = grouped[item.booster].boost.length;
948
- });
949
- return grouped;
950
- }
951
-
952
- return result;
953
- }
954
- catch (error) {return error;}
955
- }
956
-
957
969
  }
958
970
 
959
971
  export {