solotto 1.0.4 → 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 +88 -4
- package/SECURITY.md +15 -0
- package/package.json +1 -1
- package/solotto.d.ts +73 -1
- package/solotto.js +145 -3
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@ 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)
|
|
22
24
|
- [Lottery](#lottery-api)
|
|
23
25
|
- [BuyTickets](#buytickets)
|
|
24
26
|
- [ClaimTicket](#claimticket)
|
|
@@ -213,7 +215,89 @@ const result = await manager.ClaimExpired(authority, lotteryId, encoded);
|
|
|
213
215
|
| `lotteryId` | `String` | — | The lottery ID. |
|
|
214
216
|
| `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
|
|
215
217
|
|
|
216
|
-
**Returns:** Updated lottery state object on finalization, or the transaction object when encoded.
|
|
218
|
+
**Returns:** Updated lottery state object on finalization, `"Prize has already been claimed"` if the prize was already claimed, or the transaction object when encoded.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
#### Boost
|
|
223
|
+
|
|
224
|
+
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
|
+
|
|
226
|
+
```js
|
|
227
|
+
// Boost lottery #1 with 0.5 SOL
|
|
228
|
+
const result = await manager.Boost(authority, lotteryId, booster, 0.5);
|
|
229
|
+
|
|
230
|
+
// Boost with a memo message
|
|
231
|
+
const result = await manager.Boost(authority, lotteryId, booster, 1.0, "Good luck everyone!");
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
| Parameter | Type | Default | Description |
|
|
235
|
+
|---|---|---|---|
|
|
236
|
+
| `authority` | `{publicKey}` | — | The lottery authority (only `publicKey` is needed). |
|
|
237
|
+
| `lotteryId` | `String` | — | The lottery ID. |
|
|
238
|
+
| `booster` | `Keypair` | — | The keypair of the wallet sending the boost. |
|
|
239
|
+
| `amount` | `Number` | — | Amount of SOL to boost (e.g. `0.5` for 0.5 SOL). |
|
|
240
|
+
| `message` | `String \| false` | `false` | Optional memo string attached to the transaction. |
|
|
241
|
+
| `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
|
|
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.
|
|
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
|
+
```
|
|
217
301
|
|
|
218
302
|
---
|
|
219
303
|
|
|
@@ -237,7 +321,7 @@ const result = await lottery.BuyTickets(buyer, authority, lotteryId, amount, enc
|
|
|
237
321
|
| `amount` | `Number` | `1` | Number of tickets to purchase (1–4). |
|
|
238
322
|
| `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
|
|
239
323
|
|
|
240
|
-
**Returns:** `"finalized"` on success, or the transaction object when encoded.
|
|
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.
|
|
241
325
|
|
|
242
326
|
**Example:**
|
|
243
327
|
|
|
@@ -274,7 +358,7 @@ const result = await lottery.ClaimTicket(authority, lotteryId, winner, encoded);
|
|
|
274
358
|
| `winner` | `Keypair` | — | The keypair of the winning ticket's owner. |
|
|
275
359
|
| `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
|
|
276
360
|
|
|
277
|
-
**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.
|
|
278
362
|
|
|
279
363
|
---
|
|
280
364
|
|
|
@@ -492,7 +576,7 @@ const status = await network.Status(signature, maxRetries, intervalSeconds);
|
|
|
492
576
|
|
|
493
577
|
## Transaction Modes
|
|
494
578
|
|
|
495
|
-
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:
|
|
496
580
|
|
|
497
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.
|
|
498
582
|
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
<a name="reporting"></a>
|
|
4
|
+
## Reporting Security Problems
|
|
5
|
+
|
|
6
|
+
**DO NOT CREATE A GITHUB ISSUE** to report a security problem.
|
|
7
|
+
|
|
8
|
+
Please contact the maintainers:
|
|
9
|
+
|
|
10
|
+
X: @SolDapper
|
|
11
|
+
|
|
12
|
+
<a name="process"></a>
|
|
13
|
+
## Incident Response Process
|
|
14
|
+
|
|
15
|
+
Maintainers will respond to security incidents as fast as possible, and will keep you informed of our progress. Thank you.
|
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(
|
|
@@ -337,5 +365,49 @@ declare module "solotto" {
|
|
|
337
365
|
lotteryId: number,
|
|
338
366
|
encoded?: boolean
|
|
339
367
|
): 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>;
|
|
340
412
|
}
|
|
341
413
|
}
|
package/solotto.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {Connection, PublicKey, TransactionMessage, TransactionInstruction, VersionedTransaction, ComputeBudgetProgram, SystemProgram, Keypair, SYSVAR_SLOT_HASHES_PUBKEY,
|
|
1
|
+
import {Connection, PublicKey, TransactionMessage, TransactionInstruction, VersionedTransaction, ComputeBudgetProgram, SystemProgram, Keypair, SYSVAR_SLOT_HASHES_PUBKEY, LAMPORTS_PER_SOL} from '@solana/web3.js';
|
|
2
2
|
import bs58 from 'bs58';
|
|
3
3
|
import BN from 'bn.js';
|
|
4
4
|
import {createMemoInstruction} from '@solana/spl-memo';
|
|
5
5
|
import BufferLayout from "buffer-layout";
|
|
6
6
|
const publicKey=(property="publicKey")=>{return BufferLayout.blob(32,property);};const uint64=(property="uint64")=>{return BufferLayout.blob(8,property);}
|
|
7
|
-
import {createSolanaRpcSubscriptions} from "@solana/kit";
|
|
7
|
+
import {createSolanaRpcSubscriptions, SOLANA_ERROR__ADDRESSES__FAILED_TO_FIND_VIABLE_PDA_BUMP_SEED} from "@solana/kit";
|
|
8
8
|
import {EventEmitter} from 'events';
|
|
9
9
|
|
|
10
10
|
const INSTRUCTIONS = {
|
|
@@ -14,6 +14,7 @@ const INSTRUCTIONS = {
|
|
|
14
14
|
CLAIM_PRIZE: 3,
|
|
15
15
|
LOCK_LOTTERY: 4,
|
|
16
16
|
RELEASE_EXPIRED: 5,
|
|
17
|
+
BOOST_LOTTERY: 6,
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
class LotteryNetwork {
|
|
@@ -284,6 +285,9 @@ class Lottery extends EventEmitter {
|
|
|
284
285
|
_tx_.encode = false;
|
|
285
286
|
}
|
|
286
287
|
const tx = await network.Tx(_tx_);
|
|
288
|
+
if(tx.logs){
|
|
289
|
+
return tx.logs;
|
|
290
|
+
}
|
|
287
291
|
if(winner.secretKey && !encoded){
|
|
288
292
|
tx.transaction.sign([winner]);
|
|
289
293
|
const sig = await network.Send(tx.transaction);
|
|
@@ -321,6 +325,9 @@ class Lottery extends EventEmitter {
|
|
|
321
325
|
_tx_.encode = false;
|
|
322
326
|
}
|
|
323
327
|
const tx = await network.Tx(_tx_);
|
|
328
|
+
if(tx.logs && tx.logs.includes("Program log: Lottery is not active, no more tickets can be sold")){
|
|
329
|
+
return "Lottery is not active, no tickets can be sold";
|
|
330
|
+
}
|
|
324
331
|
if(buyer.secretKey && !encoded){
|
|
325
332
|
tx.transaction.sign([buyer]);
|
|
326
333
|
const sig = await network.Send(tx.transaction);
|
|
@@ -793,7 +800,11 @@ class LotteryManager {
|
|
|
793
800
|
_tx_.serialize = false;
|
|
794
801
|
_tx_.encode = false;
|
|
795
802
|
}
|
|
796
|
-
const tx = await network.Tx(_tx_);
|
|
803
|
+
const tx = await network.Tx(_tx_);
|
|
804
|
+
//
|
|
805
|
+
if(tx.logs && tx.logs.includes("Program log: Prize has already been claimed")){
|
|
806
|
+
return "Prize has already been claimed";
|
|
807
|
+
}
|
|
797
808
|
if(tx.status !== "ok"){return tx;}
|
|
798
809
|
if(authority.secretKey && !encoded){
|
|
799
810
|
tx.transaction.sign([authority]);
|
|
@@ -812,6 +823,137 @@ class LotteryManager {
|
|
|
812
823
|
}
|
|
813
824
|
}
|
|
814
825
|
|
|
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
|
+
|
|
815
957
|
}
|
|
816
958
|
|
|
817
959
|
export {
|