solotto 1.0.6 → 1.0.7

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/README.md CHANGED
@@ -242,13 +242,13 @@ const result = await manager.Boost(authority, lotteryId, booster, 1.0, "Good luc
242
242
 
243
243
  **Returns:** `"boosted"` on success, `"Draw initiated, cannot boost this prize pool"` if the draw has already started, or the transaction object when encoded.
244
244
 
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.
245
+ > **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
246
 
247
247
  ---
248
248
 
249
249
  #### GetBoosters
250
250
 
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.
251
+ 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
252
 
253
253
  ```js
254
254
  // Get all boosters for a specific lottery
@@ -273,10 +273,11 @@ const grouped = await manager.GetBoosters(authority, lotteryId, true);
273
273
  ```js
274
274
  [
275
275
  {
276
- lotteryId: 1,
277
- authority: "Pubkey...",
278
- booster: "Pubkey...",
279
- amount: 0.5,
276
+ booster: "Pubkey...", // Booster wallet public key
277
+ lotteryId: 1, // Lottery ID
278
+ authority: "Pubkey...", // Lottery authority public key
279
+ amount: 0.5, // Boost amount in SOL
280
+ message: "Good luck!", // Optional memo message (empty string if none)
280
281
  signature: "TxSignature...",
281
282
  },
282
283
  // ...
@@ -289,7 +290,7 @@ const grouped = await manager.GetBoosters(authority, lotteryId, true);
289
290
  {
290
291
  "BoosterPubkey...": {
291
292
  boost: [
292
- { lotteryId: 1, authority: "Pubkey...", booster: "Pubkey...", amount: 0.5, signature: "TxSig..." },
293
+ { booster: "Pubkey...", lotteryId: 1, authority: "Pubkey...", amount: 0.5, message: "...", signature: "TxSig..." },
293
294
  // ...
294
295
  ],
295
296
  total: 1.5, // Sum of all boost amounts in SOL
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solotto",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
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
  }
package/solotto.js CHANGED
@@ -840,9 +840,7 @@ class LotteryManager {
840
840
  buffer.writeBigUInt64LE(BigInt(lamports), 9);
841
841
  return buffer;
842
842
  }
843
- if(message){
844
- message = ":booster:"+authority.publicKey.toString()+","+lotteryId+","+booster.publicKey.toString()+","+amount+":booster:"+message;
845
- }
843
+ if(message){message = ":booster:"+message;}
846
844
  const lottery = new Lottery(this.connection, false, this.program);
847
845
  const network = new LotteryNetwork(this.connection);
848
846
  const [lotteryPDA] = await lottery.DeriveLotteryPDA(authority.publicKey, lotteryId);
@@ -898,49 +896,65 @@ class LotteryManager {
898
896
 
899
897
  /**
900
898
  * @param {Keypair} authority - Keypair
901
- * @param {String} lotteryId - The lottery id
899
+ * @param {Number} lotteryId - The lottery id
902
900
  * @param {Boolean} group - if true, groups results by booster wallet address
903
901
  * @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 } }
902
+ * @returns {Array|Object} - Array of booster objects or grouped booster objects if group=true
914
903
  */
915
904
  async GetBoosters(authority=false, lotteryId=false, group=false, limit=1000) {
916
905
  try{
906
+ const initial = [];
917
907
  const result = [];
918
908
  const signatures = await this.connection.getSignaturesForAddress(this.program, {limit: limit,});
919
909
  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
- });
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();
933
938
  }
934
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
+ }
935
947
  }
948
+ // Group by booster if requested
936
949
  if (group) {
937
950
  const grouped = {};
938
951
  result.forEach(item => {
939
952
  if (!grouped[item.booster]) {
940
953
  grouped[item.booster] = {
941
954
  boost: [],
942
- total: 0
943
- }
955
+ total: 0,
956
+ count: 0
957
+ };
944
958
  }
945
959
  grouped[item.booster].boost.push(item);
946
960
  grouped[item.booster].total += item.amount;
@@ -948,7 +962,6 @@ class LotteryManager {
948
962
  });
949
963
  return grouped;
950
964
  }
951
-
952
965
  return result;
953
966
  }
954
967
  catch (error) {return error;}