axie-tools
Version:
TypeScript library and CLI tool for interacting with Axie Infinity marketplace and NFTs on Ronin network. Features marketplace operations (buy/sell/delist), batch transfers, and wallet information.
110 lines (94 loc) • 3.76 kB
text/typescript
import { parseUnits, type Provider, type Signer, type Wallet } from 'ethers';
import { getAtiaContract } from "./contracts";
import { getAtiaBlessingDelegations } from './atia/graphql';
const PREFIX = `Atia's Blessing`;
export async function checkBlessings(wallet: Wallet, accessToken: string) {
console.log(`⚙️ Starting ${PREFIX} daily pray`);
const provider = 'provider' in wallet ? wallet.provider : undefined;
const signer = 'provider' in wallet ? wallet : undefined;
if (!provider) {
console.error(`⚠️ ${PREFIX}: Provider is required for praying!`);
return;
}
if (!signer) {
console.error(`⚠️ ${PREFIX}: Wallet with signer is required for praying!`);
return;
}
const address = await signer.getAddress();
console.log("📋 Fetching delegations...");
const delegations = await getAtiaBlessingDelegations(accessToken, address)
// Extract unique delegatee addresses from delegations where current address is delegator
const delegateeAddresses = new Set<string>();
for (const delegation of delegations) {
if (delegation.toAddress.toLowerCase() === address.toLowerCase()) {
delegateeAddresses.add(delegation.fromAddress);
}
}
// If no delegations limit found, pray for self too
if (delegateeAddresses.size < 5) {
delegateeAddresses.add(address);
console.log("ℹ️ No delegations found, praying for self only");
}
const delegateesToPray = Array.from(delegateeAddresses);
if (delegateesToPray.length > 5) {
console.log(`❌ ${PREFIX}: Too many delegatees for prayer ${address.slice(-4)} (max: 5)`);
return;
}
console.log(`🙏 Praying for ${delegateesToPray.length} delegatees...`);
for (const delegatee of delegateesToPray) {
await isActivated(delegatee, provider).then(async ({ status, streak }) => {
if (status) {
console.log(`⏱️ ${PREFIX}: Already activated for ${delegatee.slice(-4)} (streak: ${streak})`);
} else {
await activateStreak(signer, delegatee).then(({ status, streak }) => {
if (!status) return;
console.log(`✅ ${PREFIX}: Activated for ${delegatee.slice(-4)} (streak: ${streak})`);
});
}
});
}
}
export async function isActivated(address: string, provider: Provider) {
const atiaContract = getAtiaContract(provider);
const [currentStreakCount] = await atiaContract.getStreak(address);
const [isLostStreak, hasPrayedToday] = await atiaContract.getActivationStatus(
address,
{
gasPrice: parseUnits("20", "gwei"),
}
);
return { status: hasPrayedToday, streak: Number(currentStreakCount) };
}
export async function activateStreak(signer: Signer | Provider, delegatee: string) {
const atiaContract = getAtiaContract(signer);
try {
const [currentStreakCount] = await atiaContract.getStreak(
delegatee,
{
gasPrice: parseUnits("20", "gwei"),
}
);
const tx = await atiaContract.activateStreak(
delegatee,
{
gasPrice: parseUnits("20", "gwei"),
}
);
await tx.wait();
return { status: true, streak: Number(currentStreakCount) + 1 };
} catch (e: unknown) {
console.error(e);
console.error(`⚠️ ${PREFIX}: Failed to pray for ${delegatee.slice(-4)}`);
return { status: false, streak: 0 };
}
}
export async function getStreakDetails(address: string, provider: Provider) {
const atiaContract = getAtiaContract(provider);
const [currentStreakCount, lastActivated, longestStreakCount, lostStreakCount] = await atiaContract.getStreak(address);
return {
currentStreak: Number(currentStreakCount),
lastActivated: Number(lastActivated),
longestStreak: Number(longestStreakCount),
lostStreaks: Number(lostStreakCount)
};
}