solotto 1.1.1 → 1.1.3
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 +45 -3
- package/package.json +1 -1
- package/solotto.d.ts +26 -2
- package/solotto.js +47 -1
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@ A JavaScript SDK for interacting with the Solotto on-chain lottery program on So
|
|
|
24
24
|
- [ClaimTicket](#claimticket)
|
|
25
25
|
- [Boost](#boost)
|
|
26
26
|
- [GetBoosters](#getboosters)
|
|
27
|
+
- [GetMessages](#getmessages)
|
|
27
28
|
- [GetLottery](#getlottery)
|
|
28
29
|
- [GetLotteries](#getlotteries)
|
|
29
30
|
- [GetTicket](#getticket)
|
|
@@ -341,6 +342,7 @@ const grouped = await lottery.GetBoosters(authority, lotteryId, true);
|
|
|
341
342
|
authority: "Pubkey...", // Lottery authority public key
|
|
342
343
|
amount: 0.5, // Boost amount in SOL
|
|
343
344
|
message: "Good luck!", // Optional memo message (empty string if none)
|
|
345
|
+
time: 1700000000, // Unix block timestamp of the boost transaction
|
|
344
346
|
signature: "TxSignature...",
|
|
345
347
|
},
|
|
346
348
|
// ...
|
|
@@ -353,7 +355,7 @@ const grouped = await lottery.GetBoosters(authority, lotteryId, true);
|
|
|
353
355
|
{
|
|
354
356
|
"BoosterPubkey...": {
|
|
355
357
|
boost: [
|
|
356
|
-
{ booster: "Pubkey...", lotteryId: 1, authority: "Pubkey...", amount: 0.5, message: "...", signature: "TxSig..." },
|
|
358
|
+
{ booster: "Pubkey...", lotteryId: 1, authority: "Pubkey...", amount: 0.5, message: "...", time: 1700000000, signature: "TxSig..." },
|
|
357
359
|
// ...
|
|
358
360
|
],
|
|
359
361
|
total: 1.5, // Sum of all boost amounts in SOL
|
|
@@ -365,6 +367,41 @@ const grouped = await lottery.GetBoosters(authority, lotteryId, true);
|
|
|
365
367
|
|
|
366
368
|
---
|
|
367
369
|
|
|
370
|
+
#### GetMessages
|
|
371
|
+
|
|
372
|
+
Retrieves boost memo messages from on-chain transaction history. Paginates through program signatures and extracts messages from transactions tagged with `:booster:`. Useful for displaying a feed of booster shoutouts.
|
|
373
|
+
|
|
374
|
+
```js
|
|
375
|
+
// Get the latest boost messages (up to 1000)
|
|
376
|
+
const messages = await lottery.GetMessages();
|
|
377
|
+
|
|
378
|
+
// Get up to 200 messages
|
|
379
|
+
const recent = await lottery.GetMessages(200);
|
|
380
|
+
|
|
381
|
+
// Paginate: get messages until a specific signature
|
|
382
|
+
const older = await lottery.GetMessages(1000, "LastKnownSignature...");
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
| Parameter | Type | Default | Description |
|
|
386
|
+
|---|---|---|---|
|
|
387
|
+
| `limit` | `Number` | `1000` | Maximum number of transactions to scan. Paginates automatically if needed. |
|
|
388
|
+
| `until` | `String \| null` | `null` | Stop scanning at this transaction signature (exclusive). Useful for pagination. |
|
|
389
|
+
|
|
390
|
+
**Returns:** An array of message objects:
|
|
391
|
+
|
|
392
|
+
```js
|
|
393
|
+
[
|
|
394
|
+
{
|
|
395
|
+
message: "Good luck everyone!", // The booster's memo text
|
|
396
|
+
time: 1700000000, // Unix block timestamp
|
|
397
|
+
signature: "TxSignature...", // Transaction signature
|
|
398
|
+
},
|
|
399
|
+
// ...
|
|
400
|
+
]
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
368
405
|
#### GetLottery
|
|
369
406
|
|
|
370
407
|
Fetches the full on-chain state of a lottery.
|
|
@@ -457,7 +494,7 @@ const ticket = await lottery.GetTicket(authority, lotteryId, ticketNumber);
|
|
|
457
494
|
|
|
458
495
|
#### GetTickets
|
|
459
496
|
|
|
460
|
-
Fetches all tickets for a lottery, optionally filtered by buyer and/or
|
|
497
|
+
Fetches all tickets for a lottery, optionally filtered by buyer, grouped by owner, and/or enriched with purchase timestamps.
|
|
461
498
|
|
|
462
499
|
```js
|
|
463
500
|
// Get all tickets
|
|
@@ -468,6 +505,9 @@ const myTickets = await lottery.GetTickets(authority, lotteryId, buyer);
|
|
|
468
505
|
|
|
469
506
|
// Get all tickets grouped by owner
|
|
470
507
|
const grouped = await lottery.GetTickets(authority, lotteryId, false, true);
|
|
508
|
+
|
|
509
|
+
// Get all tickets with purchase timestamps
|
|
510
|
+
const withTime = await lottery.GetTickets(authority, lotteryId, false, false, true);
|
|
471
511
|
```
|
|
472
512
|
|
|
473
513
|
| Parameter | Type | Default | Description |
|
|
@@ -476,6 +516,7 @@ const grouped = await lottery.GetTickets(authority, lotteryId, false, true);
|
|
|
476
516
|
| `lotteryId` | `Number` | — | The lottery ID. |
|
|
477
517
|
| `buyer` | `{publicKey} \| false` | `false` | Optional buyer to filter by. |
|
|
478
518
|
| `group` | `Boolean` | `false` | If `true`, groups tickets by owner. |
|
|
519
|
+
| `time` | `Boolean` | `false` | If `true`, fetches the block timestamp for each ticket (slower — requires extra RPC calls). |
|
|
479
520
|
|
|
480
521
|
**Returns (ungrouped):**
|
|
481
522
|
|
|
@@ -492,6 +533,7 @@ const grouped = await lottery.GetTickets(authority, lotteryId, false, true);
|
|
|
492
533
|
ticketReceipt: "Pubkey...",
|
|
493
534
|
ticketNumber: 42,
|
|
494
535
|
ticketPda: "Pubkey...",
|
|
536
|
+
time: null, // Unix timestamp when time=true, null otherwise
|
|
495
537
|
},
|
|
496
538
|
// ... sorted descending by ticket number
|
|
497
539
|
],
|
|
@@ -511,7 +553,7 @@ const grouped = await lottery.GetTickets(authority, lotteryId, false, true);
|
|
|
511
553
|
owner: "Pubkey...",
|
|
512
554
|
ticketCount: 3,
|
|
513
555
|
tickets: [
|
|
514
|
-
{ owner: "Pubkey...", lottery: "Pubkey...", ticketReceipt: "Pubkey...", ticketNumber: 42, ticketPda: "Pubkey..." },
|
|
556
|
+
{ owner: "Pubkey...", lottery: "Pubkey...", ticketReceipt: "Pubkey...", ticketNumber: 42, ticketPda: "Pubkey...", time: null },
|
|
515
557
|
// ...
|
|
516
558
|
],
|
|
517
559
|
},
|
package/package.json
CHANGED
package/solotto.d.ts
CHANGED
|
@@ -105,6 +105,8 @@ declare module "solotto" {
|
|
|
105
105
|
ticketReceipt: string;
|
|
106
106
|
ticketNumber: number;
|
|
107
107
|
ticketPda: string;
|
|
108
|
+
/** Unix block timestamp of ticket purchase, or `null` when `time=false`. */
|
|
109
|
+
time: number | null;
|
|
108
110
|
}
|
|
109
111
|
|
|
110
112
|
interface GroupedTicketOwner {
|
|
@@ -160,6 +162,8 @@ declare module "solotto" {
|
|
|
160
162
|
amount: number;
|
|
161
163
|
/** Optional memo message from the booster. */
|
|
162
164
|
message: string;
|
|
165
|
+
/** Unix block timestamp of the boost transaction. */
|
|
166
|
+
time: number;
|
|
163
167
|
/** Transaction signature. */
|
|
164
168
|
signature: string;
|
|
165
169
|
}
|
|
@@ -177,6 +181,15 @@ declare module "solotto" {
|
|
|
177
181
|
[boosterAddress: string]: GroupedBooster;
|
|
178
182
|
}
|
|
179
183
|
|
|
184
|
+
interface MessageRecord {
|
|
185
|
+
/** The booster's memo text. */
|
|
186
|
+
message: string;
|
|
187
|
+
/** Unix block timestamp of the transaction. */
|
|
188
|
+
time: number;
|
|
189
|
+
/** Transaction signature. */
|
|
190
|
+
signature: string;
|
|
191
|
+
}
|
|
192
|
+
|
|
180
193
|
// ── Authority-like objects ────────────────────────────────────────────
|
|
181
194
|
|
|
182
195
|
/** An object with at least a `publicKey` property (e.g. a Keypair without the secret key). */
|
|
@@ -310,12 +323,13 @@ declare module "solotto" {
|
|
|
310
323
|
ticket: number
|
|
311
324
|
): Promise<TicketInfo>;
|
|
312
325
|
|
|
313
|
-
/** Fetch all tickets for a lottery, optionally filtered by buyer and/or
|
|
326
|
+
/** Fetch all tickets for a lottery, optionally filtered by buyer, grouped by owner, and/or with timestamps. */
|
|
314
327
|
GetTickets(
|
|
315
328
|
authority: HasPublicKey,
|
|
316
329
|
lotteryId: number,
|
|
317
330
|
buyer?: HasPublicKey | false,
|
|
318
|
-
group?: boolean
|
|
331
|
+
group?: boolean,
|
|
332
|
+
time?: boolean
|
|
319
333
|
): Promise<TicketListResult>;
|
|
320
334
|
|
|
321
335
|
/**
|
|
@@ -362,6 +376,16 @@ declare module "solotto" {
|
|
|
362
376
|
limit?: number
|
|
363
377
|
): Promise<BoosterRecord[] | GroupedBoostersResult>;
|
|
364
378
|
|
|
379
|
+
/**
|
|
380
|
+
* Retrieve boost memo messages from on-chain transaction history.
|
|
381
|
+
* @param limit - Maximum number of transactions to scan (paginates automatically).
|
|
382
|
+
* @param until - Stop scanning at this transaction signature (exclusive).
|
|
383
|
+
*/
|
|
384
|
+
GetMessages(
|
|
385
|
+
limit?: number,
|
|
386
|
+
until?: string | null
|
|
387
|
+
): Promise<MessageRecord[]>;
|
|
388
|
+
|
|
365
389
|
/** Derive the lottery PDA. */
|
|
366
390
|
DeriveLotteryPDA(
|
|
367
391
|
authority: PublicKey,
|
package/solotto.js
CHANGED
|
@@ -441,7 +441,7 @@ class Lottery extends EventEmitter {
|
|
|
441
441
|
* @param {Number} lotteryId - Lottery Id
|
|
442
442
|
* @param {PublicKey} buyer - Ticket Buyer Optional
|
|
443
443
|
*/
|
|
444
|
-
async GetTickets(authority, lotteryId, buyer = false, group = false) {
|
|
444
|
+
async GetTickets(authority, lotteryId, buyer = false, group = false, time = false) {
|
|
445
445
|
const [lotteryPDA] = await this.DeriveLotteryPDA(authority.publicKey, lotteryId);
|
|
446
446
|
const filters = [];
|
|
447
447
|
filters.push({dataSize: 104});
|
|
@@ -459,6 +459,11 @@ class Lottery extends EventEmitter {
|
|
|
459
459
|
newTicket.ticketReceipt = new PublicKey(decoded.ticketReceipt).toString();
|
|
460
460
|
newTicket.ticketNumber = parseInt(new BN(decoded.ticketNumber, 10, "le"));
|
|
461
461
|
newTicket.ticketPda = data.pubkey.toString();
|
|
462
|
+
newTicket.time = null;
|
|
463
|
+
if(time){
|
|
464
|
+
const dat = await this.connection.getSignaturesForAddress(data.pubkey, "finalized");
|
|
465
|
+
newTicket.time = dat[0].blockTime;
|
|
466
|
+
}
|
|
462
467
|
tickets.push(newTicket);
|
|
463
468
|
i++;
|
|
464
469
|
}
|
|
@@ -732,6 +737,7 @@ class Lottery extends EventEmitter {
|
|
|
732
737
|
else if(log.includes("Program log: Memo ")){
|
|
733
738
|
const parts = log.split(":booster:");
|
|
734
739
|
item.message = parts[1].slice(0, -1).trim();
|
|
740
|
+
item.message = item.message.replace(new RegExp("\\\\", "g"), "");
|
|
735
741
|
}
|
|
736
742
|
else if(log.includes("Program log: Authority ")){
|
|
737
743
|
item.authority = log.replace("Program log: Authority ","").trim();
|
|
@@ -741,6 +747,7 @@ class Lottery extends EventEmitter {
|
|
|
741
747
|
const matchesAuthority = authority ? (item.authority && authority.publicKey.toString() === item.authority) : true;
|
|
742
748
|
const matchesLotteryId = lotteryId ? (item.lotteryId !== undefined && lotteryId.toString() === item.lotteryId.toString()) : true;
|
|
743
749
|
if(matchesAuthority && matchesLotteryId && item.amount >= 0.0001){
|
|
750
|
+
item.time = init.blockTime;
|
|
744
751
|
item.signature = init.signature;
|
|
745
752
|
result.push(item);
|
|
746
753
|
}
|
|
@@ -767,6 +774,45 @@ class Lottery extends EventEmitter {
|
|
|
767
774
|
catch (error) {return error;}
|
|
768
775
|
}
|
|
769
776
|
|
|
777
|
+
/**
|
|
778
|
+
* @param {Number} limit - the results to request (max 1000)
|
|
779
|
+
* @param {String} until - until signature to stop at (optional)
|
|
780
|
+
* @returns {Array|Object} - Array of booster objects or grouped booster objects if group=true
|
|
781
|
+
*/
|
|
782
|
+
async GetMessages(limit = 1000, until = null) {
|
|
783
|
+
try {
|
|
784
|
+
const result = [];
|
|
785
|
+
let allSignatures = [];
|
|
786
|
+
let lastSignature = null;
|
|
787
|
+
while (allSignatures.length < limit) {
|
|
788
|
+
const options = {limit: Math.min(1000, limit - allSignatures.length)};
|
|
789
|
+
if (lastSignature) {options.before = lastSignature;}
|
|
790
|
+
if (until) {options.until = until;}
|
|
791
|
+
const signatures = await this.connection.getSignaturesForAddress(this.program, options);
|
|
792
|
+
if (signatures.length === 0) break;
|
|
793
|
+
allSignatures.push(...signatures);
|
|
794
|
+
lastSignature = signatures[signatures.length - 1].signature;
|
|
795
|
+
if (signatures.length < options.limit) break;
|
|
796
|
+
}
|
|
797
|
+
for (const row of allSignatures) {
|
|
798
|
+
if (!row.err &&
|
|
799
|
+
row.confirmationStatus === "finalized" &&
|
|
800
|
+
row.memo &&
|
|
801
|
+
row.memo.includes(":booster:")) {
|
|
802
|
+
const memo = {
|
|
803
|
+
message: row.memo.split(":booster:")[1].trim(),
|
|
804
|
+
time: row.blockTime,
|
|
805
|
+
signature: row.signature
|
|
806
|
+
};
|
|
807
|
+
result.push(memo);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
return result;
|
|
811
|
+
} catch (error) {
|
|
812
|
+
return error;
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
770
816
|
}
|
|
771
817
|
|
|
772
818
|
class LotteryManager {
|