@slvr-labs/sdk 0.1.0
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/LICENSE +21 -0
- package/README.md +849 -0
- package/dist/connect.d.ts +47 -0
- package/dist/connect.d.ts.map +1 -0
- package/dist/connect.js +56 -0
- package/dist/connect.js.map +1 -0
- package/dist/contracts/autoCommit.d.ts +151 -0
- package/dist/contracts/autoCommit.d.ts.map +1 -0
- package/dist/contracts/autoCommit.js +426 -0
- package/dist/contracts/autoCommit.js.map +1 -0
- package/dist/contracts/hub.d.ts +50 -0
- package/dist/contracts/hub.d.ts.map +1 -0
- package/dist/contracts/hub.js +118 -0
- package/dist/contracts/hub.js.map +1 -0
- package/dist/contracts/index.d.ts +8 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +18 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/jackpot.d.ts +21 -0
- package/dist/contracts/jackpot.d.ts.map +1 -0
- package/dist/contracts/jackpot.js +44 -0
- package/dist/contracts/jackpot.js.map +1 -0
- package/dist/contracts/lottery.d.ts +256 -0
- package/dist/contracts/lottery.d.ts.map +1 -0
- package/dist/contracts/lottery.js +767 -0
- package/dist/contracts/lottery.js.map +1 -0
- package/dist/contracts/registry.d.ts +53 -0
- package/dist/contracts/registry.d.ts.map +1 -0
- package/dist/contracts/registry.js +143 -0
- package/dist/contracts/registry.js.map +1 -0
- package/dist/contracts/staking.d.ts +101 -0
- package/dist/contracts/staking.d.ts.map +1 -0
- package/dist/contracts/staking.js +306 -0
- package/dist/contracts/staking.js.map +1 -0
- package/dist/contracts/token.d.ts +95 -0
- package/dist/contracts/token.d.ts.map +1 -0
- package/dist/contracts/token.js +273 -0
- package/dist/contracts/token.js.map +1 -0
- package/dist/deployments.d.ts +117 -0
- package/dist/deployments.d.ts.map +1 -0
- package/dist/deployments.js +74 -0
- package/dist/deployments.js.map +1 -0
- package/dist/errors.d.ts +39 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +67 -0
- package/dist/errors.js.map +1 -0
- package/dist/ev.d.ts +123 -0
- package/dist/ev.d.ts.map +1 -0
- package/dist/ev.js +111 -0
- package/dist/ev.js.map +1 -0
- package/dist/events.d.ts +418 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +87 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +248 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +436 -0
- package/dist/index.js.map +1 -0
- package/dist/oracle.d.ts +48 -0
- package/dist/oracle.d.ts.map +1 -0
- package/dist/oracle.js +77 -0
- package/dist/oracle.js.map +1 -0
- package/dist/price.d.ts +52 -0
- package/dist/price.d.ts.map +1 -0
- package/dist/price.js +78 -0
- package/dist/price.js.map +1 -0
- package/dist/transaction.d.ts +54 -0
- package/dist/transaction.d.ts.map +1 -0
- package/dist/transaction.js +105 -0
- package/dist/transaction.js.map +1 -0
- package/dist/types.d.ts +162 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +23 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +58 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +110 -0
- package/dist/utils.js.map +1 -0
- package/examples/.env.example +22 -0
- package/examples/README.md +417 -0
- package/examples/automated-betting.ts +232 -0
- package/examples/combined-strategy.ts +227 -0
- package/examples/constants.ts +35 -0
- package/examples/custom-strategy-example.ts +231 -0
- package/examples/expected-value-strategy.ts +255 -0
- package/examples/fixed-squares-strategy.ts +176 -0
- package/examples/index.ts +30 -0
- package/examples/least-allocated-strategy.ts +224 -0
- package/examples/local-test.ts +172 -0
- package/examples/quickstart-bet.ts +72 -0
- package/examples/quickstart-read.ts +87 -0
- package/examples/simple-example.ts +122 -0
- package/examples/strategy-base.ts +283 -0
- package/package.json +71 -0
- package/skills/slvr-bot/SKILL.md +193 -0
- package/skills/slvr-bot/references/api.md +117 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example SDK usage against local Anvil instance
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* 1. Start local environment: ./scripts/start-local.sh
|
|
6
|
+
* 2. Update contract addresses below
|
|
7
|
+
* 3. Run: npx tsx examples/local-test.ts
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { createPublicClient, createWalletClient, http, parseEther } from 'viem';
|
|
11
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
12
|
+
import { SlvrSDK } from '../src/index';
|
|
13
|
+
|
|
14
|
+
// Local Anvil configuration
|
|
15
|
+
const RPC_URL = process.env.RPC_URL || 'http://localhost:8545';
|
|
16
|
+
const CHAIN_ID = 31337;
|
|
17
|
+
|
|
18
|
+
// Update these addresses after deployment (from script/deployments/localhost.json)
|
|
19
|
+
const CONTRACT_ADDRESSES = {
|
|
20
|
+
lottery: '0x0000000000000000000000000000000000000000' as `0x${string}`, // Update this
|
|
21
|
+
staking: '0x0000000000000000000000000000000000000000' as `0x${string}`, // Update this (SlvrVoteEscrowStaking)
|
|
22
|
+
token: '0x0000000000000000000000000000000000000000' as `0x${string}`, // Update this
|
|
23
|
+
autoCommit: '0x0000000000000000000000000000000000000000' as `0x${string}`, // Optional
|
|
24
|
+
hub: '0x0000000000000000000000000000000000000000' as `0x${string}`, // Optional: SlvrHub
|
|
25
|
+
registry: '0x0000000000000000000000000000000000000000' as `0x${string}`, // Optional: SlvrGameRegistry
|
|
26
|
+
jackpot: '0x0000000000000000000000000000000000000000' as `0x${string}`, // Optional: SlvrJackpot
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
// The veNFT tokenId to inspect for staking (update after staking a token)
|
|
30
|
+
const STAKING_TOKEN_ID = 1n;
|
|
31
|
+
|
|
32
|
+
// Use Anvil's first account (or set your own private key)
|
|
33
|
+
const PRIVATE_KEY = process.env.PRIVATE_KEY || '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80';
|
|
34
|
+
|
|
35
|
+
// Define localhost chain
|
|
36
|
+
const localhostChain = {
|
|
37
|
+
id: CHAIN_ID,
|
|
38
|
+
name: 'Localhost',
|
|
39
|
+
nativeCurrency: {
|
|
40
|
+
decimals: 18,
|
|
41
|
+
name: 'Ether',
|
|
42
|
+
symbol: 'ETH',
|
|
43
|
+
},
|
|
44
|
+
rpcUrls: {
|
|
45
|
+
default: {
|
|
46
|
+
http: [RPC_URL],
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
} as const;
|
|
50
|
+
|
|
51
|
+
async function main() {
|
|
52
|
+
console.log('🚀 Testing SLVR SDK against local Anvil instance\n');
|
|
53
|
+
console.log(`RPC URL: ${RPC_URL}`);
|
|
54
|
+
console.log(`Chain ID: ${CHAIN_ID}\n`);
|
|
55
|
+
|
|
56
|
+
// Create clients
|
|
57
|
+
const publicClient = createPublicClient({
|
|
58
|
+
chain: localhostChain,
|
|
59
|
+
transport: http(RPC_URL),
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const account = privateKeyToAccount(PRIVATE_KEY as `0x${string}`);
|
|
63
|
+
const walletClient = createWalletClient({
|
|
64
|
+
chain: localhostChain,
|
|
65
|
+
transport: http(RPC_URL),
|
|
66
|
+
account,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
console.log(`Using account: ${account.address}\n`);
|
|
70
|
+
|
|
71
|
+
// Initialize SDK
|
|
72
|
+
const sdk = new SlvrSDK({
|
|
73
|
+
publicClient,
|
|
74
|
+
walletClient,
|
|
75
|
+
addresses: CONTRACT_ADDRESSES,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
// Test 1: Get current round
|
|
80
|
+
console.log('📊 Test 1: Get current round');
|
|
81
|
+
const currentRoundId = await sdk.lottery.currentRoundId();
|
|
82
|
+
console.log(` Current round ID: ${currentRoundId}\n`);
|
|
83
|
+
|
|
84
|
+
// Test 2: Get round info
|
|
85
|
+
console.log('📊 Test 2: Get round info');
|
|
86
|
+
const roundInfo = await sdk.lottery.getRound(currentRoundId);
|
|
87
|
+
console.log(` Round ${currentRoundId}:`, {
|
|
88
|
+
totalWager: roundInfo.totalWager.toString(),
|
|
89
|
+
resolved: roundInfo.resolved,
|
|
90
|
+
winningSquare: roundInfo.winningSquare,
|
|
91
|
+
});
|
|
92
|
+
console.log('');
|
|
93
|
+
|
|
94
|
+
// Test 3: Get token balance
|
|
95
|
+
console.log('📊 Test 3: Get token balance');
|
|
96
|
+
const tokenBalance = await sdk.token.balanceOf(account.address);
|
|
97
|
+
console.log(` SLVR balance: ${SlvrSDK.formatToken(tokenBalance)}\n`);
|
|
98
|
+
|
|
99
|
+
// Test 4: Get staking info (veNFT staker, keyed by tokenId)
|
|
100
|
+
console.log('📊 Test 4: Get staking info');
|
|
101
|
+
const stakingInfo = await sdk.staking.getStakingInfo(STAKING_TOKEN_ID);
|
|
102
|
+
console.log(` Token ${STAKING_TOKEN_ID} weight: ${SlvrSDK.formatToken(stakingInfo.balance)}`);
|
|
103
|
+
console.log(` Total weight: ${SlvrSDK.formatToken(stakingInfo.totalWeight)}`);
|
|
104
|
+
console.log(` Claimable rewards: ${SlvrSDK.formatToken(stakingInfo.rewards)}\n`);
|
|
105
|
+
|
|
106
|
+
// Test 5: Place a bet (if you have ETH)
|
|
107
|
+
console.log('📊 Test 5: Place a bet');
|
|
108
|
+
const betAmount = parseEther('0.1');
|
|
109
|
+
const squares = [5, 10, 15];
|
|
110
|
+
const amounts = [
|
|
111
|
+
betAmount / 3n,
|
|
112
|
+
betAmount / 3n,
|
|
113
|
+
betAmount / 3n + (betAmount % 3n), // Handle remainder
|
|
114
|
+
];
|
|
115
|
+
|
|
116
|
+
console.log(` Placing bet on squares ${squares.join(', ')}`);
|
|
117
|
+
console.log(` Total amount: ${SlvrSDK.formatToken(betAmount)} ETH`);
|
|
118
|
+
|
|
119
|
+
// Uncomment to actually place the bet:
|
|
120
|
+
// const txHash = await sdk.lottery.bet({
|
|
121
|
+
// roundId: currentRoundId,
|
|
122
|
+
// squares,
|
|
123
|
+
// amounts,
|
|
124
|
+
// });
|
|
125
|
+
// console.log(` Transaction: ${txHash}`);
|
|
126
|
+
// console.log(' Waiting for confirmation...');
|
|
127
|
+
// await publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
128
|
+
// console.log(' ✅ Bet placed!\n');
|
|
129
|
+
|
|
130
|
+
console.log(' (Skipped - uncomment in code to execute)\n');
|
|
131
|
+
|
|
132
|
+
// Test 6: Emission / registry / jackpot stats (optional bindings)
|
|
133
|
+
console.log('📊 Test 6: Emission / registry / jackpot stats');
|
|
134
|
+
if (sdk.hub) {
|
|
135
|
+
const rate = await sdk.hub.emissionRatePerSec();
|
|
136
|
+
const target = await sdk.hub.targetSupply();
|
|
137
|
+
console.log(` Emission rate/sec: ${SlvrSDK.formatToken(rate)}`);
|
|
138
|
+
console.log(` Target supply: ${SlvrSDK.formatToken(target)}`);
|
|
139
|
+
}
|
|
140
|
+
if (sdk.registry) {
|
|
141
|
+
const gameId = await sdk.registry.gameIdOf(CONTRACT_ADDRESSES.lottery);
|
|
142
|
+
const totalWeight = await sdk.registry.totalActiveWeight();
|
|
143
|
+
console.log(` Lottery gameId: ${gameId}`);
|
|
144
|
+
console.log(` Total active weight: ${totalWeight}`);
|
|
145
|
+
// Combined helper: game's weighted SLVR/sec share (requires hub + registry)
|
|
146
|
+
if (sdk.hub && gameId > 0n) {
|
|
147
|
+
const effRate = await sdk.effectiveEmissionRate(gameId);
|
|
148
|
+
const pending = await sdk.pendingEmission(gameId);
|
|
149
|
+
console.log(` Effective emission rate: ${SlvrSDK.formatToken(effRate)}/sec`);
|
|
150
|
+
console.log(` Pending emission: ${SlvrSDK.formatToken(pending)}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (sdk.jackpot) {
|
|
154
|
+
const ethPool = await sdk.jackpot.jackpotPool();
|
|
155
|
+
const slvrPool = await sdk.jackpot.jackpotSlvrPool();
|
|
156
|
+
console.log(` Jackpot ETH pool: ${SlvrSDK.formatToken(ethPool)}`);
|
|
157
|
+
console.log(` Jackpot SLVR pool: ${SlvrSDK.formatToken(slvrPool)}`);
|
|
158
|
+
}
|
|
159
|
+
if (!sdk.hub && !sdk.registry && !sdk.jackpot) {
|
|
160
|
+
console.log(' (No hub/registry/jackpot addresses configured - skipped)');
|
|
161
|
+
}
|
|
162
|
+
console.log('');
|
|
163
|
+
|
|
164
|
+
console.log('✅ All tests completed!');
|
|
165
|
+
} catch (error) {
|
|
166
|
+
console.error('❌ Error:', error);
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
main();
|
|
172
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quickstart 2 — place a bet with a wallet
|
|
3
|
+
* ========================================
|
|
4
|
+
*
|
|
5
|
+
* The minimal write path: build a wallet-backed SDK, sanity-check the round's
|
|
6
|
+
* expected value, place one small bet, and print how to claim once the round
|
|
7
|
+
* resolves. Bets are paid in native ETH (no token approval needed).
|
|
8
|
+
*
|
|
9
|
+
* Run it (uses a tiny stake by default — start on a testnet / small amount):
|
|
10
|
+
* PRIVATE_KEY=0xabc... npx ts-node quickstart-bet.ts
|
|
11
|
+
*
|
|
12
|
+
* To use this in your own project, change the `../src` import to `@slvr-labs/sdk`.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { createPublicClient, createWalletClient, http, parseEther, formatEther } from 'viem';
|
|
16
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
17
|
+
import { SlvrSDK, robinhoodChain, deployments } from '../src';
|
|
18
|
+
|
|
19
|
+
// How much to bet, total, and which squares to spread it across (indices 0–24).
|
|
20
|
+
const STAKE_ETH = '0.002';
|
|
21
|
+
const SQUARES = [0, 12, 24];
|
|
22
|
+
|
|
23
|
+
async function main() {
|
|
24
|
+
const privateKey = process.env.PRIVATE_KEY as `0x${string}` | undefined;
|
|
25
|
+
if (!privateKey) throw new Error('Set PRIVATE_KEY to a funded key on Robinhood Chain');
|
|
26
|
+
|
|
27
|
+
// 1. Wallet-backed SDK from the shipped chain + addresses.
|
|
28
|
+
const account = privateKeyToAccount(privateKey);
|
|
29
|
+
const publicClient = createPublicClient({ chain: robinhoodChain, transport: http() });
|
|
30
|
+
const walletClient = createWalletClient({ chain: robinhoodChain, transport: http(), account });
|
|
31
|
+
const sdk = new SlvrSDK({ publicClient, walletClient, addresses: deployments.robinhood.addresses });
|
|
32
|
+
|
|
33
|
+
console.log(`Account: ${account.address}`);
|
|
34
|
+
const ethBalance = await publicClient.getBalance({ address: account.address });
|
|
35
|
+
console.log(`ETH balance: ${formatEther(ethBalance)}\n`);
|
|
36
|
+
|
|
37
|
+
// 2. Pick the current round and make sure it's open.
|
|
38
|
+
const roundId = await sdk.lottery.currentRoundId();
|
|
39
|
+
if (!(await sdk.lottery.roundOpen(roundId))) {
|
|
40
|
+
console.log(`Round #${roundId} is closed for betting — try again next round.`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 3. Optional sanity check: is mining this round +EV right now?
|
|
45
|
+
// (Informational — we bet regardless in this demo.)
|
|
46
|
+
const ev = await sdk.estimateRoundEv({ stake: Number(STAKE_ETH) });
|
|
47
|
+
console.log(
|
|
48
|
+
`Round #${roundId} EV @ ${STAKE_ETH} ETH: ` +
|
|
49
|
+
`${ev.netEth >= 0 ? '+' : ''}${ev.netEth.toFixed(6)} ETH/round ` +
|
|
50
|
+
`(${ev.profitable ? 'profitable' : 'not profitable'}; break-even pot ${ev.breakEvenPot.toFixed(4)} ETH)`
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
// 4. Split the stake evenly across the chosen squares and bet.
|
|
54
|
+
const stakeWei = parseEther(STAKE_ETH);
|
|
55
|
+
const per = stakeWei / BigInt(SQUARES.length);
|
|
56
|
+
const amounts = SQUARES.map((_, i) => (i === 0 ? per + (stakeWei - per * BigInt(SQUARES.length)) : per));
|
|
57
|
+
|
|
58
|
+
console.log(`\nBetting ${STAKE_ETH} ETH on squares ${SQUARES.join(', ')}…`);
|
|
59
|
+
const txHash = await sdk.lottery.bet({ roundId, squares: SQUARES, amounts });
|
|
60
|
+
console.log(`✅ Bet placed: ${txHash}`);
|
|
61
|
+
|
|
62
|
+
// 5. How to collect. Rounds resolve after betting closes; you can only claim a
|
|
63
|
+
// round you won (held the winning square) and haven't claimed yet.
|
|
64
|
+
console.log(`\nTo claim after the round resolves:`);
|
|
65
|
+
console.log(` const canClaim = await sdk.canClaim(${roundId}n, "${account.address}");`);
|
|
66
|
+
console.log(` if (canClaim) await sdk.lottery.claim({ roundId: ${roundId}n });`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
main().catch((err) => {
|
|
70
|
+
console.error(err);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Quickstart 1 — read-only tour (no wallet needed)
|
|
3
|
+
* ================================================
|
|
4
|
+
*
|
|
5
|
+
* The fastest way to confirm the SDK works. It needs nothing but an RPC — no
|
|
6
|
+
* private key — and prints a snapshot of the live game: the current round, the
|
|
7
|
+
* pot, and the SLVR price in both ETH and USD.
|
|
8
|
+
*
|
|
9
|
+
* Run it:
|
|
10
|
+
* npx ts-node quickstart-read.ts
|
|
11
|
+
* npx ts-node quickstart-read.ts 0xYourAddress # also show that address's balance/bets
|
|
12
|
+
*
|
|
13
|
+
* To use this in your own project, change the `../src` import to `@slvr-labs/sdk`.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { createPublicClient, http, formatEther, isAddress, type Address } from 'viem';
|
|
17
|
+
import { SlvrSDK, robinhoodChain, deployments } from '../src';
|
|
18
|
+
|
|
19
|
+
async function main() {
|
|
20
|
+
// 1. A read-only SDK: just a public client + the shipped mainnet addresses.
|
|
21
|
+
// No walletClient means write calls are disabled — reads are all we need here.
|
|
22
|
+
const publicClient = createPublicClient({ chain: robinhoodChain, transport: http() });
|
|
23
|
+
const sdk = new SlvrSDK({
|
|
24
|
+
publicClient,
|
|
25
|
+
addresses: deployments.robinhood.addresses,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
console.log(`Connected to ${robinhoodChain.name} (chain ${robinhoodChain.id})\n`);
|
|
29
|
+
|
|
30
|
+
// 2. Current round + whether it's still open for betting.
|
|
31
|
+
const roundId = await sdk.lottery.currentRoundId();
|
|
32
|
+
const [isOpen, bettingEnd, squares] = await Promise.all([
|
|
33
|
+
sdk.lottery.roundOpen(roundId),
|
|
34
|
+
sdk.lottery.bettingEnd(roundId),
|
|
35
|
+
sdk.lottery.getRoundSquares(roundId),
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
const pot = squares.reduce((sum, s) => sum + s.total, 0n);
|
|
39
|
+
const totalBettors = squares.reduce((sum, s) => sum + s.bettors, 0n);
|
|
40
|
+
const secondsLeft = Number(bettingEnd) - Math.floor(Date.now() / 1000);
|
|
41
|
+
|
|
42
|
+
console.log(`Round #${roundId}`);
|
|
43
|
+
console.log(` status: ${isOpen ? 'OPEN for betting' : 'closed'}`);
|
|
44
|
+
console.log(` betting ends: ${secondsLeft > 0 ? `in ~${secondsLeft}s` : 'passed'}`);
|
|
45
|
+
console.log(` pot: ${formatEther(pot)} ETH across ${squares.length} squares`);
|
|
46
|
+
console.log(` bettors: ${totalBettors}`);
|
|
47
|
+
|
|
48
|
+
// 3. Prices — SLVR in ETH (from the UniswapV2 pair) and USD (via the Chainlink feed).
|
|
49
|
+
const [slvr, ethUsd] = await Promise.all([sdk.getSlvrPrice(), sdk.getEthPriceUsd()]);
|
|
50
|
+
console.log(`\nPrices`);
|
|
51
|
+
console.log(` ETH: $${ethUsd.toFixed(2)}`);
|
|
52
|
+
console.log(
|
|
53
|
+
` SLVR: ${slvr.eth.toExponential(4)} ETH` +
|
|
54
|
+
(slvr.usd !== null ? ` · $${slvr.usd.toFixed(4)}` : ' · (USD unavailable)')
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
// 4. Token supply, for context.
|
|
58
|
+
const [supply, maxSupply] = await Promise.all([
|
|
59
|
+
sdk.token.totalSupply(),
|
|
60
|
+
sdk.token.maxSupply(),
|
|
61
|
+
]);
|
|
62
|
+
console.log(`\nSLVR supply: ${formatEther(supply)} / ${formatEther(maxSupply)} max`);
|
|
63
|
+
|
|
64
|
+
// 5. Optional: pass an address to see its SLVR balance and bets this round.
|
|
65
|
+
const who = process.argv[2];
|
|
66
|
+
if (who && isAddress(who)) {
|
|
67
|
+
const addr = who as Address;
|
|
68
|
+
const [bal, bets] = await Promise.all([
|
|
69
|
+
sdk.token.balanceOf(addr),
|
|
70
|
+
sdk.lottery.getUserBets(roundId, addr),
|
|
71
|
+
]);
|
|
72
|
+
console.log(`\n${addr}`);
|
|
73
|
+
console.log(` SLVR balance: ${formatEther(bal)}`);
|
|
74
|
+
console.log(
|
|
75
|
+
` bets this round: ${
|
|
76
|
+
bets.length ? bets.map((b) => `#${b.square}=${formatEther(b.amount)}ETH`).join(', ') : 'none'
|
|
77
|
+
}`
|
|
78
|
+
);
|
|
79
|
+
} else if (who) {
|
|
80
|
+
console.log(`\n(ignoring "${who}" — not a valid address)`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
main().catch((err) => {
|
|
85
|
+
console.error(err);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
});
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple example: Basic usage of the Slvr SDK
|
|
3
|
+
*
|
|
4
|
+
* This is a minimal example showing how to:
|
|
5
|
+
* 1. Initialize the SDK
|
|
6
|
+
* 2. Get current round information
|
|
7
|
+
* 3. Place a simple bet
|
|
8
|
+
*
|
|
9
|
+
* Set PRIVATE_KEY environment variable to use wallet operations
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { SlvrSDK } from '../src';
|
|
13
|
+
import { createPublicClient, createWalletClient, http, parseEther } from 'viem';
|
|
14
|
+
import { defineChain } from 'viem';
|
|
15
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
16
|
+
import { CONTRACTS, ROBINHOOD_CHAIN } from './constants';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Simple example function
|
|
20
|
+
*/
|
|
21
|
+
export async function simpleExample() {
|
|
22
|
+
// 1. Define the Robinhood chain
|
|
23
|
+
const robinhood = defineChain(ROBINHOOD_CHAIN);
|
|
24
|
+
|
|
25
|
+
// 2. Create public client for read operations
|
|
26
|
+
const publicClient = createPublicClient({
|
|
27
|
+
chain: robinhood,
|
|
28
|
+
transport: http(),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// 3. Create wallet client for write operations (if private key is provided)
|
|
32
|
+
let walletClient: ReturnType<typeof createWalletClient> | undefined;
|
|
33
|
+
const privateKey = process.env.PRIVATE_KEY;
|
|
34
|
+
|
|
35
|
+
if (privateKey) {
|
|
36
|
+
const account = privateKeyToAccount(privateKey as `0x${string}`);
|
|
37
|
+
walletClient = createWalletClient({
|
|
38
|
+
chain: robinhood,
|
|
39
|
+
transport: http(),
|
|
40
|
+
account,
|
|
41
|
+
});
|
|
42
|
+
console.log(`Using account: ${account.address}`);
|
|
43
|
+
} else {
|
|
44
|
+
console.log('No PRIVATE_KEY found in environment - wallet operations disabled');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 4. Initialize SDK
|
|
48
|
+
const sdk = new SlvrSDK({
|
|
49
|
+
publicClient,
|
|
50
|
+
walletClient,
|
|
51
|
+
addresses: {
|
|
52
|
+
lottery: CONTRACTS.LOTTERY,
|
|
53
|
+
staking: CONTRACTS.STAKING,
|
|
54
|
+
token: CONTRACTS.TOKEN,
|
|
55
|
+
autoCommit: CONTRACTS.AUTO_COMMIT !== '0x...' ? CONTRACTS.AUTO_COMMIT : undefined,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// 4. Get current round
|
|
60
|
+
const roundId = await sdk.lottery.currentRoundId();
|
|
61
|
+
console.log(`Current round: ${roundId}`);
|
|
62
|
+
|
|
63
|
+
// 5. Get round information
|
|
64
|
+
const round = await sdk.lottery.getRound(roundId);
|
|
65
|
+
console.log(`Round ${roundId}:`, {
|
|
66
|
+
resolved: round.resolved,
|
|
67
|
+
totalWager: SlvrSDK.formatToken(round.totalWager),
|
|
68
|
+
winningSquare: round.winningSquare,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// 6. Check if round is open
|
|
72
|
+
const isOpen = await sdk.lottery.roundOpen(roundId);
|
|
73
|
+
console.log(`Round ${roundId} is ${isOpen ? 'open' : 'closed'} for betting`);
|
|
74
|
+
|
|
75
|
+
// 7. Get squares data
|
|
76
|
+
const squares = await sdk.lottery.getRoundSquares(roundId);
|
|
77
|
+
console.log(`Square allocations:`, squares.map(sq => ({
|
|
78
|
+
square: sq.square,
|
|
79
|
+
total: SlvrSDK.formatToken(sq.total),
|
|
80
|
+
bettors: Number(sq.bettors),
|
|
81
|
+
})));
|
|
82
|
+
|
|
83
|
+
// 8. Place a bet (requires wallet client)
|
|
84
|
+
if (isOpen && walletClient) {
|
|
85
|
+
const squaresToBet = [0, 1, 2]; // Square indices (0-24)
|
|
86
|
+
const amounts = [
|
|
87
|
+
parseEther('1'), // 1 ETH on square 0
|
|
88
|
+
parseEther('1'), // 1 ETH on square 1
|
|
89
|
+
parseEther('1'), // 1 ETH on square 2
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
const txHash = await sdk.lottery.bet({
|
|
93
|
+
roundId,
|
|
94
|
+
squares: squaresToBet,
|
|
95
|
+
amounts,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
console.log(`Bet placed! Transaction: ${txHash}`);
|
|
99
|
+
} else if (isOpen && !walletClient) {
|
|
100
|
+
console.log('Cannot place bet - wallet client not available (set PRIVATE_KEY env var)');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// 9. Get user's bets (if wallet client is available)
|
|
104
|
+
if (walletClient?.account) {
|
|
105
|
+
const userAddress = walletClient.account.address;
|
|
106
|
+
const userBets = await sdk.lottery.getUserBets(roundId, userAddress);
|
|
107
|
+
console.log(`Your bets:`, userBets.map(bet => ({
|
|
108
|
+
square: bet.square,
|
|
109
|
+
amount: SlvrSDK.formatToken(bet.amount),
|
|
110
|
+
})));
|
|
111
|
+
|
|
112
|
+
// 10. Check if you can claim
|
|
113
|
+
const canClaim = await sdk.canClaim(roundId, userAddress);
|
|
114
|
+
if (canClaim) {
|
|
115
|
+
console.log(`You can claim rewards for round ${roundId}`);
|
|
116
|
+
// Uncomment to actually claim:
|
|
117
|
+
// const txHash = await sdk.lottery.claim({ roundId });
|
|
118
|
+
// console.log(`Claimed! Transaction: ${txHash}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|