gainlings-sdk-viem
v1.0.34
Published
Gainlings SDK using Viem
Readme
Gainlings SDK
Usage
First install the SDK:
npm install gainlings-sdk-viem
# or
yarn add gainlings-sdk-viemThen use the SDK:
import { GainlingsSDK, getLatestSeasonContractAddress } from "gainlings-sdk-viem";
import { createWalletClient, custom } from "viem";
import { arbitrumSepolia } from "viem/chains"; // Or your desired chain
import { parseEther, zeroAddress } from "viem"; // Need parseEther for value calculation, add zeroAddress for referrer example
// Define the contract addresses (Replace with actual addresses)
const managerAddress = "0xYOUR_MANAGER_CONTRACT_ADDRESS";
const marketPlaceContractAddress = "0xYOUR_MARKETPLACE_CONTRACT_ADDRESS";
const trophyAddress = "0xYOUR_TROPHY_CONTRACT_ADDRESS";
// Define your RPC endpoints.
// An HTTP(S) endpoint is required for standard operations.
// A WebSocket (WSS) endpoint is required for real-time event subscriptions.
const HTTP_RPC_URL = "https://arb-sepolia.g.alchemy.com/v2/YOUR_ALCHEMY_API_KEY";
const WSS_RPC_URL = "wss://arb-sepolia.g.alchemy.com/v2/YOUR_ALCHEMY_WEBSOCKET_API_KEY"; // Provide if subscriptions are needed
async function main() {
// Get the latest season contract address using the HTTP endpoint
const latestSeasonContractAddress = await getLatestSeasonContractAddress(managerAddress, HTTP_RPC_URL);
console.log("Latest Season Contract Address: ", latestSeasonContractAddress);
// Optional: Create a Wallet Client
let walletClient;
if (typeof window !== 'undefined' && window.ethereum) {
walletClient = createWalletClient({
chain: arbitrumSepolia,
transport: custom(window.ethereum)
});
} else {
console.warn("No Ethereum browser provider found. Wallet functionality may be limited.");
}
// Create a new GainlingsSDK instance
const gainlingsSdk = new GainlingsSDK(
latestSeasonContractAddress,
trophyAddress,
marketPlaceContractAddress,
arbitrumSepolia, // The viem Chain object
HTTP_RPC_URL, // Required HTTP(S) RPC URL
WSS_RPC_URL, // Optional WebSocket (WSS) RPC URL for subscriptions
walletClient // Optional viem WalletClient
);
// Example: Setup wallet
if (walletClient) {
await gainlingsSdk.setupWallet();
console.log("Connected Address:", gainlingsSdk.getAddress());
}
// --- Example: Minting Gainlings (Requires Wallet Client and Funds) ---
console.log("\n[Example] Minting Gainlings...");
if (gainlingsSdk.walletClient && gainlingsSdk.address) {
try {
// 1. Get the required price per token
const contractInfo = await gainlingsSdk.gainlingsFactory.getContractInfo();
const pricePerTokenEth = contractInfo.publicPrice; // e.g., '0.001'
const pricePerTokenWei = parseEther(pricePerTokenEth); // Convert to bigint wei
// 2. Define quantity and calculate total value
const quantityToMint = 1;
const totalValueWei = pricePerTokenWei * BigInt(quantityToMint);
// 3. Define referrer (optional)
const referrerAddress = zeroAddress; // Use zeroAddress if no referrer
console.log(` Attempting to mint ${quantityToMint} token(s).`);
console.log(` Price per token: ${pricePerTokenEth} ETH`);
console.log(` Referrer: ${referrerAddress}`);
console.log(` Value to send: ${totalValueWei} wei`);
// --- Choose ONE of the following ---
// 4a. Call the mint function WITH referrer
const mintTxHashWithRef = await gainlingsSdk.gainlingsFactory.mintQRNGWithReferrer(quantityToMint, referrerAddress, totalValueWei);
console.log(` ✅ Mint (with referrer) Tx Sent: ${mintTxHashWithRef}`);
// const receiptWithRef = await gainlingsSdk.publicClient.waitForTransactionReceipt({ hash: mintTxHashWithRef });
// console.log(` ✅ Mint (with referrer) Tx Confirmed: Block ${receiptWithRef.blockNumber}`);
/*
// OR
// 4b. Call the mint function WITHOUT referrer
const mintTxHashNoRef = await gainlingsSdk.gainlingsFactory.mintQRNG(quantityToMint, totalValueWei);
console.log(` ✅ Mint (no referrer) Tx Sent: ${mintTxHashNoRef}`);
// const receiptNoRef = await gainlingsSdk.publicClient.waitForTransactionReceipt({ hash: mintTxHashNoRef });
// console.log(` ✅ Mint (no referrer) Tx Confirmed: Block ${receiptNoRef.blockNumber}`);
*/
} catch (error) {
console.error(` ❌ FAILED: Minting error.`, error);
}
} else {
console.log(" ℹ️ SKIPPED: WalletClient not available or setupWallet not called.");
}
// ----------------------------------------------------------------------
// Example: Get minted supply (uses HTTP client)
try {
let mintedSupply = await gainlingsSdk.gainlingsFactory.getMintedSupply();
console.log("Gainlings Minted Supply: ", mintedSupply.toString());
} catch (error) {
console.error("Error getting minted supply:", error);
}
// Example: Subscribe to events (requires WSS_RPC_URL to be provided)
if (WSS_RPC_URL) { // Only attempt if WSS URL was provided
console.log("\nSubscribing to Gainling mint events (will run for 60s)...");
let unwatchMints = null;
try {
// Call subscribe method directly on the SDK instance
unwatchMints = gainlingsSdk.subscribeToMints((eventData) => {
console.log("\n--- New Mint Event Received ---");
console.log("Type:", eventData.type);
console.log("Issuer:", eventData.data.issuer);
console.log("Quantity:", eventData.data.quantity);
console.log("Block:", eventData.event.blockNumber?.toString());
console.log("-----------------------------\n");
});
console.log("Successfully subscribed to mint events.");
await new Promise(resolve => setTimeout(resolve, 60000)); // Wait 60s
} catch (error) {
console.error("Error subscribing to mint events:", error);
} finally {
if (unwatchMints) {
console.log("\nUnsubscribing from mint events...");
unwatchMints();
console.log("Unsubscribed.");
}
}
} else {
console.log("\nSkipping event subscription example as no WebSocket RPC URL was provided.");
}
}
main().catch(console.error);
## Subscribing to Events
The SDK allows you to subscribe to real-time contract events using methods directly on the `GainlingsSDK` instance (e.g., `gainlingsSdk.subscribeToMints(...)`).
For this functionality, you **must** initialize the SDK with both an `httpRpcUrl` and a `webSocketRpcUrl` (`wss://...`) in the constructor. The SDK uses the WebSocket URL exclusively for subscriptions.
```javascript
// Example assuming gainlingsSdk was initialized with both HTTP and WSS URLs
async function subscribeExample(gainlingsSdk) {
console.log("Subscribing to Gainling mint events...");
let unwatch = null;
try {
// Pass a callback function to handle incoming events
// Call the method directly on the SDK instance
unwatch = gainlingsSdk.subscribeToMints((eventData) => {
console.log("\n--- New Mint Event Received ---");
console.log("Type:", eventData.type); // 'mint'
console.log("Issuer:", eventData.data.issuer);
console.log("Quantity:", eventData.data.quantity);
console.log("Block:", eventData.event.blockNumber?.toString());
console.log("-----------------------------\n");
});
console.log("Successfully subscribed. Listening for events...");
// Keep the process alive or manage subscription state
await new Promise(resolve => setTimeout(resolve, 120000)); // Wait 2 mins
} catch (error) {
console.error("Subscription error:", error);
} finally {
if (unwatch) {
console.log("Unsubscribing...");
unwatch();
console.log("Unsubscribed.");
}
}
}
// Example call:
// const sdk = new GainlingsSDK(..., httpUrl, wssUrl, ...);
// subscribeExample(sdk).catch(console.error);Similar subscribeTo... methods exist directly on the GainlingsSDK instance for other events like GainlingSeeded, GainlingApproached, and GainlingAttacked.
