solotto 1.0.4 → 1.0.5
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 +28 -2
- package/SECURITY.md +15 -0
- package/package.json +1 -1
- package/solotto.d.ts +18 -0
- package/solotto.js +81 -3
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ 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)
|
|
22
23
|
- [Lottery](#lottery-api)
|
|
23
24
|
- [BuyTickets](#buytickets)
|
|
24
25
|
- [ClaimTicket](#claimticket)
|
|
@@ -213,7 +214,32 @@ const result = await manager.ClaimExpired(authority, lotteryId, encoded);
|
|
|
213
214
|
| `lotteryId` | `String` | — | The lottery ID. |
|
|
214
215
|
| `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
|
|
215
216
|
|
|
216
|
-
**Returns:** Updated lottery state object on finalization, or the transaction object when encoded.
|
|
217
|
+
**Returns:** Updated lottery state object on finalization, `"Prize has already been claimed"` if the prize was already claimed, or the transaction object when encoded.
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
#### Boost
|
|
222
|
+
|
|
223
|
+
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.
|
|
224
|
+
|
|
225
|
+
```js
|
|
226
|
+
// Boost lottery #1 with 0.5 SOL
|
|
227
|
+
const result = await manager.Boost(authority, lotteryId, booster, 0.5);
|
|
228
|
+
|
|
229
|
+
// Boost with a memo message
|
|
230
|
+
const result = await manager.Boost(authority, lotteryId, booster, 1.0, "Good luck everyone!");
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
| Parameter | Type | Default | Description |
|
|
234
|
+
|---|---|---|---|
|
|
235
|
+
| `authority` | `{publicKey}` | — | The lottery authority (only `publicKey` is needed). |
|
|
236
|
+
| `lotteryId` | `String` | — | The lottery ID. |
|
|
237
|
+
| `booster` | `Keypair` | — | The keypair of the wallet sending the boost. |
|
|
238
|
+
| `amount` | `Number` | — | Amount of SOL to boost (e.g. `0.5` for 0.5 SOL). |
|
|
239
|
+
| `message` | `String \| false` | `false` | Optional memo string attached to the transaction. |
|
|
240
|
+
| `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
|
|
241
|
+
|
|
242
|
+
**Returns:** `"boosted"` on success, `"Draw initiated, cannot boost this prize pool"` if the draw has already started, or the transaction object when encoded.
|
|
217
243
|
|
|
218
244
|
---
|
|
219
245
|
|
|
@@ -237,7 +263,7 @@ const result = await lottery.BuyTickets(buyer, authority, lotteryId, amount, enc
|
|
|
237
263
|
| `amount` | `Number` | `1` | Number of tickets to purchase (1–4). |
|
|
238
264
|
| `encoded` | `Boolean` | `false` | If `true`, returns encoded transaction. |
|
|
239
265
|
|
|
240
|
-
**Returns:** `"finalized"` on success, or the transaction object when encoded.
|
|
266
|
+
**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
267
|
|
|
242
268
|
**Example:**
|
|
243
269
|
|
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
|
@@ -337,5 +337,23 @@ declare module "solotto" {
|
|
|
337
337
|
lotteryId: number,
|
|
338
338
|
encoded?: boolean
|
|
339
339
|
): Promise<LotteryState | string | TxResult | undefined>;
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Boost a lottery's prize pool by transferring SOL from any wallet.
|
|
343
|
+
* @param authority - The lottery authority (only `publicKey` needed).
|
|
344
|
+
* @param lotteryId - Lottery numeric identifier.
|
|
345
|
+
* @param booster - The keypair of the wallet sending the boost.
|
|
346
|
+
* @param amount - Amount of SOL to boost (e.g. `0.5` for 0.5 SOL).
|
|
347
|
+
* @param message - Optional memo string attached to the transaction.
|
|
348
|
+
* @param encoded - If `true`, return a base64-encoded transaction.
|
|
349
|
+
*/
|
|
350
|
+
Boost(
|
|
351
|
+
authority: HasPublicKey,
|
|
352
|
+
lotteryId: number,
|
|
353
|
+
booster: Keypair,
|
|
354
|
+
amount: number,
|
|
355
|
+
message?: string | false,
|
|
356
|
+
encoded?: boolean
|
|
357
|
+
): Promise<string | TxResult | undefined>;
|
|
340
358
|
}
|
|
341
359
|
}
|
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 {
|
|
@@ -321,6 +322,9 @@ class Lottery extends EventEmitter {
|
|
|
321
322
|
_tx_.encode = false;
|
|
322
323
|
}
|
|
323
324
|
const tx = await network.Tx(_tx_);
|
|
325
|
+
if(tx.logs && tx.logs.includes("Program log: Lottery is not active, no more tickets can be sold")){
|
|
326
|
+
return "Lottery is not active, no tickets can be sold";
|
|
327
|
+
}
|
|
324
328
|
if(buyer.secretKey && !encoded){
|
|
325
329
|
tx.transaction.sign([buyer]);
|
|
326
330
|
const sig = await network.Send(tx.transaction);
|
|
@@ -793,7 +797,11 @@ class LotteryManager {
|
|
|
793
797
|
_tx_.serialize = false;
|
|
794
798
|
_tx_.encode = false;
|
|
795
799
|
}
|
|
796
|
-
const tx = await network.Tx(_tx_);
|
|
800
|
+
const tx = await network.Tx(_tx_);
|
|
801
|
+
//
|
|
802
|
+
if(tx.logs && tx.logs.includes("Program log: Prize has already been claimed")){
|
|
803
|
+
return "Prize has already been claimed";
|
|
804
|
+
}
|
|
797
805
|
if(tx.status !== "ok"){return tx;}
|
|
798
806
|
if(authority.secretKey && !encoded){
|
|
799
807
|
tx.transaction.sign([authority]);
|
|
@@ -812,6 +820,76 @@ class LotteryManager {
|
|
|
812
820
|
}
|
|
813
821
|
}
|
|
814
822
|
|
|
823
|
+
/**
|
|
824
|
+
* @param {Keypair} authority - Keypair
|
|
825
|
+
* @param {String} lotteryId - The lottery id
|
|
826
|
+
* @param {Keypair} booster - The booster's keypair
|
|
827
|
+
* @param {Number} amount - The amount of sol to boost
|
|
828
|
+
* @param {Boolean} encoded - true returns encoded transaction
|
|
829
|
+
*/
|
|
830
|
+
async Boost(authority, lotteryId, booster, amount, message = false, encoded = false) {
|
|
831
|
+
try{
|
|
832
|
+
async function boostData(lotId, amount) {
|
|
833
|
+
const lamports = parseInt(amount * LAMPORTS_PER_SOL);
|
|
834
|
+
const buffer = Buffer.alloc(17); // 1 byte discriminator + 1 bytes price + 8 bytes id
|
|
835
|
+
buffer.writeUInt8(INSTRUCTIONS.BOOST_LOTTERY, 0); // boostLottery discriminator
|
|
836
|
+
buffer.writeBigUInt64LE(BigInt(lotId), 1);
|
|
837
|
+
buffer.writeBigUInt64LE(BigInt(lamports), 9);
|
|
838
|
+
return buffer;
|
|
839
|
+
}
|
|
840
|
+
const lottery = new Lottery(this.connection, false, this.program);
|
|
841
|
+
const network = new LotteryNetwork(this.connection);
|
|
842
|
+
const [lotteryPDA] = await lottery.DeriveLotteryPDA(authority.publicKey, lotteryId);
|
|
843
|
+
const LOTTO = await lottery.GetLottery(authority, lotteryId);
|
|
844
|
+
const keys = [
|
|
845
|
+
{ pubkey: booster.publicKey, isSigner: true, isWritable: true },
|
|
846
|
+
{ pubkey: lotteryPDA, isSigner: false, isWritable: true },
|
|
847
|
+
{ pubkey: new PublicKey(LOTTO.prizePoolAddress), isSigner: false, isWritable: true },
|
|
848
|
+
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
|
|
849
|
+
];
|
|
850
|
+
const ix = new TransactionInstruction(
|
|
851
|
+
{programId: this.program, keys, data: await boostData(lotteryId, amount)}
|
|
852
|
+
);
|
|
853
|
+
const _tx_ = {};
|
|
854
|
+
_tx_.account = booster.publicKey.toString(); // string : required
|
|
855
|
+
_tx_.instructions = [ix]; // array : required
|
|
856
|
+
_tx_.signers = false; // array : default false
|
|
857
|
+
_tx_.table = false; // array : default false
|
|
858
|
+
_tx_.tolerance = 1.2; // int : default 1.1
|
|
859
|
+
_tx_.compute = true; // bool : default true
|
|
860
|
+
_tx_.fees = true; // bool : default true
|
|
861
|
+
_tx_.priority = "Low"; // string : default Low
|
|
862
|
+
_tx_.memo = message;
|
|
863
|
+
if(encoded){
|
|
864
|
+
_tx_.serialize = true;
|
|
865
|
+
_tx_.encode = true;
|
|
866
|
+
}
|
|
867
|
+
else{
|
|
868
|
+
_tx_.serialize = false;
|
|
869
|
+
_tx_.encode = false;
|
|
870
|
+
}
|
|
871
|
+
const tx = await network.Tx(_tx_);
|
|
872
|
+
if(tx.logs && tx.logs.includes("Program log: Lottery draw has been initiated, cannot boost prize pool")){
|
|
873
|
+
return "Draw initiated, cannot boost this prize pool";
|
|
874
|
+
}
|
|
875
|
+
if(tx.status !== "ok"){return tx;}
|
|
876
|
+
if(booster.secretKey && !encoded){
|
|
877
|
+
tx.transaction.sign([booster]);
|
|
878
|
+
const sig = await network.Send(tx.transaction);
|
|
879
|
+
console.log("Signature:", sig);
|
|
880
|
+
const status = await network.Status(sig);
|
|
881
|
+
if(status == "finalized"){
|
|
882
|
+
return "boosted";
|
|
883
|
+
}
|
|
884
|
+
else{return status;}
|
|
885
|
+
}
|
|
886
|
+
else{return tx;}
|
|
887
|
+
}
|
|
888
|
+
catch (error) {
|
|
889
|
+
console.log(error);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
|
|
815
893
|
}
|
|
816
894
|
|
|
817
895
|
export {
|