axie-tools
v1.8.0
Published
TypeScript SDK for building Axie Infinity trading bots and AI agents on Ronin network. Programmatic marketplace operations for Axies, Materials, and Consumables (buy/sell/delist), batch transfers, floor price detection, and wallet management. Includes int
Downloads
261
Maintainers
Keywords
Readme
Axie Tools
import { buyMarketplaceOrder, approveWETH, createProvider } from "axie-tools";
import { Wallet } from "ethers";
const provider = createProvider(process.env.SKYMAVIS_API_KEY);
const wallet = new Wallet(process.env.PRIVATE_KEY, provider);
await approveWETH(wallet);
const receipt = await buyMarketplaceOrder(
12345, // Axie ID
wallet,
process.env.MARKETPLACE_ACCESS_TOKEN,
process.env.SKYMAVIS_API_KEY,
);TypeScript SDK for building Axie Infinity trading bots and AI agents on Ronin network. Automate marketplace operations: buy, sell, list, and transfer Axies and Materials programmatically. Built-in floor price detection, batch transfers, and token management. Includes an interactive CLI for manual use.
Quick start
npm install axie-tools ethers dotenvSet up your credentials in a .env file:
PRIVATE_KEY="your_ronin_wallet_private_key"
MARKETPLACE_ACCESS_TOKEN="your_access_token"
SKYMAVIS_API_KEY="your_api_key"
# Optional: override the default Ronin public RPC
RONIN_RPC_URL="https://api.roninchain.com/rpc"You need:
- A Ronin wallet private key
- A marketplace access token from app.axieinfinity.com
- A SkyMavis API key from the Developer Console for marketplace API calls
- Optional: a custom Ronin RPC URL if you do not want to use the default public endpoint (
https://api.roninchain.com/rpc)
Check floor price and buy an Axie
import { getAxieFloorPrice, buyMarketplaceOrder, approveWETH, createProvider } from "axie-tools";
import { Wallet } from "ethers";
import "dotenv/config";
const provider = createProvider(process.env.SKYMAVIS_API_KEY);
const wallet = new Wallet(process.env.PRIVATE_KEY, provider);
// Check the floor price first
const floorPrice = await getAxieFloorPrice(process.env.SKYMAVIS_API_KEY);
console.log(`Current floor: ${floorPrice} WETH`);
// Approve WETH spending (one-time)
await approveWETH(wallet);
// Buy a specific Axie
const receipt = await buyMarketplaceOrder(
12345, // Axie ID to buy
wallet,
process.env.MARKETPLACE_ACCESS_TOKEN,
process.env.SKYMAVIS_API_KEY,
);
console.log(`TX: https://app.roninchain.com/tx/${receipt.hash}`);List all your Axies for sale
import { getAxieIdsFromAccount, createMarketplaceOrder, approveMarketplaceContract, createProvider } from "axie-tools";
import { Wallet, parseEther } from "ethers";
import "dotenv/config";
const provider = createProvider(process.env.SKYMAVIS_API_KEY);
const wallet = new Wallet(process.env.PRIVATE_KEY, provider);
const address = await wallet.getAddress();
await approveMarketplaceContract(wallet);
const axieIds = await getAxieIdsFromAccount(address, provider);
const block = await provider.getBlock("latest");
for (const axieId of axieIds) {
await createMarketplaceOrder(
{
address,
axieId: axieId.toString(),
basePrice: parseEther("0.01").toString(),
endedPrice: "0",
startedAt: block.timestamp,
endedAt: 0,
expiredAt: block.timestamp + 15634800,
},
process.env.MARKETPLACE_ACCESS_TOKEN,
wallet,
process.env.SKYMAVIS_API_KEY,
);
}API reference
Market data
| Function | Description |
| --- | --- |
| getAxieFloorPrice(apiKey) | Current floor price for Axies |
| getMaterialFloorPrice(materialId, apiKey, quantity?) | Current floor price for a material |
| getAxieIdsFromAccount(address, provider) | List all Axie IDs owned by an address |
| getAccountInfo(address, provider, apiKey) | Wallet balances, allowances, and approval status |
| validateMaterialToken(materialId, apiKey) | Check if a material token ID exists |
| getTokenExpirationInfo(token) | Check when an access token expires |
| getGasPrice(signerOrProvider, options?) | Current network gas price or a supplied override |
Trading
| Function | Description |
| --- | --- |
| buyMarketplaceOrder(axieId, wallet, token, apiKey) | Buy a listed Axie |
| createMarketplaceOrder(orderData, token, wallet, apiKey) | List an Axie for sale or auction |
| cancelMarketplaceOrder(axieId, wallet, apiKey) | Cancel an Axie listing |
| buyMaterialOrder(materialId, quantity, wallet, token, apiKey) | Buy listed materials |
| createMaterialMarketplaceOrder(orderData, token, wallet, apiKey) | List materials for sale |
| cancelMaterialOrder(materialId, wallet, apiKey) | Cancel a material listing |
Transfers
| Function | Description |
| --- | --- |
| transferAxie(wallet, to, axieId) | Transfer a single Axie |
| batchTransferAxies(wallet, to, axieIds) | Transfer up to 100 Axies in one transaction |
Setup (one-time approvals)
| Function | Description |
| --- | --- |
| createProvider(apiKey, rpcUrl?) | Connect to Ronin network using RONIN_RPC_URL, rpcUrl, or the default public RPC |
| approveWETH(wallet) | Approve WETH spending for the marketplace |
| approveMarketplaceContract(wallet) | Approve marketplace to handle your Axies |
| approveMaterialMarketplace(wallet) | Approve marketplace to handle your materials |
| approveBatchTransfer(wallet) | Approve batch transfer contract |
Gas price options
Transaction helpers accept an optional GasPriceOptions parameter to customize gas pricing:
import { parseUnits } from "ethers";
import { transferAxie, buyMarketplaceOrder } from "axie-tools";
// Use dynamic gas price from the network.
await transferAxie(signer, recipientAddress, axieId);
// Or pass a custom gas price.
const customGasPrice = parseUnits("30", "gwei");
await transferAxie(signer, recipientAddress, axieId, {
gasPrice: customGasPrice,
});
await buyMarketplaceOrder(axieId, wallet, token, apiKey, {
gasPrice: customGasPrice,
});By default, transaction helpers fetch the current gas price from the network. If fetching fails, helpers fall back to 26 gwei.
Contracts
| Function | Description |
| --- | --- |
| getAxieContract(provider) | Axie NFT contract instance |
| getWETHContract(provider) | WETH token contract instance |
| getUSDCContract(provider) | USDC token contract instance |
Auth
| Function | Description |
| --- | --- |
| refreshToken(refreshToken) | Refresh an expired access token |
| ensureMarketplaceToken() | Validate and refresh token if needed |
Bot examples
Ready-to-use bot templates in the examples folder:
| Bot | Description | | --- | --- | | floor-sniper.js | Polls floor price, auto-buys when it drops below target | | auto-lister.js | Lists all owned Axies at floor price with configurable markup |
cd examples && npm install
# Snipe Axies below 0.001 WETH, check every 30 seconds
node floor-sniper.js 0.001 30
# List all your Axies at floor + 10%
node auto-lister.js 1.1Single operation scripts
| Script | Description | | --- | --- | | settle-order.js | Buy an Axie by ID | | create-order.js | List an Axie at a fixed price | | create-order-auction.js | Create a Dutch auction | | cancel-order.js | Cancel a listing | | material-order.js | List materials for sale | | transfer-all.js | Batch transfer all Axies |
CLI
For manual operations and testing, use the interactive CLI:
npx axie-tools[!TIP] Create a
.envfile from.env.exampleto avoid entering values every time.
The CLI provides: account info, token refresh, WETH/marketplace approvals, create/cancel/buy orders for Axies and Materials, auctions, bulk operations, and transfers. For automation, use the library directly.
Building from source
git clone https://github.com/alexx855/axie-tools.git
cd axie-tools
npm install
npm run buildGetting your access token
Log into app.axieinfinity.com, open dev tools, go to Application > Local storage > https://app.axieinfinity.com, and copy the accessToken value.
Screenshot showing where to find it
Troubleshooting
| Error | Fix |
| --- | --- |
| "Signer is not maker" | Access token expired. Re-login and grab a fresh token. |
| "Insufficient WETH allowance" | Run approveWETH(wallet) first. |
| "Marketplace contract not approved" | Run approveMarketplaceContract(wallet) or approveMaterialMarketplace(wallet). |
| Transactions failing | Not enough RON for gas. Top up your wallet. |
| API connection problems | Check your SKYMAVIS_API_KEY at the developer console. |
| RPC connection problems | Set RONIN_RPC_URL to another Ronin-compatible provider such as dRPC, Alchemy, Chainstack, or Moralis. |
| "Material token not found" | Invalid material ID. Use validateMaterialToken() to verify. |
Important notes
- Requires Node.js 22 or newer.
- All trading uses WETH, not ETH. Ensure your wallet has enough WETH before buying.
- Listing items is off-chain but requires contract approvals first. Buying and canceling are on-chain transactions.
MARKETPLACE_ACCESS_TOKENexpires periodically. For long-running bots, userefreshToken()andgetTokenExpirationInfo()to keep it fresh.- Marketplace API and public RPC providers have rate limits. Use reasonable poll intervals (30s+) in bot loops.
Testing
Tests use Bun and require environment variables:
# Axie tests
AXIE_ID=123456 PRICE=0.1 bun test tests/create-order-axie.test.ts --timeout 30000
AXIE_ID=123456 bun test tests/cancel-order-axie.test.ts --timeout 30000
AXIE_ID=123456 bun test tests/settle-order-axie.test.ts --timeout 30000
bun test tests/create-orders-all-axies.test.ts --timeout 60000
# Material tests
MATERIAL_ID=1099511627776 QUANTITY=5 PRICE=0.001 bun test tests/create-order-materials.test.ts --timeout 30000
MATERIAL_ID=1099511627776 bun test tests/cancel-order-materials.test.ts --timeout 30000
MATERIAL_ID=1099511627776 QUANTITY=5 PRICE=0.001 bun test tests/settle-order-materials.test.ts --timeout 30000
# Floor price tests
AXIE_ID=1 bun test tests/axie-floor-price.test.ts --timeout 45000
MATERIAL_ID=1099511627776 bun test tests/material-floor-price.test.ts --timeout 30000Contributing
Check the Contributing Guidelines for details. Open an issue for bugs or ideas.
License
Released under the MIT License. See the LICENSE file.
