solotto 1.0.5 → 1.0.6
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 +60 -2
- package/package.json +1 -1
- package/solotto.d.ts +55 -1
- package/solotto.js +64 -0
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ A JavaScript SDK for interacting with the Solotto on-chain lottery program on So
|
|
|
20
20
|
- [LockLottery](#locklottery)
|
|
21
21
|
- [ClaimExpired](#claimexpired)
|
|
22
22
|
- [Boost](#boost)
|
|
23
|
+
- [GetBoosters](#getboosters)
|
|
23
24
|
- [Lottery](#lottery-api)
|
|
24
25
|
- [BuyTickets](#buytickets)
|
|
25
26
|
- [ClaimTicket](#claimticket)
|
|
@@ -241,6 +242,63 @@ const result = await manager.Boost(authority, lotteryId, booster, 1.0, "Good luc
|
|
|
241
242
|
|
|
242
243
|
**Returns:** `"boosted"` on success, `"Draw initiated, cannot boost this prize pool"` if the draw has already started, or the transaction object when encoded.
|
|
243
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.
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
#### GetBoosters
|
|
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.
|
|
252
|
+
|
|
253
|
+
```js
|
|
254
|
+
// Get all boosters for a specific lottery
|
|
255
|
+
const boosters = await manager.GetBoosters(authority, lotteryId);
|
|
256
|
+
|
|
257
|
+
// Get all boosters across all lotteries (up to 500 transactions)
|
|
258
|
+
const allBoosters = await manager.GetBoosters(false, false, false, 500);
|
|
259
|
+
|
|
260
|
+
// Get boosters grouped by wallet address
|
|
261
|
+
const grouped = await manager.GetBoosters(authority, lotteryId, true);
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
| Parameter | Type | Default | Description |
|
|
265
|
+
|---|---|---|---|
|
|
266
|
+
| `authority` | `{publicKey} \| false` | `false` | Filter by lottery authority. Pass `false` to include all authorities. |
|
|
267
|
+
| `lotteryId` | `Number \| false` | `false` | Filter by lottery ID. Pass `false` to include all lotteries. |
|
|
268
|
+
| `group` | `Boolean` | `false` | If `true`, groups results by booster wallet address. |
|
|
269
|
+
| `limit` | `Number` | `1000` | Maximum number of recent transactions to scan (max 1000). |
|
|
270
|
+
|
|
271
|
+
**Returns (ungrouped):** An array of booster objects:
|
|
272
|
+
|
|
273
|
+
```js
|
|
274
|
+
[
|
|
275
|
+
{
|
|
276
|
+
lotteryId: 1,
|
|
277
|
+
authority: "Pubkey...",
|
|
278
|
+
booster: "Pubkey...",
|
|
279
|
+
amount: 0.5,
|
|
280
|
+
signature: "TxSignature...",
|
|
281
|
+
},
|
|
282
|
+
// ...
|
|
283
|
+
]
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Returns (grouped, `group = true`):** An object keyed by booster wallet address:
|
|
287
|
+
|
|
288
|
+
```js
|
|
289
|
+
{
|
|
290
|
+
"BoosterPubkey...": {
|
|
291
|
+
boost: [
|
|
292
|
+
{ lotteryId: 1, authority: "Pubkey...", booster: "Pubkey...", amount: 0.5, signature: "TxSig..." },
|
|
293
|
+
// ...
|
|
294
|
+
],
|
|
295
|
+
total: 1.5, // Sum of all boost amounts in SOL
|
|
296
|
+
count: 3, // Number of boosts
|
|
297
|
+
},
|
|
298
|
+
// ...
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
244
302
|
---
|
|
245
303
|
|
|
246
304
|
### Lottery API
|
|
@@ -300,7 +358,7 @@ const result = await lottery.ClaimTicket(authority, lotteryId, winner, encoded);
|
|
|
300
358
|
| `winner` | `Keypair` | — | The keypair of the winning ticket's owner. |
|
|
301
359
|
| `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
|
|
302
360
|
|
|
303
|
-
**Returns:** `"finalized"` on success, or the transaction object when encoded.
|
|
361
|
+
**Returns:** `"finalized"` on success, the simulation log array (`string[]`) if the transaction fails simulation, or the transaction object when encoded.
|
|
304
362
|
|
|
305
363
|
---
|
|
306
364
|
|
|
@@ -518,7 +576,7 @@ const status = await network.Status(signature, maxRetries, intervalSeconds);
|
|
|
518
576
|
|
|
519
577
|
## Transaction Modes
|
|
520
578
|
|
|
521
|
-
Every write method (`Initialize`, `RandomDraw`, `LockLottery`, `BuyTickets`, `ClaimTicket`) supports two modes controlled by the `encoded` parameter:
|
|
579
|
+
Every write method (`Initialize`, `RandomDraw`, `LockLottery`, `ClaimExpired`, `Boost`, `BuyTickets`, `ClaimTicket`) supports two modes controlled by the `encoded` parameter:
|
|
522
580
|
|
|
523
581
|
**Direct Mode** (`encoded = false`, default) — The SDK signs, sends, and confirms the transaction. Requires the keypair to have a `secretKey`. Returns the final status or lottery state.
|
|
524
582
|
|
package/package.json
CHANGED
package/solotto.d.ts
CHANGED
|
@@ -138,6 +138,34 @@ declare module "solotto" {
|
|
|
138
138
|
reconnecting: (event: ReconnectingEvent) => void;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
// ── Booster Types ──────────────────────────────────────────────────
|
|
142
|
+
|
|
143
|
+
interface BoosterRecord {
|
|
144
|
+
/** Lottery numeric identifier. */
|
|
145
|
+
lotteryId: number;
|
|
146
|
+
/** Lottery authority public key. */
|
|
147
|
+
authority: string;
|
|
148
|
+
/** Booster wallet public key. */
|
|
149
|
+
booster: string;
|
|
150
|
+
/** Boost amount in SOL. */
|
|
151
|
+
amount: number;
|
|
152
|
+
/** Transaction signature. */
|
|
153
|
+
signature: string;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
interface GroupedBooster {
|
|
157
|
+
/** Array of individual boost records. */
|
|
158
|
+
boost: BoosterRecord[];
|
|
159
|
+
/** Total SOL boosted by this wallet. */
|
|
160
|
+
total: number;
|
|
161
|
+
/** Number of boosts from this wallet. */
|
|
162
|
+
count: number;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
interface GroupedBoostersResult {
|
|
166
|
+
[boosterAddress: string]: GroupedBooster;
|
|
167
|
+
}
|
|
168
|
+
|
|
141
169
|
// ── Authority-like objects ────────────────────────────────────────────
|
|
142
170
|
|
|
143
171
|
/** An object with at least a `publicKey` property (e.g. a Keypair without the secret key). */
|
|
@@ -237,7 +265,7 @@ declare module "solotto" {
|
|
|
237
265
|
lotteryId: number,
|
|
238
266
|
winner: Keypair,
|
|
239
267
|
encoded?: boolean
|
|
240
|
-
): Promise<string | TxResult>;
|
|
268
|
+
): Promise<string | string[] | TxResult>;
|
|
241
269
|
|
|
242
270
|
/** Fetch the on-chain state of a lottery. */
|
|
243
271
|
GetLottery(
|
|
@@ -355,5 +383,31 @@ declare module "solotto" {
|
|
|
355
383
|
message?: string | false,
|
|
356
384
|
encoded?: boolean
|
|
357
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>;
|
|
358
412
|
}
|
|
359
413
|
}
|
package/solotto.js
CHANGED
|
@@ -285,6 +285,9 @@ class Lottery extends EventEmitter {
|
|
|
285
285
|
_tx_.encode = false;
|
|
286
286
|
}
|
|
287
287
|
const tx = await network.Tx(_tx_);
|
|
288
|
+
if(tx.logs){
|
|
289
|
+
return tx.logs;
|
|
290
|
+
}
|
|
288
291
|
if(winner.secretKey && !encoded){
|
|
289
292
|
tx.transaction.sign([winner]);
|
|
290
293
|
const sig = await network.Send(tx.transaction);
|
|
@@ -837,6 +840,9 @@ class LotteryManager {
|
|
|
837
840
|
buffer.writeBigUInt64LE(BigInt(lamports), 9);
|
|
838
841
|
return buffer;
|
|
839
842
|
}
|
|
843
|
+
if(message){
|
|
844
|
+
message = ":booster:"+authority.publicKey.toString()+","+lotteryId+","+booster.publicKey.toString()+","+amount+":booster:"+message;
|
|
845
|
+
}
|
|
840
846
|
const lottery = new Lottery(this.connection, false, this.program);
|
|
841
847
|
const network = new LotteryNetwork(this.connection);
|
|
842
848
|
const [lotteryPDA] = await lottery.DeriveLotteryPDA(authority.publicKey, lotteryId);
|
|
@@ -890,6 +896,64 @@ class LotteryManager {
|
|
|
890
896
|
}
|
|
891
897
|
}
|
|
892
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
|
+
|
|
893
957
|
}
|
|
894
958
|
|
|
895
959
|
export {
|