@slvr-labs/sdk 0.1.0 → 0.1.2
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 +42 -0
- package/dist/index.d.mts +2117 -0
- package/dist/index.d.ts +1903 -34
- package/dist/index.js +3091 -427
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3035 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +19 -11
- package/skills/slvr-bot/SKILL.md +9 -8
- package/skills/slvr-bot/references/api.md +8 -0
- package/dist/connect.d.ts +0 -47
- package/dist/connect.d.ts.map +0 -1
- package/dist/connect.js +0 -56
- package/dist/connect.js.map +0 -1
- package/dist/contracts/autoCommit.d.ts +0 -151
- package/dist/contracts/autoCommit.d.ts.map +0 -1
- package/dist/contracts/autoCommit.js +0 -426
- package/dist/contracts/autoCommit.js.map +0 -1
- package/dist/contracts/hub.d.ts +0 -50
- package/dist/contracts/hub.d.ts.map +0 -1
- package/dist/contracts/hub.js +0 -118
- package/dist/contracts/hub.js.map +0 -1
- package/dist/contracts/index.d.ts +0 -8
- package/dist/contracts/index.d.ts.map +0 -1
- package/dist/contracts/index.js +0 -18
- package/dist/contracts/index.js.map +0 -1
- package/dist/contracts/jackpot.d.ts +0 -21
- package/dist/contracts/jackpot.d.ts.map +0 -1
- package/dist/contracts/jackpot.js +0 -44
- package/dist/contracts/jackpot.js.map +0 -1
- package/dist/contracts/lottery.d.ts +0 -256
- package/dist/contracts/lottery.d.ts.map +0 -1
- package/dist/contracts/lottery.js +0 -767
- package/dist/contracts/lottery.js.map +0 -1
- package/dist/contracts/registry.d.ts +0 -53
- package/dist/contracts/registry.d.ts.map +0 -1
- package/dist/contracts/registry.js +0 -143
- package/dist/contracts/registry.js.map +0 -1
- package/dist/contracts/staking.d.ts +0 -101
- package/dist/contracts/staking.d.ts.map +0 -1
- package/dist/contracts/staking.js +0 -306
- package/dist/contracts/staking.js.map +0 -1
- package/dist/contracts/token.d.ts +0 -95
- package/dist/contracts/token.d.ts.map +0 -1
- package/dist/contracts/token.js +0 -273
- package/dist/contracts/token.js.map +0 -1
- package/dist/deployments.d.ts +0 -117
- package/dist/deployments.d.ts.map +0 -1
- package/dist/deployments.js +0 -74
- package/dist/deployments.js.map +0 -1
- package/dist/errors.d.ts +0 -39
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -67
- package/dist/errors.js.map +0 -1
- package/dist/ev.d.ts +0 -123
- package/dist/ev.d.ts.map +0 -1
- package/dist/ev.js +0 -111
- package/dist/ev.js.map +0 -1
- package/dist/events.d.ts +0 -418
- package/dist/events.d.ts.map +0 -1
- package/dist/events.js +0 -87
- package/dist/events.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/oracle.d.ts +0 -48
- package/dist/oracle.d.ts.map +0 -1
- package/dist/oracle.js +0 -77
- package/dist/oracle.js.map +0 -1
- package/dist/price.d.ts +0 -52
- package/dist/price.d.ts.map +0 -1
- package/dist/price.js +0 -78
- package/dist/price.js.map +0 -1
- package/dist/transaction.d.ts +0 -54
- package/dist/transaction.d.ts.map +0 -1
- package/dist/transaction.js +0 -105
- package/dist/transaction.js.map +0 -1
- package/dist/types.d.ts +0 -162
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -23
- package/dist/types.js.map +0 -1
- package/dist/utils.d.ts +0 -58
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -110
- package/dist/utils.js.map +0 -1
|
@@ -1,767 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SlvrGridLottery = void 0;
|
|
4
|
-
const viem_1 = require("viem");
|
|
5
|
-
const errors_1 = require("../errors");
|
|
6
|
-
const utils_1 = require("../utils");
|
|
7
|
-
const events_1 = require("../events");
|
|
8
|
-
/**
|
|
9
|
-
* SlvrGridLottery contract interface
|
|
10
|
-
*/
|
|
11
|
-
class SlvrGridLottery {
|
|
12
|
-
constructor(publicClient, walletClient, address) {
|
|
13
|
-
this.publicClient = publicClient;
|
|
14
|
-
this.walletClient = walletClient;
|
|
15
|
-
this.address = address;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Update the wallet client
|
|
19
|
-
* @param walletClient New wallet client
|
|
20
|
-
*/
|
|
21
|
-
setWalletClient(walletClient) {
|
|
22
|
-
this.walletClient = walletClient;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Get the current round ID
|
|
26
|
-
*/
|
|
27
|
-
async currentRoundId() {
|
|
28
|
-
return await this.publicClient.readContract({
|
|
29
|
-
address: this.address,
|
|
30
|
-
abi: SlvrGridLottery.ABI,
|
|
31
|
-
functionName: 'currentRoundId',
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Get round start time
|
|
36
|
-
*/
|
|
37
|
-
async roundStart(roundId) {
|
|
38
|
-
return await this.publicClient.readContract({
|
|
39
|
-
address: this.address,
|
|
40
|
-
abi: SlvrGridLottery.ABI,
|
|
41
|
-
functionName: 'roundStart',
|
|
42
|
-
args: [roundId],
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Get round end time
|
|
47
|
-
*/
|
|
48
|
-
async roundEnd(roundId) {
|
|
49
|
-
return await this.publicClient.readContract({
|
|
50
|
-
address: this.address,
|
|
51
|
-
abi: SlvrGridLottery.ABI,
|
|
52
|
-
functionName: 'roundEnd',
|
|
53
|
-
args: [roundId],
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Check if round is open for betting
|
|
58
|
-
*/
|
|
59
|
-
async roundOpen(roundId) {
|
|
60
|
-
return await this.publicClient.readContract({
|
|
61
|
-
address: this.address,
|
|
62
|
-
abi: SlvrGridLottery.ABI,
|
|
63
|
-
functionName: 'roundOpen',
|
|
64
|
-
args: [roundId],
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Get the betting cutoff timestamp (unix seconds) for a round.
|
|
69
|
-
*
|
|
70
|
-
* Bets are only accepted until this time, which can be earlier than
|
|
71
|
-
* {@link roundEnd}. Bots deciding whether they can still bet should gate on
|
|
72
|
-
* this rather than on `roundEnd`.
|
|
73
|
-
*/
|
|
74
|
-
async bettingEnd(roundId) {
|
|
75
|
-
return await this.publicClient.readContract({
|
|
76
|
-
address: this.address,
|
|
77
|
-
abi: SlvrGridLottery.ABI,
|
|
78
|
-
functionName: 'bettingEnd',
|
|
79
|
-
args: [roundId],
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Estimate the reward an account would receive for a round, in wei.
|
|
84
|
-
*
|
|
85
|
-
* Thin pass-through to the contract's `getExpectedReward`. Useful for sizing
|
|
86
|
-
* bets or deciding whether a claim is worth the gas.
|
|
87
|
-
*/
|
|
88
|
-
async getExpectedReward(account, roundId) {
|
|
89
|
-
return await this.publicClient.readContract({
|
|
90
|
-
address: this.address,
|
|
91
|
-
abi: SlvrGridLottery.ABI,
|
|
92
|
-
functionName: 'getExpectedReward',
|
|
93
|
-
args: [account, roundId],
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Get the latest resolved round ID (type(uint256).max sentinel when none resolved yet)
|
|
98
|
-
*/
|
|
99
|
-
async latestResolvedRoundId() {
|
|
100
|
-
return await this.publicClient.readContract({
|
|
101
|
-
address: this.address,
|
|
102
|
-
abi: SlvrGridLottery.ABI,
|
|
103
|
-
functionName: 'latestResolvedRoundId',
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Get full round information
|
|
108
|
-
*/
|
|
109
|
-
async getRound(roundId) {
|
|
110
|
-
const result = await this.publicClient.readContract({
|
|
111
|
-
address: this.address,
|
|
112
|
-
abi: SlvrGridLottery.ABI,
|
|
113
|
-
functionName: 'getRound',
|
|
114
|
-
args: [roundId],
|
|
115
|
-
});
|
|
116
|
-
return {
|
|
117
|
-
roundId,
|
|
118
|
-
requestedAt: result[0],
|
|
119
|
-
resolved: result[1],
|
|
120
|
-
randomnessId: result[2],
|
|
121
|
-
randomnessValue: result[3],
|
|
122
|
-
winningSquare: Number(result[4]),
|
|
123
|
-
jackpotHit: result[5],
|
|
124
|
-
singleMinerRound: result[6],
|
|
125
|
-
singleMinerWinner: result[7],
|
|
126
|
-
totalWager: result[8],
|
|
127
|
-
fee: result[9],
|
|
128
|
-
winnerTotal: result[10],
|
|
129
|
-
potForWinners: result[11],
|
|
130
|
-
slvrForWinners: result[12],
|
|
131
|
-
payoutMulWad: result[13],
|
|
132
|
-
slvrMulWad: result[14],
|
|
133
|
-
totalUnclaimedSlvr: result[15],
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Get total amount bet on a square for a round
|
|
138
|
-
*/
|
|
139
|
-
async getTotalOnSquare(roundId, square) {
|
|
140
|
-
return await this.publicClient.readContract({
|
|
141
|
-
address: this.address,
|
|
142
|
-
abi: SlvrGridLottery.ABI,
|
|
143
|
-
functionName: 'getTotalOnSquare',
|
|
144
|
-
args: [roundId, square],
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Get number of bettors on a square for a round
|
|
149
|
-
*/
|
|
150
|
-
async getBettorsOnSquare(roundId, square) {
|
|
151
|
-
return await this.publicClient.readContract({
|
|
152
|
-
address: this.address,
|
|
153
|
-
abi: SlvrGridLottery.ABI,
|
|
154
|
-
functionName: 'getBettorsOnSquare',
|
|
155
|
-
args: [roundId, square],
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Get a user's bet amount on a square for a round
|
|
160
|
-
*/
|
|
161
|
-
async getUserBet(roundId, square, bettor) {
|
|
162
|
-
return await this.publicClient.readContract({
|
|
163
|
-
address: this.address,
|
|
164
|
-
abi: SlvrGridLottery.ABI,
|
|
165
|
-
functionName: 'getUserBet',
|
|
166
|
-
args: [roundId, square, bettor],
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Check if a user has claimed rewards for a round
|
|
171
|
-
*/
|
|
172
|
-
async getHasClaimed(roundId, user) {
|
|
173
|
-
return await this.publicClient.readContract({
|
|
174
|
-
address: this.address,
|
|
175
|
-
abi: SlvrGridLottery.ABI,
|
|
176
|
-
functionName: 'getHasClaimed',
|
|
177
|
-
args: [roundId, user],
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Get miner state for an account
|
|
182
|
-
*/
|
|
183
|
-
async getMinerState(account) {
|
|
184
|
-
const result = await this.publicClient.readContract({
|
|
185
|
-
address: this.address,
|
|
186
|
-
abi: SlvrGridLottery.ABI,
|
|
187
|
-
functionName: 'getMinerState',
|
|
188
|
-
args: [account],
|
|
189
|
-
});
|
|
190
|
-
return {
|
|
191
|
-
rewardsSlvr: result[0],
|
|
192
|
-
refinedAccrued: result[1],
|
|
193
|
-
indexSnapshot: result[2],
|
|
194
|
-
hasAccount: result[3],
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Check if an account exists
|
|
199
|
-
*/
|
|
200
|
-
async hasAccount(account) {
|
|
201
|
-
return await this.publicClient.readContract({
|
|
202
|
-
address: this.address,
|
|
203
|
-
abi: SlvrGridLottery.ABI,
|
|
204
|
-
functionName: 'getHasAccount',
|
|
205
|
-
args: [account],
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Get carry-over winner native pool (when no winners)
|
|
210
|
-
*/
|
|
211
|
-
async carryWinnerNativePool() {
|
|
212
|
-
return await this.publicClient.readContract({
|
|
213
|
-
address: this.address,
|
|
214
|
-
abi: SlvrGridLottery.ABI,
|
|
215
|
-
functionName: 'carryWinnerNativePool',
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Get staker rewards that failed to distribute (owed)
|
|
220
|
-
*/
|
|
221
|
-
async carryStakerNativeOwed() {
|
|
222
|
-
return await this.publicClient.readContract({
|
|
223
|
-
address: this.address,
|
|
224
|
-
abi: SlvrGridLottery.ABI,
|
|
225
|
-
functionName: 'carryStakerNativeOwed',
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Get jackpot funds that failed to add (owed)
|
|
230
|
-
*/
|
|
231
|
-
async carryJackpotNativeOwed() {
|
|
232
|
-
return await this.publicClient.readContract({
|
|
233
|
-
address: this.address,
|
|
234
|
-
abi: SlvrGridLottery.ABI,
|
|
235
|
-
functionName: 'carryJackpotNativeOwed',
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* Get carry-over SLVR pool
|
|
240
|
-
*/
|
|
241
|
-
async carrySlvrPool() {
|
|
242
|
-
return await this.publicClient.readContract({
|
|
243
|
-
address: this.address,
|
|
244
|
-
abi: SlvrGridLottery.ABI,
|
|
245
|
-
functionName: 'carrySlvrPool',
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Get the configured SLVR-per-round value.
|
|
250
|
-
*
|
|
251
|
-
* NOTE: This is no longer the authoritative emission number. Emission is hub-gated: the amount
|
|
252
|
-
* actually minted each round is bounded by the game's streamed emission budget on SlvrHub
|
|
253
|
-
* (see SlvrHub.pendingEmission / mintReward). Treat this only as the requested/target value.
|
|
254
|
-
*/
|
|
255
|
-
async slvrPerRound() {
|
|
256
|
-
return await this.publicClient.readContract({
|
|
257
|
-
address: this.address,
|
|
258
|
-
abi: SlvrGridLottery.ABI,
|
|
259
|
-
functionName: 'slvrPerRound',
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Get protocol fee in basis points
|
|
264
|
-
*/
|
|
265
|
-
async protocolFeeBps() {
|
|
266
|
-
return await this.publicClient.readContract({
|
|
267
|
-
address: this.address,
|
|
268
|
-
abi: SlvrGridLottery.ABI,
|
|
269
|
-
functionName: 'protocolFeeBps',
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
|
-
/**
|
|
273
|
-
* Get grid size (should be 25)
|
|
274
|
-
*/
|
|
275
|
-
async grid() {
|
|
276
|
-
return await this.publicClient.readContract({
|
|
277
|
-
address: this.address,
|
|
278
|
-
abi: SlvrGridLottery.ABI,
|
|
279
|
-
functionName: 'GRID',
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Get account deposit amount
|
|
284
|
-
*/
|
|
285
|
-
async accountDeposit() {
|
|
286
|
-
return await this.publicClient.readContract({
|
|
287
|
-
address: this.address,
|
|
288
|
-
abi: SlvrGridLottery.ABI,
|
|
289
|
-
functionName: 'ACCOUNT_DEPOSIT',
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
/**
|
|
293
|
-
* Place a bet on the current round
|
|
294
|
-
* Note: The contract will automatically handle account deposit for new accounts.
|
|
295
|
-
* If the beneficiary is a new account, ensure msg.value >= ACCOUNT_DEPOSIT + total bet amount.
|
|
296
|
-
* @param params Bet parameters
|
|
297
|
-
* @returns Transaction hash
|
|
298
|
-
* @throws WalletClientRequiredError if wallet client is not available
|
|
299
|
-
* @throws ValidationError if inputs are invalid
|
|
300
|
-
* @throws ContractCallError if contract call fails
|
|
301
|
-
*/
|
|
302
|
-
async bet(params) {
|
|
303
|
-
if (!this.walletClient) {
|
|
304
|
-
throw new errors_1.WalletClientRequiredError('betting');
|
|
305
|
-
}
|
|
306
|
-
const { roundId, squares, amounts, beneficiary } = params;
|
|
307
|
-
// Validate inputs
|
|
308
|
-
if (roundId < 0n) {
|
|
309
|
-
throw new errors_1.ContractCallError('Round ID must be non-negative');
|
|
310
|
-
}
|
|
311
|
-
(0, utils_1.validateSquares)(squares);
|
|
312
|
-
(0, utils_1.validateArrayLengths)([squares, amounts], ['squares', 'amounts']);
|
|
313
|
-
for (const amount of amounts) {
|
|
314
|
-
(0, utils_1.validateAmount)(amount, 'bet amount');
|
|
315
|
-
}
|
|
316
|
-
const totalAmount = amounts.reduce((sum, amt) => sum + amt, 0n);
|
|
317
|
-
try {
|
|
318
|
-
// Check if account exists, if not, add account deposit to the value sent
|
|
319
|
-
const beneficiaryAddress = beneficiary
|
|
320
|
-
? (0, utils_1.validateAddress)(beneficiary, 'beneficiary')
|
|
321
|
-
: this.walletClient.account.address;
|
|
322
|
-
const hasAccount_ = await this.hasAccount(beneficiaryAddress);
|
|
323
|
-
const accountDeposit_ = hasAccount_ ? 0n : await this.accountDeposit();
|
|
324
|
-
const totalValue = totalAmount + accountDeposit_;
|
|
325
|
-
if (beneficiary) {
|
|
326
|
-
return await this.walletClient.writeContract({
|
|
327
|
-
address: this.address,
|
|
328
|
-
abi: SlvrGridLottery.ABI,
|
|
329
|
-
functionName: 'betFor',
|
|
330
|
-
args: [roundId, beneficiaryAddress, squares, amounts],
|
|
331
|
-
value: totalValue,
|
|
332
|
-
account: this.walletClient.account,
|
|
333
|
-
chain: null,
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
else {
|
|
337
|
-
return await this.walletClient.writeContract({
|
|
338
|
-
address: this.address,
|
|
339
|
-
abi: SlvrGridLottery.ABI,
|
|
340
|
-
functionName: 'bet',
|
|
341
|
-
args: [roundId, squares, amounts],
|
|
342
|
-
value: totalValue,
|
|
343
|
-
account: this.walletClient.account,
|
|
344
|
-
chain: null,
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
catch (error) {
|
|
349
|
-
if (error instanceof errors_1.WalletClientRequiredError || error instanceof errors_1.ContractCallError) {
|
|
350
|
-
throw error;
|
|
351
|
-
}
|
|
352
|
-
throw new errors_1.ContractCallError(`Failed to place bet: ${error instanceof Error ? error.message : String(error)}`, error);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Claim rewards for a round
|
|
357
|
-
* @param params Claim parameters
|
|
358
|
-
* @returns Transaction hash
|
|
359
|
-
* @throws WalletClientRequiredError if wallet client is not available
|
|
360
|
-
* @throws ValidationError if inputs are invalid
|
|
361
|
-
* @throws ContractCallError if contract call fails
|
|
362
|
-
*/
|
|
363
|
-
async claim(params) {
|
|
364
|
-
if (!this.walletClient) {
|
|
365
|
-
throw new errors_1.WalletClientRequiredError('claiming');
|
|
366
|
-
}
|
|
367
|
-
if (params.roundId < 0n) {
|
|
368
|
-
throw new errors_1.ContractCallError('Round ID must be non-negative');
|
|
369
|
-
}
|
|
370
|
-
try {
|
|
371
|
-
return await this.walletClient.writeContract({
|
|
372
|
-
address: this.address,
|
|
373
|
-
abi: SlvrGridLottery.ABI,
|
|
374
|
-
functionName: 'claim',
|
|
375
|
-
args: [params.roundId],
|
|
376
|
-
account: this.walletClient.account,
|
|
377
|
-
chain: null,
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
catch (error) {
|
|
381
|
-
if (error instanceof errors_1.WalletClientRequiredError || error instanceof errors_1.ContractCallError) {
|
|
382
|
-
throw error;
|
|
383
|
-
}
|
|
384
|
-
throw new errors_1.ContractCallError(`Failed to claim rewards: ${error instanceof Error ? error.message : String(error)}`, error);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* Advanced claim function covering all claim variants
|
|
389
|
-
* Handles: user vs delegate, native/SLVR recipients, bypassFee, ethOnly
|
|
390
|
-
* @param params Advanced claim parameters
|
|
391
|
-
* @returns Transaction hash
|
|
392
|
-
* @throws WalletClientRequiredError if wallet client is not available
|
|
393
|
-
* @throws ValidationError if inputs are invalid
|
|
394
|
-
* @throws ContractCallError if contract call fails
|
|
395
|
-
*/
|
|
396
|
-
async claimAdvanced(params) {
|
|
397
|
-
if (!this.walletClient) {
|
|
398
|
-
throw new errors_1.WalletClientRequiredError('claiming');
|
|
399
|
-
}
|
|
400
|
-
if (params.roundId < 0n) {
|
|
401
|
-
throw new errors_1.ContractCallError('Round ID must be non-negative');
|
|
402
|
-
}
|
|
403
|
-
const user = (0, utils_1.validateAddress)(params.user, 'user');
|
|
404
|
-
const recipientNative = params.recipientNative
|
|
405
|
-
? (0, utils_1.validateAddress)(params.recipientNative, 'recipientNative')
|
|
406
|
-
: '0x0000000000000000000000000000000000000000';
|
|
407
|
-
const recipientSlvr = params.recipientSlvr
|
|
408
|
-
? (0, utils_1.validateAddress)(params.recipientSlvr, 'recipientSlvr')
|
|
409
|
-
: '0x0000000000000000000000000000000000000000';
|
|
410
|
-
try {
|
|
411
|
-
return await this.walletClient.writeContract({
|
|
412
|
-
address: this.address,
|
|
413
|
-
abi: SlvrGridLottery.ABI,
|
|
414
|
-
functionName: 'claimAdvanced',
|
|
415
|
-
args: [{
|
|
416
|
-
user,
|
|
417
|
-
roundId: params.roundId,
|
|
418
|
-
recipientNative,
|
|
419
|
-
recipientSlvr,
|
|
420
|
-
bypassFee: params.bypassFee || false,
|
|
421
|
-
ethOnly: params.ethOnly || false,
|
|
422
|
-
}],
|
|
423
|
-
account: this.walletClient.account,
|
|
424
|
-
chain: null,
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
catch (error) {
|
|
428
|
-
if (error instanceof errors_1.WalletClientRequiredError || error instanceof errors_1.ContractCallError) {
|
|
429
|
-
throw error;
|
|
430
|
-
}
|
|
431
|
-
throw new errors_1.ContractCallError(`Failed to claim rewards: ${error instanceof Error ? error.message : String(error)}`, error);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
* Batch claim rewards for multiple rounds
|
|
436
|
-
* Note: This sends multiple transactions sequentially. For better UX, consider
|
|
437
|
-
* using a multicall contract or batching in your application layer.
|
|
438
|
-
* @param roundIds Array of round IDs to claim
|
|
439
|
-
* @param user User address to claim for (defaults to wallet client account)
|
|
440
|
-
* @param options Optional configuration
|
|
441
|
-
* @param options.waitForReceipt Whether to wait for each transaction receipt (default: false)
|
|
442
|
-
* @returns Array of transaction hashes
|
|
443
|
-
* @throws WalletClientRequiredError if wallet client is not available
|
|
444
|
-
* @throws ValidationError if inputs are invalid
|
|
445
|
-
* @throws ContractCallError if contract call fails
|
|
446
|
-
*/
|
|
447
|
-
async batchClaim(roundIds, user, options) {
|
|
448
|
-
if (!this.walletClient) {
|
|
449
|
-
throw new errors_1.WalletClientRequiredError('batch claiming');
|
|
450
|
-
}
|
|
451
|
-
if (roundIds.length === 0) {
|
|
452
|
-
throw new errors_1.ContractCallError('No rounds to claim');
|
|
453
|
-
}
|
|
454
|
-
const claimUser = user ? (0, utils_1.validateAddress)(user, 'user') : this.walletClient.account.address;
|
|
455
|
-
const hashes = [];
|
|
456
|
-
for (const roundId of roundIds) {
|
|
457
|
-
if (roundId < 0n) {
|
|
458
|
-
throw new errors_1.ContractCallError(`Invalid round ID: ${roundId}`);
|
|
459
|
-
}
|
|
460
|
-
try {
|
|
461
|
-
const hash = await this.claimAdvanced({
|
|
462
|
-
user: claimUser,
|
|
463
|
-
roundId,
|
|
464
|
-
});
|
|
465
|
-
hashes.push(hash);
|
|
466
|
-
// Optionally wait for receipt before proceeding
|
|
467
|
-
if (options?.waitForReceipt) {
|
|
468
|
-
await (0, utils_1.waitForTransactionReceipt)(this.publicClient, hash);
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
catch (error) {
|
|
472
|
-
// If one claim fails, we still return the hashes we've collected so far
|
|
473
|
-
// The caller can decide how to handle partial failures
|
|
474
|
-
throw new errors_1.ContractCallError(`Failed to claim round ${roundId}: ${error instanceof Error ? error.message : String(error)}`, error);
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
return hashes;
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* Approve a delegate to claim rewards on your behalf
|
|
481
|
-
*/
|
|
482
|
-
async approveDelegate(delegate) {
|
|
483
|
-
if (!this.walletClient) {
|
|
484
|
-
throw new errors_1.WalletClientRequiredError('approving delegate');
|
|
485
|
-
}
|
|
486
|
-
const delegateAddress = (0, utils_1.validateAddress)(delegate, 'delegate');
|
|
487
|
-
return await this.walletClient.writeContract({
|
|
488
|
-
address: this.address,
|
|
489
|
-
abi: SlvrGridLottery.ABI,
|
|
490
|
-
functionName: 'approveDelegate',
|
|
491
|
-
args: [delegateAddress],
|
|
492
|
-
account: this.walletClient.account,
|
|
493
|
-
chain: null,
|
|
494
|
-
});
|
|
495
|
-
}
|
|
496
|
-
/**
|
|
497
|
-
* Revoke a delegate's approval to claim on your behalf
|
|
498
|
-
*/
|
|
499
|
-
async revokeDelegate(delegate) {
|
|
500
|
-
if (!this.walletClient) {
|
|
501
|
-
throw new errors_1.WalletClientRequiredError('revoking delegate');
|
|
502
|
-
}
|
|
503
|
-
const delegateAddress = (0, utils_1.validateAddress)(delegate, 'delegate');
|
|
504
|
-
return await this.walletClient.writeContract({
|
|
505
|
-
address: this.address,
|
|
506
|
-
abi: SlvrGridLottery.ABI,
|
|
507
|
-
functionName: 'revokeDelegate',
|
|
508
|
-
args: [delegateAddress],
|
|
509
|
-
account: this.walletClient.account,
|
|
510
|
-
chain: null,
|
|
511
|
-
});
|
|
512
|
-
}
|
|
513
|
-
/**
|
|
514
|
-
* Check if a delegate is approved for a user
|
|
515
|
-
*/
|
|
516
|
-
async getDelegate(user, delegate) {
|
|
517
|
-
return await this.publicClient.readContract({
|
|
518
|
-
address: this.address,
|
|
519
|
-
abi: SlvrGridLottery.ABI,
|
|
520
|
-
functionName: 'getDelegate',
|
|
521
|
-
args: [user, delegate],
|
|
522
|
-
});
|
|
523
|
-
}
|
|
524
|
-
/**
|
|
525
|
-
* Donate SLVR tokens directly to the jackpot pool.
|
|
526
|
-
* Note: caller must have approved the lottery to spend `amount` of SLVR beforehand.
|
|
527
|
-
*/
|
|
528
|
-
async donateSlvrToJackpot(amount) {
|
|
529
|
-
if (!this.walletClient) {
|
|
530
|
-
throw new errors_1.WalletClientRequiredError('donating to jackpot');
|
|
531
|
-
}
|
|
532
|
-
(0, utils_1.validateAmount)(amount, 'donation amount');
|
|
533
|
-
return await this.walletClient.writeContract({
|
|
534
|
-
address: this.address,
|
|
535
|
-
abi: SlvrGridLottery.ABI,
|
|
536
|
-
functionName: 'donateSlvrToJackpot',
|
|
537
|
-
args: [amount],
|
|
538
|
-
account: this.walletClient.account,
|
|
539
|
-
chain: null,
|
|
540
|
-
});
|
|
541
|
-
}
|
|
542
|
-
/**
|
|
543
|
-
* Add ETH (native) tokens to the jackpot pool
|
|
544
|
-
* @param value Amount of native ETH to deposit
|
|
545
|
-
*/
|
|
546
|
-
async addEthToJackpot(value) {
|
|
547
|
-
if (!this.walletClient) {
|
|
548
|
-
throw new errors_1.WalletClientRequiredError('adding ETH to jackpot');
|
|
549
|
-
}
|
|
550
|
-
(0, utils_1.validateAmount)(value, 'jackpot amount');
|
|
551
|
-
return await this.walletClient.writeContract({
|
|
552
|
-
address: this.address,
|
|
553
|
-
abi: SlvrGridLottery.ABI,
|
|
554
|
-
functionName: 'addEthToJackpot',
|
|
555
|
-
value,
|
|
556
|
-
account: this.walletClient.account,
|
|
557
|
-
chain: null,
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
/**
|
|
561
|
-
* Withdraw your accumulated mined SLVR (the "refine and cash out" path).
|
|
562
|
-
*
|
|
563
|
-
* Settles your miner accrual (auto-checkpoints) and transfers your SLVR out,
|
|
564
|
-
* net of the refining fee. This is the function a mining bot wants to realize
|
|
565
|
-
* SLVR rewards outside of a specific round claim. Reverts if you have nothing to
|
|
566
|
-
* withdraw. The exact `(totalPayout, refiningFee)` are in the emitted `Claimed`
|
|
567
|
-
* event; this returns the transaction hash.
|
|
568
|
-
*/
|
|
569
|
-
async withdrawUnrefinedSlvr() {
|
|
570
|
-
if (!this.walletClient) {
|
|
571
|
-
throw new errors_1.WalletClientRequiredError('withdrawing unrefined SLVR');
|
|
572
|
-
}
|
|
573
|
-
return await this.walletClient.writeContract({
|
|
574
|
-
address: this.address,
|
|
575
|
-
abi: SlvrGridLottery.ABI,
|
|
576
|
-
functionName: 'withdrawUnrefinedSlvr',
|
|
577
|
-
account: this.walletClient.account,
|
|
578
|
-
chain: null,
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
|
-
/**
|
|
582
|
-
* Force on-chain settlement of a miner's refined-reward accrual (lazy
|
|
583
|
-
* "checkpoint"). Permissionless — you can checkpoint any account.
|
|
584
|
-
*
|
|
585
|
-
* This only updates accounting (rolls index growth into `refinedAccrued`); it
|
|
586
|
-
* moves no tokens. You rarely need it: `claim` and {@link withdrawUnrefinedSlvr}
|
|
587
|
-
* both checkpoint internally, and the up-to-date figure can be derived off-chain
|
|
588
|
-
* from {@link getMinerState}. Use it when you want state settled without a
|
|
589
|
-
* claim/withdraw — e.g. to make a subsequent `getMinerState` read exact.
|
|
590
|
-
*/
|
|
591
|
-
async checkpoint(account) {
|
|
592
|
-
if (!this.walletClient) {
|
|
593
|
-
throw new errors_1.WalletClientRequiredError('checkpointing');
|
|
594
|
-
}
|
|
595
|
-
return await this.walletClient.writeContract({
|
|
596
|
-
address: this.address,
|
|
597
|
-
abi: SlvrGridLottery.ABI,
|
|
598
|
-
functionName: 'checkpoint',
|
|
599
|
-
args: [account],
|
|
600
|
-
account: this.walletClient.account,
|
|
601
|
-
chain: null,
|
|
602
|
-
});
|
|
603
|
-
}
|
|
604
|
-
/**
|
|
605
|
-
* Get all square data for a round
|
|
606
|
-
*/
|
|
607
|
-
async getRoundSquares(roundId) {
|
|
608
|
-
const gridSize = await this.grid();
|
|
609
|
-
const squares = Array.from({ length: gridSize }, (_, i) => i);
|
|
610
|
-
// Fast path: batch all 2×gridSize reads into a single multicall. Requires the
|
|
611
|
-
// client's chain to know Multicall3 (robinhoodChain registers it). Falls back
|
|
612
|
-
// to parallel individual reads on any chain/client without it.
|
|
613
|
-
try {
|
|
614
|
-
const contracts = squares.flatMap((sq) => [
|
|
615
|
-
{ address: this.address, abi: SlvrGridLottery.ABI, functionName: 'getTotalOnSquare', args: [roundId, sq] },
|
|
616
|
-
{ address: this.address, abi: SlvrGridLottery.ABI, functionName: 'getBettorsOnSquare', args: [roundId, sq] },
|
|
617
|
-
]);
|
|
618
|
-
const res = (await this.publicClient.multicall({
|
|
619
|
-
contracts: contracts,
|
|
620
|
-
allowFailure: false,
|
|
621
|
-
}));
|
|
622
|
-
return squares.map((square, i) => ({ square, total: res[i * 2], bettors: res[i * 2 + 1] }));
|
|
623
|
-
}
|
|
624
|
-
catch {
|
|
625
|
-
const [totals, bettors] = await Promise.all([
|
|
626
|
-
Promise.all(squares.map((sq) => this.getTotalOnSquare(roundId, sq))),
|
|
627
|
-
Promise.all(squares.map((sq) => this.getBettorsOnSquare(roundId, sq))),
|
|
628
|
-
]);
|
|
629
|
-
return squares.map((square, i) => ({ square, total: totals[i], bettors: bettors[i] }));
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
/**
|
|
633
|
-
* Get user's bets for a round
|
|
634
|
-
*/
|
|
635
|
-
async getUserBets(roundId, user) {
|
|
636
|
-
const gridSize = await this.grid();
|
|
637
|
-
const squares = Array.from({ length: gridSize }, (_, i) => i);
|
|
638
|
-
// Batch via multicall when available; fall back to parallel reads otherwise.
|
|
639
|
-
let bets;
|
|
640
|
-
try {
|
|
641
|
-
const contracts = squares.map((sq) => ({
|
|
642
|
-
address: this.address,
|
|
643
|
-
abi: SlvrGridLottery.ABI,
|
|
644
|
-
functionName: 'getUserBet',
|
|
645
|
-
args: [roundId, sq, user],
|
|
646
|
-
}));
|
|
647
|
-
bets = (await this.publicClient.multicall({ contracts: contracts, allowFailure: false }));
|
|
648
|
-
}
|
|
649
|
-
catch {
|
|
650
|
-
bets = await Promise.all(squares.map((sq) => this.getUserBet(roundId, sq, user)));
|
|
651
|
-
}
|
|
652
|
-
return squares
|
|
653
|
-
.map((square, i) => ({ square, amount: bets[i] }))
|
|
654
|
-
.filter((bet) => bet.amount > 0n);
|
|
655
|
-
}
|
|
656
|
-
// ---------------------------------------------------------------------------
|
|
657
|
-
// Reactive helpers
|
|
658
|
-
// ---------------------------------------------------------------------------
|
|
659
|
-
/**
|
|
660
|
-
* Wait until a round is resolved, resolving with its final {@link RoundInfo}.
|
|
661
|
-
* Polls `getRound` on an interval — handy for "bet, then claim once it settles".
|
|
662
|
-
*
|
|
663
|
-
* @param opts.pollIntervalMs how often to check (default 4000)
|
|
664
|
-
* @param opts.timeoutMs give up after this long (default: wait indefinitely)
|
|
665
|
-
* @throws {Error} if `timeoutMs` elapses before resolution
|
|
666
|
-
*/
|
|
667
|
-
async waitForResolution(roundId, opts = {}) {
|
|
668
|
-
const interval = opts.pollIntervalMs ?? 4000;
|
|
669
|
-
const deadline = opts.timeoutMs !== undefined ? Date.now() + opts.timeoutMs : Infinity;
|
|
670
|
-
for (;;) {
|
|
671
|
-
const round = await this.getRound(roundId);
|
|
672
|
-
if (round.resolved)
|
|
673
|
-
return round;
|
|
674
|
-
if (Date.now() >= deadline)
|
|
675
|
-
throw new Error(`round ${roundId} not resolved within ${opts.timeoutMs}ms`);
|
|
676
|
-
await new Promise((r) => setTimeout(r, interval));
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
/**
|
|
680
|
-
* Subscribe to `RoundResolved` events. Returns an unsubscribe function.
|
|
681
|
-
*
|
|
682
|
-
* @example
|
|
683
|
-
* ```typescript
|
|
684
|
-
* const stop = sdk.lottery.watchRoundResolved((e) => {
|
|
685
|
-
* console.log(`round ${e.roundId} won by square ${e.winningSquare}`);
|
|
686
|
-
* });
|
|
687
|
-
* // later: stop();
|
|
688
|
-
* ```
|
|
689
|
-
*/
|
|
690
|
-
watchRoundResolved(onResolved, opts = {}) {
|
|
691
|
-
return this.publicClient.watchContractEvent({
|
|
692
|
-
address: this.address,
|
|
693
|
-
abi: events_1.SlvrGridLotteryEvents,
|
|
694
|
-
eventName: 'RoundResolved',
|
|
695
|
-
onLogs: (logs) => {
|
|
696
|
-
for (const log of logs)
|
|
697
|
-
onResolved(log.args);
|
|
698
|
-
},
|
|
699
|
-
onError: opts.onError,
|
|
700
|
-
poll: true,
|
|
701
|
-
});
|
|
702
|
-
}
|
|
703
|
-
/**
|
|
704
|
-
* Subscribe to `BetPlaced` events (optionally for one round). Returns an
|
|
705
|
-
* unsubscribe function. Useful for reacting to pot changes in real time.
|
|
706
|
-
*/
|
|
707
|
-
watchBets(onBet, opts = {}) {
|
|
708
|
-
return this.publicClient.watchContractEvent({
|
|
709
|
-
address: this.address,
|
|
710
|
-
abi: events_1.SlvrGridLotteryEvents,
|
|
711
|
-
eventName: 'BetPlaced',
|
|
712
|
-
args: opts.roundId !== undefined ? { roundId: opts.roundId } : undefined,
|
|
713
|
-
onLogs: (logs) => {
|
|
714
|
-
for (const log of logs)
|
|
715
|
-
onBet(log.args);
|
|
716
|
-
},
|
|
717
|
-
onError: opts.onError,
|
|
718
|
-
poll: true,
|
|
719
|
-
});
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
exports.SlvrGridLottery = SlvrGridLottery;
|
|
723
|
-
// ABI for SlvrGridLottery contract
|
|
724
|
-
SlvrGridLottery.ABI = (0, viem_1.parseAbi)([
|
|
725
|
-
// View functions
|
|
726
|
-
'function currentRoundId() view returns (uint256)',
|
|
727
|
-
'function roundStart(uint256 roundId) view returns (uint256)',
|
|
728
|
-
'function roundEnd(uint256 roundId) view returns (uint256)',
|
|
729
|
-
'function roundOpen(uint256 roundId) view returns (bool)',
|
|
730
|
-
// Betting cutoff for a round. This is the timestamp bets stop being accepted,
|
|
731
|
-
// which can be earlier than roundEnd() — gate bots on this, not roundEnd.
|
|
732
|
-
'function bettingEnd(uint256 roundId) view returns (uint256)',
|
|
733
|
-
'function getExpectedReward(address account, uint256 roundId) view returns (uint256)',
|
|
734
|
-
'function latestResolvedRoundId() view returns (uint256)',
|
|
735
|
-
// getRound returns a flat 16-value tuple (no wrapping struct)
|
|
736
|
-
'function getRound(uint256 roundId) view returns (uint64 requestedAt, bool resolved, bytes32 randomnessId, uint256 randomnessValue, uint8 winningSquare, bool jackpotHit, bool singleMinerRound, address singleMinerWinner, uint256 totalWager, uint256 fee, uint256 winnerTotal, uint256 potForWinners, uint256 slvrForWinners, uint256 payoutMulWad, uint256 slvrMulWad, uint256 totalUnclaimedSlvr)',
|
|
737
|
-
'function getTotalOnSquare(uint256 roundId, uint8 square) view returns (uint256)',
|
|
738
|
-
'function getBettorsOnSquare(uint256 roundId, uint8 square) view returns (uint256)',
|
|
739
|
-
'function getUserBet(uint256 roundId, uint8 square, address bettor) view returns (uint256)',
|
|
740
|
-
'function getHasClaimed(uint256 roundId, address user) view returns (bool)',
|
|
741
|
-
'function getMinerState(address account) view returns (uint256 rewardsSlvr, uint256 refinedAccrued, uint256 indexSnapshot, bool hasAccount)',
|
|
742
|
-
'function getHasAccount(address account) view returns (bool)',
|
|
743
|
-
'function getDelegate(address user, address delegate) view returns (bool)',
|
|
744
|
-
'function carryWinnerNativePool() view returns (uint256)',
|
|
745
|
-
'function carryStakerNativeOwed() view returns (uint256)',
|
|
746
|
-
'function carryJackpotNativeOwed() view returns (uint256)',
|
|
747
|
-
'function carrySlvrPool() view returns (uint256)',
|
|
748
|
-
// NOTE: slvrPerRound() still exists as a public var but is NO LONGER the authoritative
|
|
749
|
-
// emission number. Emission is hub-gated (see SlvrHub.pendingEmission / mintReward), so the
|
|
750
|
-
// amount actually minted per round is bounded by the game's streamed emission budget.
|
|
751
|
-
'function slvrPerRound() view returns (uint256)',
|
|
752
|
-
'function protocolFeeBps() view returns (uint16)',
|
|
753
|
-
'function GRID() view returns (uint8)',
|
|
754
|
-
'function ACCOUNT_DEPOSIT() view returns (uint256)',
|
|
755
|
-
// Write functions
|
|
756
|
-
'function bet(uint256 roundId, uint8[] squares, uint256[] amounts) payable',
|
|
757
|
-
'function betFor(uint256 roundId, address beneficiary, uint8[] squares, uint256[] amounts) payable',
|
|
758
|
-
'function claim(uint256 roundId)',
|
|
759
|
-
'function claimAdvanced((address user, uint256 roundId, address recipientNative, address recipientSlvr, bool bypassFee, bool ethOnly) params)',
|
|
760
|
-
'function approveDelegate(address delegate)',
|
|
761
|
-
'function revokeDelegate(address delegate)',
|
|
762
|
-
'function donateSlvrToJackpot(uint256 amount)',
|
|
763
|
-
'function addEthToJackpot() payable',
|
|
764
|
-
'function checkpoint(address account)',
|
|
765
|
-
'function withdrawUnrefinedSlvr() returns (uint256 totalPayout, uint256 refiningFee)',
|
|
766
|
-
]);
|
|
767
|
-
//# sourceMappingURL=lottery.js.map
|