Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 176 additions & 8 deletions cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,22 @@ import {
createProvider,
validateMaterialToken,
getMaterialFloorPrice,
validateConsumableToken,
getConsumableFloorPrice,
getAxieFloorPrice,
approveMarketplaceContract,
approveMaterialMarketplace,
approveConsumableMarketplace,
approveWETH,
buyMarketplaceOrder,
buyMaterialOrder,
buyConsumableOrder,
cancelMarketplaceOrder,
cancelMaterialOrder,
cancelConsumableOrder,
createMarketplaceOrder,
createMaterialMarketplaceOrder,
createConsumableMarketplaceOrder,
} from "./index";
import "dotenv/config";

Expand Down Expand Up @@ -79,6 +85,46 @@ const getMaterialId = async (skyMavisApiKey: string) => {
return response.materialId;
};

const getConsumableId = async (skyMavisApiKey: string) => {
const response = await prompts({
type: "text",
name: "consumableId",
message: "🆔 Enter Consumable ID:",
validate: (value: string) => value !== undefined && value.length > 0,
});
if (response.consumableId === undefined) {
console.log("❌ Invalid Consumable ID!");
return null;
}

console.log("🔍 Validating consumable token...");
const consumableInfo = await validateConsumableToken(
response.consumableId,
skyMavisApiKey,
);

if (!consumableInfo) {
console.log("❌ Consumable ID not found or invalid!");
return null;
}

console.log(`✅ Found consumable: ${consumableInfo.name}`);
console.log(`📄 Description: ${consumableInfo.description}`);
console.log(`📦 Total Supply: ${consumableInfo.totalSupply}`);
console.log(`👥 Total Owners: ${consumableInfo.totalOwners}`);
if (consumableInfo.minPrice) {
console.log(
`💰 Min Price: ${(Number(consumableInfo.minPrice) / 1e18).toFixed(6)} WETH`,
);
}
if (consumableInfo.orders) {
console.log(`🛒 Listed Quantity: ${consumableInfo.orders.totalListed}`);
console.log(`📋 Total Orders: ${consumableInfo.orders.totalOrders}`);
}

return response.consumableId;
};

const getQuantity = async (optional = false) => {
const message = optional
? "📦 Enter Quantity (leave empty to use all available):"
Expand All @@ -105,16 +151,12 @@ const getPrice = async (
skyMavisApiKey?: string,
quantity?: number,
isAxie = false,
customMessage?: string,
consumableId?: string,
) => {
let message: string;
if (customMessage) {
message = customMessage;
} else {
message = optional
? "💰 Enter Price (in WETH, leave empty to use floor price):"
: "💰 Enter Price (in WETH):";
}
message = optional
? "💰 Enter Price (in WETH, leave empty to use floor price):"
: "💰 Enter Price (in WETH):";

const response = await prompts({
type: "text",
Expand All @@ -141,6 +183,12 @@ const getPrice = async (
skyMavisApiKey,
quantity,
);
} else if (consumableId) {
floorPrice = await getConsumableFloorPrice(
consumableId,
skyMavisApiKey,
quantity,
);
}

if (!floorPrice) {
Expand Down Expand Up @@ -218,16 +266,28 @@ async function main() {
title: "Approve Material marketplace",
value: "approve-material-marketplace",
},
{
title: "Approve Consumable marketplace",
value: "approve-consumable-marketplace",
},
{ title: "Settle axie order (buy axie)", value: "settle" },
{
title: "Settle material order (buy material)",
value: "settle-material",
},
{
title: "Settle consumable order (buy consumable)",
value: "settle-consumable",
},
{ title: "Cancel axie order (delist axie)", value: "cancel" },
{
title: "Cancel material order (delist materials)",
value: "cancel-material",
},
{
title: "Cancel consumable order (delist consumables)",
value: "cancel-consumable",
},
{
title: "Cancel all axie orders (delist all axies)",
value: "cancel-all",
Expand All @@ -237,6 +297,10 @@ async function main() {
title: "Create material order (list material)",
value: "create-material",
},
{
title: "Create consumable order (list consumable)",
value: "create-consumable",
},
{
title: "Create axie auction (list axie for auction)",
value: "create-auction",
Expand Down Expand Up @@ -330,6 +394,10 @@ async function main() {
await approveMaterialMarketplace(wallet);
break;
}
case "approve-consumable-marketplace": {
await approveConsumableMarketplace(wallet);
break;
}
case "settle": {
const token = await ensureMarketplaceToken();
const axieId = await getAxieId();
Expand Down Expand Up @@ -373,6 +441,29 @@ async function main() {
}
break;
}
case "settle-consumable": {
const token = await ensureMarketplaceToken();
const consumableId = await getConsumableId(skyMavisApiKey);
if (!consumableId) break;
const quantity = await getQuantity();
if (!quantity) break;
await approveWETH(wallet);
const receipt = await buyConsumableOrder(
consumableId,
quantity,
wallet,
token,
skyMavisApiKey,
);
if (receipt) {
console.log("🚀 Transaction successful! Hash:", receipt.hash);
console.log(
"🔗 View transaction: https://app.roninchain.com/tx/" +
receipt.hash,
);
}
break;
}
case "create": {
const axieId = await getAxieId();
if (!axieId) break;
Expand Down Expand Up @@ -471,6 +562,57 @@ async function main() {
);
break;
}
case "create-consumable": {
const consumableId = await getConsumableId(skyMavisApiKey);
if (!consumableId) break;
const quantity = await getQuantity(true); // Optional quantity
const price = await getPrice(
true,
undefined,
skyMavisApiKey,
quantity,
false,
consumableId,
); // Optional price with floor price fallback
if (!price) break;

const token = await ensureMarketplaceToken();
await approveConsumableMarketplace(wallet);

const currentBlock = await provider.getBlock("latest");
const startedAt = currentBlock!.timestamp;
const expiredAt = startedAt + 15634800; // ~6 months

const orderData = {
address,
consumableId: consumableId.toString(),
quantity: quantity ? quantity.toString() : undefined,
unitPrice: parseEther(price).toString(),
endedUnitPrice: "0",
startedAt,
endedAt: 0,
expiredAt,
};

const result = await createConsumableMarketplaceOrder(
orderData,
token,
wallet,
skyMavisApiKey,
);
if (result === null || result.errors || !result.data) {
console.error(
"❌ Error:",
result?.errors?.[0]?.message || "Unknown error",
);
break;
}

console.log(
`✅ Created consumable order for Consumable ${consumableId}${quantity ? ` (qty: ${quantity})` : " (all available)"}! Current price in USD: ${result.data.createOrder.currentPriceUsd}`,
);
break;
}
case "create-auction": {
const axieId = await getAxieId();
if (!axieId) break;
Expand Down Expand Up @@ -753,6 +895,32 @@ async function main() {
}
break;
}
case "cancel-consumable": {
const consumableId = await getConsumableId(skyMavisApiKey);
if (!consumableId) break;

const result = await cancelConsumableOrder(
consumableId,
wallet,
skyMavisApiKey,
);
if (result && "canceled" in result && result.canceled > 0) {
console.log(
`✅ Successfully cancelled ${result.canceled} consumable order(s)!`,
);
if (result.canceledOrders.length > 0) {
result.canceledOrders.forEach((order) => {
console.log(
"🔗 View transaction: https://app.roninchain.com/tx/" +
order.transactionHash,
);
});
}
} else if (result && "message" in result) {
console.log("❌", result.message);
}
break;
}
case "cancel-all": {
const fromAddress = await wallet.getAddress();
let axieIds = await getAxieIdsFromAccount(fromAddress, provider);
Expand Down
Loading