mantle-agent-kit-sdk 1.0.3 → 1.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/README.md +192 -87
- package/dist/index.cjs +2637 -169
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2153 -261
- package/dist/index.d.ts +2153 -261
- package/dist/index.js +2604 -172
- package/dist/index.js.map +1 -1
- package/package.json +19 -3
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseUnits, parseEther, encodeFunctionData,
|
|
1
|
+
import { parseUnits, parseEther, encodeFunctionData, getAddress, parseAbiItem, encodeAbiParameters, parseAbiParameters, erc20Abi as erc20Abi$1, createWalletClient, http, publicActions } from 'viem';
|
|
2
2
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
3
3
|
import { mantle, mantleSepoliaTestnet } from 'viem/chains';
|
|
4
4
|
import { getTransactionReceipt } from 'viem/actions';
|
|
@@ -465,8 +465,8 @@ async function approveToken2(agent, tokenAddress, spenderAddress, amount) {
|
|
|
465
465
|
return { approved: true, txHash: null };
|
|
466
466
|
}
|
|
467
467
|
console.log("Insufficient allowance, approving tokens...");
|
|
468
|
-
const { encodeFunctionData:
|
|
469
|
-
const approveData =
|
|
468
|
+
const { encodeFunctionData: encodeFunctionData14 } = await import('viem');
|
|
469
|
+
const approveData = encodeFunctionData14({
|
|
470
470
|
abi: erc20Abi$1,
|
|
471
471
|
functionName: "approve",
|
|
472
472
|
args: [spenderAddress, BigInt(amount)]
|
|
@@ -495,6 +495,9 @@ async function swapOnOpenOcean(agent, fromToken, toToken, amount, slippage = "1"
|
|
|
495
495
|
if (agent.demo) {
|
|
496
496
|
return createMockOpenOceanSwapResponse(amount);
|
|
497
497
|
}
|
|
498
|
+
if (!agent.demo && agent.chain != "mainnet") {
|
|
499
|
+
throw new Error("Openocean swaps happen only on mainnet");
|
|
500
|
+
}
|
|
498
501
|
const walletAddress = agent.account.address;
|
|
499
502
|
if (fromToken.toLowerCase() !== NATIVE_TOKEN_ADDRESS.toLowerCase()) {
|
|
500
503
|
await approveToken2(agent, fromToken, OPENOCEAN_EXCHANGE_PROXY, amount);
|
|
@@ -944,8 +947,10 @@ __export(lendle_exports, {
|
|
|
944
947
|
LENDING_POOL: () => LENDING_POOL,
|
|
945
948
|
LENDING_POOL_ABI: () => LENDING_POOL_ABI,
|
|
946
949
|
LENDING_POOL_ADDRESSES_PROVIDER: () => LENDING_POOL_ADDRESSES_PROVIDER,
|
|
950
|
+
LENDLE_SUPPORTED_ASSETS: () => LENDLE_SUPPORTED_ASSETS,
|
|
947
951
|
ORACLE: () => ORACLE,
|
|
948
952
|
PROTOCOL_DATA_PROVIDER: () => PROTOCOL_DATA_PROVIDER,
|
|
953
|
+
PROTOCOL_DATA_PROVIDER_ABI: () => PROTOCOL_DATA_PROVIDER_ABI,
|
|
949
954
|
WMNT_ADDRESS: () => WMNT_ADDRESS2
|
|
950
955
|
});
|
|
951
956
|
var LENDING_POOL = {
|
|
@@ -1060,6 +1065,65 @@ var LENDING_POOL_ABI = [
|
|
|
1060
1065
|
type: "function"
|
|
1061
1066
|
}
|
|
1062
1067
|
];
|
|
1068
|
+
var PROTOCOL_DATA_PROVIDER_ABI = [
|
|
1069
|
+
{
|
|
1070
|
+
inputs: [],
|
|
1071
|
+
name: "getAllReservesTokens",
|
|
1072
|
+
outputs: [
|
|
1073
|
+
{
|
|
1074
|
+
components: [
|
|
1075
|
+
{ name: "symbol", type: "string" },
|
|
1076
|
+
{ name: "tokenAddress", type: "address" }
|
|
1077
|
+
],
|
|
1078
|
+
name: "",
|
|
1079
|
+
type: "tuple[]"
|
|
1080
|
+
}
|
|
1081
|
+
],
|
|
1082
|
+
stateMutability: "view",
|
|
1083
|
+
type: "function"
|
|
1084
|
+
},
|
|
1085
|
+
{
|
|
1086
|
+
inputs: [
|
|
1087
|
+
{ name: "asset", type: "address" },
|
|
1088
|
+
{ name: "user", type: "address" }
|
|
1089
|
+
],
|
|
1090
|
+
name: "getUserReserveData",
|
|
1091
|
+
outputs: [
|
|
1092
|
+
{ name: "currentATokenBalance", type: "uint256" },
|
|
1093
|
+
{ name: "currentStableDebt", type: "uint256" },
|
|
1094
|
+
{ name: "currentVariableDebt", type: "uint256" },
|
|
1095
|
+
{ name: "principalStableDebt", type: "uint256" },
|
|
1096
|
+
{ name: "scaledVariableDebt", type: "uint256" },
|
|
1097
|
+
{ name: "stableBorrowRate", type: "uint256" },
|
|
1098
|
+
{ name: "liquidityRate", type: "uint256" },
|
|
1099
|
+
{ name: "stableRateLastUpdated", type: "uint40" },
|
|
1100
|
+
{ name: "usageAsCollateralEnabled", type: "bool" }
|
|
1101
|
+
],
|
|
1102
|
+
stateMutability: "view",
|
|
1103
|
+
type: "function"
|
|
1104
|
+
},
|
|
1105
|
+
{
|
|
1106
|
+
inputs: [{ name: "asset", type: "address" }],
|
|
1107
|
+
name: "getReserveTokensAddresses",
|
|
1108
|
+
outputs: [
|
|
1109
|
+
{ name: "aTokenAddress", type: "address" },
|
|
1110
|
+
{ name: "stableDebtTokenAddress", type: "address" },
|
|
1111
|
+
{ name: "variableDebtTokenAddress", type: "address" }
|
|
1112
|
+
],
|
|
1113
|
+
stateMutability: "view",
|
|
1114
|
+
type: "function"
|
|
1115
|
+
}
|
|
1116
|
+
];
|
|
1117
|
+
var LENDLE_SUPPORTED_ASSETS = {
|
|
1118
|
+
mainnet: [
|
|
1119
|
+
{ symbol: "WMNT", address: "0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8" },
|
|
1120
|
+
{ symbol: "WETH", address: "0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111" },
|
|
1121
|
+
{ symbol: "USDC", address: "0x09Bc4E0D10C81b3a3766c49F0f98a8aaa7adA8D2" },
|
|
1122
|
+
{ symbol: "USDT", address: "0x201EBa5CC46D216Ce6DC03F6a759e8E766e956aE" },
|
|
1123
|
+
{ symbol: "mETH", address: "0xcDA86A272531e8640cD7F1a92c01839911B90bb0" }
|
|
1124
|
+
],
|
|
1125
|
+
testnet: []
|
|
1126
|
+
};
|
|
1063
1127
|
|
|
1064
1128
|
// src/tools/lendle/supply.ts
|
|
1065
1129
|
async function lendleSupply(agent, tokenAddress, amount) {
|
|
@@ -1165,6 +1229,67 @@ async function lendleRepay(agent, tokenAddress, amount, rateMode = INTEREST_RATE
|
|
|
1165
1229
|
await agent.client.waitForTransactionReceipt({ hash });
|
|
1166
1230
|
return hash;
|
|
1167
1231
|
}
|
|
1232
|
+
async function lendleGetPositions(agent, userAddress) {
|
|
1233
|
+
const dataProviderAddress = PROTOCOL_DATA_PROVIDER[agent.chain];
|
|
1234
|
+
const address = userAddress || agent.account.address;
|
|
1235
|
+
if (dataProviderAddress === "0x0000000000000000000000000000000000000000") {
|
|
1236
|
+
throw new Error(
|
|
1237
|
+
`Lendle ProtocolDataProvider not configured for ${agent.chain}. Only available on mainnet.`
|
|
1238
|
+
);
|
|
1239
|
+
}
|
|
1240
|
+
const supportedAssets = LENDLE_SUPPORTED_ASSETS[agent.chain];
|
|
1241
|
+
if (!supportedAssets || supportedAssets.length === 0) {
|
|
1242
|
+
throw new Error(`No supported assets configured for ${agent.chain}`);
|
|
1243
|
+
}
|
|
1244
|
+
const positions = [];
|
|
1245
|
+
let totalSupplied = 0n;
|
|
1246
|
+
let totalDebt = 0n;
|
|
1247
|
+
for (const asset of supportedAssets) {
|
|
1248
|
+
try {
|
|
1249
|
+
const assetAddress = getAddress(asset.address);
|
|
1250
|
+
const result = await agent.client.readContract({
|
|
1251
|
+
address: dataProviderAddress,
|
|
1252
|
+
abi: PROTOCOL_DATA_PROVIDER_ABI,
|
|
1253
|
+
functionName: "getUserReserveData",
|
|
1254
|
+
args: [assetAddress, address]
|
|
1255
|
+
});
|
|
1256
|
+
const [
|
|
1257
|
+
currentATokenBalance,
|
|
1258
|
+
currentStableDebt,
|
|
1259
|
+
currentVariableDebt,
|
|
1260
|
+
_principalStableDebt,
|
|
1261
|
+
_scaledVariableDebt,
|
|
1262
|
+
stableBorrowRate,
|
|
1263
|
+
liquidityRate,
|
|
1264
|
+
_stableRateLastUpdated,
|
|
1265
|
+
usageAsCollateralEnabled
|
|
1266
|
+
] = result;
|
|
1267
|
+
if (currentATokenBalance > 0n || currentStableDebt > 0n || currentVariableDebt > 0n) {
|
|
1268
|
+
const assetTotalDebt = currentStableDebt + currentVariableDebt;
|
|
1269
|
+
positions.push({
|
|
1270
|
+
asset: assetAddress,
|
|
1271
|
+
symbol: asset.symbol,
|
|
1272
|
+
supplied: currentATokenBalance,
|
|
1273
|
+
stableDebt: currentStableDebt,
|
|
1274
|
+
variableDebt: currentVariableDebt,
|
|
1275
|
+
totalDebt: assetTotalDebt,
|
|
1276
|
+
liquidityRate,
|
|
1277
|
+
stableBorrowRate,
|
|
1278
|
+
usageAsCollateralEnabled
|
|
1279
|
+
});
|
|
1280
|
+
totalSupplied += currentATokenBalance;
|
|
1281
|
+
totalDebt += assetTotalDebt;
|
|
1282
|
+
}
|
|
1283
|
+
} catch (error) {
|
|
1284
|
+
console.warn(`Failed to get position for ${asset.symbol}:`, error);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
return {
|
|
1288
|
+
positions,
|
|
1289
|
+
totalSupplied,
|
|
1290
|
+
totalDebt
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1168
1293
|
|
|
1169
1294
|
// src/constants/agni/index.ts
|
|
1170
1295
|
var agni_exports = {};
|
|
@@ -1327,197 +1452,2198 @@ async function merchantMoeSwap(agent, tokenIn, tokenOut, amountIn, slippagePerce
|
|
|
1327
1452
|
// src/constants/meth/index.ts
|
|
1328
1453
|
var meth_exports = {};
|
|
1329
1454
|
__export(meth_exports, {
|
|
1330
|
-
|
|
1455
|
+
METH_ABI: () => METH_ABI,
|
|
1456
|
+
METH_TOKEN: () => METH_TOKEN,
|
|
1457
|
+
NATIVE_MNT_ADDRESS: () => NATIVE_MNT_ADDRESS,
|
|
1458
|
+
WETH_TOKEN: () => WETH_TOKEN,
|
|
1459
|
+
WMNT_TOKEN: () => WMNT_TOKEN
|
|
1331
1460
|
});
|
|
1332
1461
|
var METH_TOKEN = {
|
|
1333
1462
|
mainnet: "0xcDA86A272531e8640cD7F1a92c01839911B90bb0",
|
|
1334
1463
|
testnet: "0x0000000000000000000000000000000000000000"
|
|
1335
1464
|
};
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
if (agent.demo) {
|
|
1340
|
-
return createMockQuoteResponse("OKX", amount);
|
|
1341
|
-
}
|
|
1342
|
-
const chainIndex = agent.chain === "mainnet" ? "5000" : "5003";
|
|
1343
|
-
return getSwapTransaction(from, to, amount, chainIndex, slippagePercentage);
|
|
1465
|
+
var WETH_TOKEN = {
|
|
1466
|
+
mainnet: "0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111",
|
|
1467
|
+
testnet: "0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111"
|
|
1344
1468
|
};
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
var
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1469
|
+
var WMNT_TOKEN = {
|
|
1470
|
+
mainnet: "0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8",
|
|
1471
|
+
testnet: "0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8"
|
|
1472
|
+
};
|
|
1473
|
+
var NATIVE_MNT_ADDRESS = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
1474
|
+
var METH_ABI = [
|
|
1475
|
+
{
|
|
1476
|
+
inputs: [{ name: "account", type: "address" }],
|
|
1477
|
+
name: "balanceOf",
|
|
1478
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
1479
|
+
stateMutability: "view",
|
|
1480
|
+
type: "function"
|
|
1481
|
+
},
|
|
1482
|
+
{
|
|
1483
|
+
inputs: [],
|
|
1484
|
+
name: "totalSupply",
|
|
1485
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
1486
|
+
stateMutability: "view",
|
|
1487
|
+
type: "function"
|
|
1488
|
+
},
|
|
1489
|
+
{
|
|
1490
|
+
inputs: [],
|
|
1491
|
+
name: "decimals",
|
|
1492
|
+
outputs: [{ name: "", type: "uint8" }],
|
|
1493
|
+
stateMutability: "view",
|
|
1494
|
+
type: "function"
|
|
1495
|
+
},
|
|
1496
|
+
{
|
|
1497
|
+
inputs: [],
|
|
1498
|
+
name: "symbol",
|
|
1499
|
+
outputs: [{ name: "", type: "string" }],
|
|
1500
|
+
stateMutability: "view",
|
|
1501
|
+
type: "function"
|
|
1502
|
+
},
|
|
1503
|
+
{
|
|
1504
|
+
inputs: [
|
|
1505
|
+
{ name: "spender", type: "address" },
|
|
1506
|
+
{ name: "amount", type: "uint256" }
|
|
1507
|
+
],
|
|
1508
|
+
name: "approve",
|
|
1509
|
+
outputs: [{ name: "", type: "bool" }],
|
|
1510
|
+
stateMutability: "nonpayable",
|
|
1511
|
+
type: "function"
|
|
1512
|
+
},
|
|
1513
|
+
{
|
|
1514
|
+
inputs: [
|
|
1515
|
+
{ name: "owner", type: "address" },
|
|
1516
|
+
{ name: "spender", type: "address" }
|
|
1517
|
+
],
|
|
1518
|
+
name: "allowance",
|
|
1519
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
1520
|
+
stateMutability: "view",
|
|
1521
|
+
type: "function"
|
|
1353
1522
|
}
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
const
|
|
1358
|
-
const
|
|
1359
|
-
const
|
|
1360
|
-
|
|
1361
|
-
headers: { "Content-Type": "application/json" }
|
|
1362
|
-
});
|
|
1363
|
-
if (!response.ok) {
|
|
1364
|
-
if (response.status === 404) {
|
|
1365
|
-
throw new Error(
|
|
1366
|
-
"Platform: Project not found. Invalid APP_ID. Please check your APP_ID configuration."
|
|
1367
|
-
);
|
|
1368
|
-
}
|
|
1369
|
-
if (response.status === 401) {
|
|
1370
|
-
throw new Error(
|
|
1371
|
-
"Platform: Unauthorized. Invalid APP_ID. Please verify your APP_ID."
|
|
1372
|
-
);
|
|
1373
|
-
}
|
|
1523
|
+
];
|
|
1524
|
+
async function methGetPosition(agent, userAddress) {
|
|
1525
|
+
const methTokenAddress = METH_TOKEN[agent.chain];
|
|
1526
|
+
const wethTokenAddress = WETH_TOKEN[agent.chain];
|
|
1527
|
+
const wmntTokenAddress = WMNT_TOKEN[agent.chain];
|
|
1528
|
+
const address = userAddress || agent.account.address;
|
|
1529
|
+
if (methTokenAddress === "0x0000000000000000000000000000000000000000") {
|
|
1374
1530
|
throw new Error(
|
|
1375
|
-
`
|
|
1531
|
+
`mETH not available on ${agent.chain}. Only available on mainnet.`
|
|
1376
1532
|
);
|
|
1377
1533
|
}
|
|
1378
|
-
const
|
|
1379
|
-
|
|
1380
|
-
|
|
1534
|
+
const methBalance = await agent.client.readContract({
|
|
1535
|
+
address: methTokenAddress,
|
|
1536
|
+
abi: METH_ABI,
|
|
1537
|
+
functionName: "balanceOf",
|
|
1538
|
+
args: [address]
|
|
1539
|
+
});
|
|
1540
|
+
let wethBalance = 0n;
|
|
1541
|
+
try {
|
|
1542
|
+
wethBalance = await agent.client.readContract({
|
|
1543
|
+
address: wethTokenAddress,
|
|
1544
|
+
abi: METH_ABI,
|
|
1545
|
+
// Same ERC20 ABI works for WETH
|
|
1546
|
+
functionName: "balanceOf",
|
|
1547
|
+
args: [address]
|
|
1548
|
+
});
|
|
1549
|
+
} catch {
|
|
1381
1550
|
}
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1551
|
+
let wmntBalance = 0n;
|
|
1552
|
+
try {
|
|
1553
|
+
wmntBalance = await agent.client.readContract({
|
|
1554
|
+
address: wmntTokenAddress,
|
|
1555
|
+
abi: METH_ABI,
|
|
1556
|
+
// Same ERC20 ABI works for WMNT
|
|
1557
|
+
functionName: "balanceOf",
|
|
1558
|
+
args: [address]
|
|
1559
|
+
});
|
|
1560
|
+
} catch {
|
|
1386
1561
|
}
|
|
1387
1562
|
return {
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1563
|
+
methBalance,
|
|
1564
|
+
wethBalance,
|
|
1565
|
+
wmntBalance,
|
|
1566
|
+
methTokenAddress,
|
|
1567
|
+
wethTokenAddress,
|
|
1568
|
+
wmntTokenAddress
|
|
1393
1569
|
};
|
|
1394
1570
|
}
|
|
1395
|
-
async function
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
if (validationPromise) {
|
|
1400
|
-
return validationPromise;
|
|
1401
|
-
}
|
|
1402
|
-
let appId;
|
|
1403
|
-
if (typeof process !== "undefined" && process.env) {
|
|
1404
|
-
appId = process.env.APP_ID || process.env.NEXT_PUBLIC_APP_ID;
|
|
1405
|
-
}
|
|
1406
|
-
if (!appId || typeof appId !== "string" || appId.trim().length === 0) {
|
|
1571
|
+
async function swapToMeth(agent, amount, slippage = 0.5) {
|
|
1572
|
+
const methTokenAddress = METH_TOKEN[agent.chain];
|
|
1573
|
+
const wethTokenAddress = WETH_TOKEN[agent.chain];
|
|
1574
|
+
if (methTokenAddress === "0x0000000000000000000000000000000000000000") {
|
|
1407
1575
|
throw new Error(
|
|
1408
|
-
|
|
1576
|
+
`mETH not available on ${agent.chain}. Only available on mainnet.`
|
|
1409
1577
|
);
|
|
1410
1578
|
}
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1579
|
+
const result = await swapOnOpenOcean(
|
|
1580
|
+
agent,
|
|
1581
|
+
wethTokenAddress,
|
|
1582
|
+
methTokenAddress,
|
|
1583
|
+
amount,
|
|
1584
|
+
slippage.toString()
|
|
1585
|
+
);
|
|
1586
|
+
return result.txHash;
|
|
1419
1587
|
}
|
|
1420
|
-
function
|
|
1421
|
-
|
|
1588
|
+
async function swapFromMeth(agent, amount, slippage = 0.5) {
|
|
1589
|
+
const methTokenAddress = METH_TOKEN[agent.chain];
|
|
1590
|
+
const wethTokenAddress = WETH_TOKEN[agent.chain];
|
|
1591
|
+
if (methTokenAddress === "0x0000000000000000000000000000000000000000") {
|
|
1422
1592
|
throw new Error(
|
|
1423
|
-
|
|
1593
|
+
`mETH not available on ${agent.chain}. Only available on mainnet.`
|
|
1424
1594
|
);
|
|
1425
1595
|
}
|
|
1426
|
-
|
|
1596
|
+
const result = await swapOnOpenOcean(
|
|
1597
|
+
agent,
|
|
1598
|
+
methTokenAddress,
|
|
1599
|
+
wethTokenAddress,
|
|
1600
|
+
amount,
|
|
1601
|
+
slippage.toString()
|
|
1602
|
+
);
|
|
1603
|
+
return result.txHash;
|
|
1427
1604
|
}
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
}
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1605
|
+
|
|
1606
|
+
// src/constants/pikeperps/index.ts
|
|
1607
|
+
var pikeperps_exports = {};
|
|
1608
|
+
__export(pikeperps_exports, {
|
|
1609
|
+
BONDING_CURVE_MARKET: () => BONDING_CURVE_MARKET,
|
|
1610
|
+
BONDING_CURVE_MARKET_ABI: () => BONDING_CURVE_MARKET_ABI,
|
|
1611
|
+
PERPETUAL_TRADING: () => PERPETUAL_TRADING,
|
|
1612
|
+
PERPETUAL_TRADING_ABI: () => PERPETUAL_TRADING_ABI,
|
|
1613
|
+
PIKE_PERPS_CONFIG: () => PIKE_PERPS_CONFIG
|
|
1614
|
+
});
|
|
1615
|
+
var PERPETUAL_TRADING = {
|
|
1616
|
+
mainnet: "0x0000000000000000000000000000000000000000",
|
|
1617
|
+
// Not deployed yet
|
|
1618
|
+
testnet: "0x8081b646f349c049f2d5e8a400057d411dd657bd"
|
|
1619
|
+
};
|
|
1620
|
+
var BONDING_CURVE_MARKET = {
|
|
1621
|
+
mainnet: "0x0000000000000000000000000000000000000000",
|
|
1622
|
+
testnet: "0x93b268325A9862645c82b32229f3B52264750Ca2"
|
|
1623
|
+
};
|
|
1624
|
+
var PIKE_PERPS_CONFIG = {
|
|
1625
|
+
MAX_LEVERAGE: 100,
|
|
1626
|
+
DEFAULT_LEVERAGE: 10,
|
|
1627
|
+
MIN_LEVERAGE: 1,
|
|
1628
|
+
TRADING_FEE_BPS: 5,
|
|
1629
|
+
// 0.05%
|
|
1630
|
+
LIQUIDATION_REWARD_BPS: 500,
|
|
1631
|
+
// 5%
|
|
1632
|
+
PRICE_DECIMALS: 8
|
|
1633
|
+
// Prices are scaled by 1e8
|
|
1634
|
+
};
|
|
1635
|
+
var PERPETUAL_TRADING_ABI = [
|
|
1636
|
+
{
|
|
1637
|
+
inputs: [
|
|
1638
|
+
{ internalType: "address", name: "_pyth", type: "address" }
|
|
1639
|
+
],
|
|
1640
|
+
stateMutability: "nonpayable",
|
|
1641
|
+
type: "constructor"
|
|
1642
|
+
},
|
|
1643
|
+
{
|
|
1644
|
+
anonymous: false,
|
|
1645
|
+
inputs: [
|
|
1646
|
+
{ indexed: true, internalType: "uint256", name: "positionId", type: "uint256" },
|
|
1647
|
+
{ indexed: true, internalType: "address", name: "user", type: "address" },
|
|
1648
|
+
{ indexed: false, internalType: "uint256", name: "pnl", type: "uint256" },
|
|
1649
|
+
{ indexed: false, internalType: "uint256", name: "exitPrice", type: "uint256" }
|
|
1650
|
+
],
|
|
1651
|
+
name: "PositionClosed",
|
|
1652
|
+
type: "event"
|
|
1653
|
+
},
|
|
1654
|
+
{
|
|
1655
|
+
anonymous: false,
|
|
1656
|
+
inputs: [
|
|
1657
|
+
{ indexed: true, internalType: "uint256", name: "positionId", type: "uint256" },
|
|
1658
|
+
{ indexed: true, internalType: "address", name: "user", type: "address" },
|
|
1659
|
+
{ indexed: false, internalType: "uint256", name: "liquidationPrice", type: "uint256" }
|
|
1660
|
+
],
|
|
1661
|
+
name: "PositionLiquidated",
|
|
1662
|
+
type: "event"
|
|
1663
|
+
},
|
|
1664
|
+
{
|
|
1665
|
+
anonymous: false,
|
|
1666
|
+
inputs: [
|
|
1667
|
+
{ indexed: true, internalType: "uint256", name: "positionId", type: "uint256" },
|
|
1668
|
+
{ indexed: true, internalType: "address", name: "user", type: "address" },
|
|
1669
|
+
{ indexed: true, internalType: "address", name: "token", type: "address" },
|
|
1670
|
+
{ indexed: false, internalType: "bool", name: "isLong", type: "bool" },
|
|
1671
|
+
{ indexed: false, internalType: "uint256", name: "size", type: "uint256" },
|
|
1672
|
+
{ indexed: false, internalType: "uint256", name: "margin", type: "uint256" },
|
|
1673
|
+
{ indexed: false, internalType: "uint256", name: "leverage", type: "uint256" },
|
|
1674
|
+
{ indexed: false, internalType: "uint256", name: "entryPrice", type: "uint256" }
|
|
1675
|
+
],
|
|
1676
|
+
name: "PositionOpened",
|
|
1677
|
+
type: "event"
|
|
1678
|
+
},
|
|
1679
|
+
{
|
|
1680
|
+
inputs: [{ internalType: "uint256", name: "_positionId", type: "uint256" }],
|
|
1681
|
+
name: "closePosition",
|
|
1682
|
+
outputs: [],
|
|
1683
|
+
stateMutability: "nonpayable",
|
|
1684
|
+
type: "function"
|
|
1685
|
+
},
|
|
1686
|
+
{
|
|
1687
|
+
inputs: [{ internalType: "address", name: "_token", type: "address" }],
|
|
1688
|
+
name: "getCurrentPrice",
|
|
1689
|
+
outputs: [
|
|
1690
|
+
{ internalType: "uint256", name: "currentPrice", type: "uint256" },
|
|
1691
|
+
{ internalType: "bool", name: "hasPrice", type: "bool" }
|
|
1692
|
+
],
|
|
1693
|
+
stateMutability: "view",
|
|
1694
|
+
type: "function"
|
|
1695
|
+
},
|
|
1696
|
+
{
|
|
1697
|
+
inputs: [{ internalType: "uint256", name: "_positionId", type: "uint256" }],
|
|
1698
|
+
name: "getLiquidationPrice",
|
|
1699
|
+
outputs: [{ internalType: "uint256", name: "liquidationPrice", type: "uint256" }],
|
|
1700
|
+
stateMutability: "view",
|
|
1701
|
+
type: "function"
|
|
1702
|
+
},
|
|
1703
|
+
{
|
|
1704
|
+
inputs: [{ internalType: "uint256", name: "_positionId", type: "uint256" }],
|
|
1705
|
+
name: "getPosition",
|
|
1706
|
+
outputs: [
|
|
1707
|
+
{
|
|
1708
|
+
components: [
|
|
1709
|
+
{ internalType: "address", name: "user", type: "address" },
|
|
1710
|
+
{ internalType: "address", name: "token", type: "address" },
|
|
1711
|
+
{ internalType: "bool", name: "isLong", type: "bool" },
|
|
1712
|
+
{ internalType: "uint256", name: "size", type: "uint256" },
|
|
1713
|
+
{ internalType: "uint256", name: "margin", type: "uint256" },
|
|
1714
|
+
{ internalType: "uint256", name: "leverage", type: "uint256" },
|
|
1715
|
+
{ internalType: "uint256", name: "entryPrice", type: "uint256" },
|
|
1716
|
+
{ internalType: "uint256", name: "entryTime", type: "uint256" },
|
|
1717
|
+
{ internalType: "uint256", name: "lastFundingTime", type: "uint256" },
|
|
1718
|
+
{ internalType: "bool", name: "isOpen", type: "bool" }
|
|
1719
|
+
],
|
|
1720
|
+
internalType: "struct PerpetualTrading.Position",
|
|
1721
|
+
name: "",
|
|
1722
|
+
type: "tuple"
|
|
1723
|
+
}
|
|
1724
|
+
],
|
|
1725
|
+
stateMutability: "view",
|
|
1726
|
+
type: "function"
|
|
1727
|
+
},
|
|
1728
|
+
{
|
|
1729
|
+
inputs: [{ internalType: "uint256", name: "_positionId", type: "uint256" }],
|
|
1730
|
+
name: "getPositionPnL",
|
|
1731
|
+
outputs: [
|
|
1732
|
+
{ internalType: "uint256", name: "pnl", type: "uint256" },
|
|
1733
|
+
{ internalType: "bool", name: "isProfit", type: "bool" }
|
|
1734
|
+
],
|
|
1735
|
+
stateMutability: "view",
|
|
1736
|
+
type: "function"
|
|
1737
|
+
},
|
|
1738
|
+
{
|
|
1739
|
+
inputs: [{ internalType: "address", name: "_user", type: "address" }],
|
|
1740
|
+
name: "getUserPositions",
|
|
1741
|
+
outputs: [{ internalType: "uint256[]", name: "", type: "uint256[]" }],
|
|
1742
|
+
stateMutability: "view",
|
|
1743
|
+
type: "function"
|
|
1744
|
+
},
|
|
1745
|
+
{
|
|
1746
|
+
inputs: [{ internalType: "uint256", name: "_positionId", type: "uint256" }],
|
|
1747
|
+
name: "liquidatePosition",
|
|
1748
|
+
outputs: [],
|
|
1749
|
+
stateMutability: "nonpayable",
|
|
1750
|
+
type: "function"
|
|
1751
|
+
},
|
|
1752
|
+
{
|
|
1753
|
+
inputs: [],
|
|
1754
|
+
name: "maxLeverage",
|
|
1755
|
+
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
|
1756
|
+
stateMutability: "view",
|
|
1757
|
+
type: "function"
|
|
1758
|
+
},
|
|
1759
|
+
{
|
|
1760
|
+
inputs: [],
|
|
1761
|
+
name: "minMarginBps",
|
|
1762
|
+
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
|
1763
|
+
stateMutability: "view",
|
|
1764
|
+
type: "function"
|
|
1765
|
+
},
|
|
1766
|
+
{
|
|
1767
|
+
inputs: [],
|
|
1768
|
+
name: "nextPositionId",
|
|
1769
|
+
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
|
1770
|
+
stateMutability: "view",
|
|
1771
|
+
type: "function"
|
|
1772
|
+
},
|
|
1773
|
+
{
|
|
1774
|
+
inputs: [
|
|
1775
|
+
{ internalType: "address", name: "_token", type: "address" },
|
|
1776
|
+
{ internalType: "bool", name: "_isLong", type: "bool" },
|
|
1777
|
+
{ internalType: "uint256", name: "_margin", type: "uint256" },
|
|
1778
|
+
{ internalType: "uint256", name: "_leverage", type: "uint256" }
|
|
1779
|
+
],
|
|
1780
|
+
name: "openPosition",
|
|
1781
|
+
outputs: [{ internalType: "uint256", name: "positionId", type: "uint256" }],
|
|
1782
|
+
stateMutability: "payable",
|
|
1783
|
+
type: "function"
|
|
1784
|
+
},
|
|
1785
|
+
{
|
|
1786
|
+
inputs: [{ internalType: "uint256", name: "_positionId", type: "uint256" }],
|
|
1787
|
+
name: "shouldLiquidate",
|
|
1788
|
+
outputs: [{ internalType: "bool", name: "", type: "bool" }],
|
|
1789
|
+
stateMutability: "view",
|
|
1790
|
+
type: "function"
|
|
1791
|
+
},
|
|
1792
|
+
{
|
|
1793
|
+
inputs: [],
|
|
1794
|
+
name: "tradingFeeBps",
|
|
1795
|
+
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
|
1796
|
+
stateMutability: "view",
|
|
1797
|
+
type: "function"
|
|
1798
|
+
}
|
|
1799
|
+
];
|
|
1800
|
+
var BONDING_CURVE_MARKET_ABI = [
|
|
1801
|
+
{
|
|
1802
|
+
inputs: [{ internalType: "address", name: "_token", type: "address" }],
|
|
1803
|
+
name: "getCurrentPrice",
|
|
1804
|
+
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
|
1805
|
+
stateMutability: "view",
|
|
1806
|
+
type: "function"
|
|
1807
|
+
},
|
|
1808
|
+
{
|
|
1809
|
+
inputs: [{ internalType: "address", name: "_token", type: "address" }],
|
|
1810
|
+
name: "isListed",
|
|
1811
|
+
outputs: [{ internalType: "bool", name: "", type: "bool" }],
|
|
1812
|
+
stateMutability: "view",
|
|
1813
|
+
type: "function"
|
|
1814
|
+
},
|
|
1815
|
+
{
|
|
1816
|
+
inputs: [{ internalType: "address", name: "_token", type: "address" }],
|
|
1817
|
+
name: "getCurveProgress",
|
|
1818
|
+
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
|
|
1819
|
+
stateMutability: "view",
|
|
1820
|
+
type: "function"
|
|
1821
|
+
}
|
|
1822
|
+
];
|
|
1823
|
+
|
|
1824
|
+
// src/tools/pikeperps/openLong.ts
|
|
1825
|
+
async function pikeperpsOpenLong(agent, tokenAddress, margin, leverage = PIKE_PERPS_CONFIG.DEFAULT_LEVERAGE) {
|
|
1826
|
+
const perpetualTradingAddress = PERPETUAL_TRADING[agent.chain];
|
|
1827
|
+
if (perpetualTradingAddress === "0x0000000000000000000000000000000000000000") {
|
|
1828
|
+
throw new Error(
|
|
1829
|
+
`PikePerps not available on ${agent.chain}. Only available on testnet.`
|
|
1830
|
+
);
|
|
1831
|
+
}
|
|
1832
|
+
if (leverage < PIKE_PERPS_CONFIG.MIN_LEVERAGE || leverage > PIKE_PERPS_CONFIG.MAX_LEVERAGE) {
|
|
1833
|
+
throw new Error(
|
|
1834
|
+
`Leverage must be between ${PIKE_PERPS_CONFIG.MIN_LEVERAGE} and ${PIKE_PERPS_CONFIG.MAX_LEVERAGE}`
|
|
1835
|
+
);
|
|
1836
|
+
}
|
|
1837
|
+
if (agent.demo) {
|
|
1838
|
+
return {
|
|
1839
|
+
positionId: BigInt(Math.floor(Math.random() * 1e3)),
|
|
1840
|
+
txHash: "0xdemo_open_long_tx_hash"
|
|
1841
|
+
};
|
|
1842
|
+
}
|
|
1843
|
+
const marginBigInt = BigInt(margin);
|
|
1844
|
+
const data = encodeFunctionData({
|
|
1845
|
+
abi: PERPETUAL_TRADING_ABI,
|
|
1846
|
+
functionName: "openPosition",
|
|
1847
|
+
args: [tokenAddress, true, marginBigInt, BigInt(leverage)]
|
|
1848
|
+
});
|
|
1849
|
+
const txHash = await agent.client.sendTransaction({
|
|
1850
|
+
to: perpetualTradingAddress,
|
|
1851
|
+
data,
|
|
1852
|
+
value: marginBigInt
|
|
1853
|
+
});
|
|
1854
|
+
const receipt = await agent.client.waitForTransactionReceipt({ hash: txHash });
|
|
1855
|
+
let positionId = 0n;
|
|
1856
|
+
for (const log of receipt.logs) {
|
|
1857
|
+
try {
|
|
1858
|
+
if (log.topics[0] === "0x2e5b0e8c5f5d55d89e89f5b5d5e5f5d55d89e89f5b5d5e5f5d55d89e89f5b5d5") {
|
|
1859
|
+
positionId = BigInt(log.topics[1] || "0");
|
|
1860
|
+
break;
|
|
1861
|
+
}
|
|
1862
|
+
} catch {
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
if (positionId === 0n) {
|
|
1866
|
+
try {
|
|
1867
|
+
const nextId = await agent.client.readContract({
|
|
1868
|
+
address: perpetualTradingAddress,
|
|
1869
|
+
abi: PERPETUAL_TRADING_ABI,
|
|
1870
|
+
functionName: "nextPositionId"
|
|
1871
|
+
});
|
|
1872
|
+
positionId = nextId - 1n;
|
|
1873
|
+
} catch {
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
return {
|
|
1877
|
+
positionId,
|
|
1878
|
+
txHash
|
|
1879
|
+
};
|
|
1880
|
+
}
|
|
1881
|
+
async function pikeperpsOpenShort(agent, tokenAddress, margin, leverage = PIKE_PERPS_CONFIG.DEFAULT_LEVERAGE) {
|
|
1882
|
+
const perpetualTradingAddress = PERPETUAL_TRADING[agent.chain];
|
|
1883
|
+
if (perpetualTradingAddress === "0x0000000000000000000000000000000000000000") {
|
|
1884
|
+
throw new Error(
|
|
1885
|
+
`PikePerps not available on ${agent.chain}. Only available on testnet.`
|
|
1886
|
+
);
|
|
1887
|
+
}
|
|
1888
|
+
if (leverage < PIKE_PERPS_CONFIG.MIN_LEVERAGE || leverage > PIKE_PERPS_CONFIG.MAX_LEVERAGE) {
|
|
1889
|
+
throw new Error(
|
|
1890
|
+
`Leverage must be between ${PIKE_PERPS_CONFIG.MIN_LEVERAGE} and ${PIKE_PERPS_CONFIG.MAX_LEVERAGE}`
|
|
1891
|
+
);
|
|
1892
|
+
}
|
|
1893
|
+
if (agent.demo) {
|
|
1894
|
+
return {
|
|
1895
|
+
positionId: BigInt(Math.floor(Math.random() * 1e3)),
|
|
1896
|
+
txHash: "0xdemo_open_short_tx_hash"
|
|
1897
|
+
};
|
|
1898
|
+
}
|
|
1899
|
+
const marginBigInt = BigInt(margin);
|
|
1900
|
+
const data = encodeFunctionData({
|
|
1901
|
+
abi: PERPETUAL_TRADING_ABI,
|
|
1902
|
+
functionName: "openPosition",
|
|
1903
|
+
args: [tokenAddress, false, marginBigInt, BigInt(leverage)]
|
|
1904
|
+
});
|
|
1905
|
+
const txHash = await agent.client.sendTransaction({
|
|
1906
|
+
to: perpetualTradingAddress,
|
|
1907
|
+
data,
|
|
1908
|
+
value: marginBigInt
|
|
1909
|
+
});
|
|
1910
|
+
const receipt = await agent.client.waitForTransactionReceipt({ hash: txHash });
|
|
1911
|
+
let positionId = 0n;
|
|
1912
|
+
for (const log of receipt.logs) {
|
|
1913
|
+
try {
|
|
1914
|
+
if (log.topics[0] === "0x2e5b0e8c5f5d55d89e89f5b5d5e5f5d55d89e89f5b5d5e5f5d55d89e89f5b5d5") {
|
|
1915
|
+
positionId = BigInt(log.topics[1] || "0");
|
|
1916
|
+
break;
|
|
1917
|
+
}
|
|
1918
|
+
} catch {
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
if (positionId === 0n) {
|
|
1922
|
+
try {
|
|
1923
|
+
const nextId = await agent.client.readContract({
|
|
1924
|
+
address: perpetualTradingAddress,
|
|
1925
|
+
abi: PERPETUAL_TRADING_ABI,
|
|
1926
|
+
functionName: "nextPositionId"
|
|
1927
|
+
});
|
|
1928
|
+
positionId = nextId - 1n;
|
|
1929
|
+
} catch {
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
return {
|
|
1933
|
+
positionId,
|
|
1934
|
+
txHash
|
|
1935
|
+
};
|
|
1936
|
+
}
|
|
1937
|
+
async function pikeperpsClosePosition(agent, positionId) {
|
|
1938
|
+
const perpetualTradingAddress = PERPETUAL_TRADING[agent.chain];
|
|
1939
|
+
if (perpetualTradingAddress === "0x0000000000000000000000000000000000000000") {
|
|
1940
|
+
throw new Error(
|
|
1941
|
+
`PikePerps not available on ${agent.chain}. Only available on testnet.`
|
|
1942
|
+
);
|
|
1943
|
+
}
|
|
1944
|
+
if (agent.demo) {
|
|
1945
|
+
return "0xdemo_close_position_tx_hash";
|
|
1946
|
+
}
|
|
1947
|
+
const data = encodeFunctionData({
|
|
1948
|
+
abi: PERPETUAL_TRADING_ABI,
|
|
1949
|
+
functionName: "closePosition",
|
|
1950
|
+
args: [positionId]
|
|
1951
|
+
});
|
|
1952
|
+
const txHash = await agent.client.sendTransaction({
|
|
1953
|
+
to: perpetualTradingAddress,
|
|
1954
|
+
data
|
|
1955
|
+
});
|
|
1956
|
+
await agent.client.waitForTransactionReceipt({ hash: txHash });
|
|
1957
|
+
return txHash;
|
|
1958
|
+
}
|
|
1959
|
+
async function pikeperpsGetPositions(agent, userAddress) {
|
|
1960
|
+
const perpetualTradingAddress = PERPETUAL_TRADING[agent.chain];
|
|
1961
|
+
const address = userAddress || agent.account.address;
|
|
1962
|
+
if (perpetualTradingAddress === "0x0000000000000000000000000000000000000000") {
|
|
1963
|
+
throw new Error(
|
|
1964
|
+
`PikePerps not available on ${agent.chain}. Only available on testnet.`
|
|
1965
|
+
);
|
|
1966
|
+
}
|
|
1967
|
+
if (agent.demo) {
|
|
1968
|
+
return [
|
|
1969
|
+
{
|
|
1970
|
+
positionId: 1n,
|
|
1971
|
+
token: "0x0000000000000000000000000000000000000001",
|
|
1972
|
+
isLong: true,
|
|
1973
|
+
size: BigInt("1000000000000000000"),
|
|
1974
|
+
// 1 ETH equivalent
|
|
1975
|
+
margin: BigInt("100000000000000000"),
|
|
1976
|
+
// 0.1 ETH
|
|
1977
|
+
leverage: 10,
|
|
1978
|
+
entryPrice: BigInt("100000000"),
|
|
1979
|
+
// $1.00 scaled by 1e8
|
|
1980
|
+
entryTime: BigInt(Math.floor(Date.now() / 1e3) - 3600),
|
|
1981
|
+
currentPrice: BigInt("110000000"),
|
|
1982
|
+
// $1.10
|
|
1983
|
+
pnl: BigInt("10000000000000000"),
|
|
1984
|
+
// 0.01 ETH profit
|
|
1985
|
+
isProfit: true,
|
|
1986
|
+
liquidationPrice: BigInt("90000000"),
|
|
1987
|
+
// $0.90
|
|
1988
|
+
isOpen: true
|
|
1989
|
+
}
|
|
1990
|
+
];
|
|
1991
|
+
}
|
|
1992
|
+
const positionIds = await agent.client.readContract({
|
|
1993
|
+
address: perpetualTradingAddress,
|
|
1994
|
+
abi: PERPETUAL_TRADING_ABI,
|
|
1995
|
+
functionName: "getUserPositions",
|
|
1996
|
+
args: [address]
|
|
1997
|
+
});
|
|
1998
|
+
if (positionIds.length === 0) {
|
|
1999
|
+
return [];
|
|
2000
|
+
}
|
|
2001
|
+
const positions = [];
|
|
2002
|
+
for (const positionId of positionIds) {
|
|
2003
|
+
try {
|
|
2004
|
+
const rawPosition = await agent.client.readContract({
|
|
2005
|
+
address: perpetualTradingAddress,
|
|
2006
|
+
abi: PERPETUAL_TRADING_ABI,
|
|
2007
|
+
functionName: "getPosition",
|
|
2008
|
+
args: [positionId]
|
|
2009
|
+
});
|
|
2010
|
+
if (!rawPosition.isOpen) {
|
|
2011
|
+
continue;
|
|
2012
|
+
}
|
|
2013
|
+
const [pnl, isProfit] = await agent.client.readContract({
|
|
2014
|
+
address: perpetualTradingAddress,
|
|
2015
|
+
abi: PERPETUAL_TRADING_ABI,
|
|
2016
|
+
functionName: "getPositionPnL",
|
|
2017
|
+
args: [positionId]
|
|
2018
|
+
});
|
|
2019
|
+
const liquidationPrice = await agent.client.readContract({
|
|
2020
|
+
address: perpetualTradingAddress,
|
|
2021
|
+
abi: PERPETUAL_TRADING_ABI,
|
|
2022
|
+
functionName: "getLiquidationPrice",
|
|
2023
|
+
args: [positionId]
|
|
2024
|
+
});
|
|
2025
|
+
let currentPrice = 0n;
|
|
2026
|
+
try {
|
|
2027
|
+
const [price, hasPrice] = await agent.client.readContract({
|
|
2028
|
+
address: perpetualTradingAddress,
|
|
2029
|
+
abi: PERPETUAL_TRADING_ABI,
|
|
2030
|
+
functionName: "getCurrentPrice",
|
|
2031
|
+
args: [rawPosition.token]
|
|
2032
|
+
});
|
|
2033
|
+
if (hasPrice) {
|
|
2034
|
+
currentPrice = price;
|
|
2035
|
+
}
|
|
2036
|
+
} catch {
|
|
2037
|
+
currentPrice = rawPosition.entryPrice;
|
|
2038
|
+
}
|
|
2039
|
+
positions.push({
|
|
2040
|
+
positionId,
|
|
2041
|
+
token: rawPosition.token,
|
|
2042
|
+
isLong: rawPosition.isLong,
|
|
2043
|
+
size: rawPosition.size,
|
|
2044
|
+
margin: rawPosition.margin,
|
|
2045
|
+
leverage: Number(rawPosition.leverage),
|
|
2046
|
+
entryPrice: rawPosition.entryPrice,
|
|
2047
|
+
entryTime: rawPosition.entryTime,
|
|
2048
|
+
currentPrice,
|
|
2049
|
+
pnl,
|
|
2050
|
+
isProfit,
|
|
2051
|
+
liquidationPrice,
|
|
2052
|
+
isOpen: rawPosition.isOpen
|
|
2053
|
+
});
|
|
2054
|
+
} catch (error) {
|
|
2055
|
+
console.warn(`Failed to fetch position ${positionId}:`, error);
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
return positions;
|
|
2059
|
+
}
|
|
2060
|
+
async function pikeperpsGetMarketData(agent, tokenAddress, limit = 20) {
|
|
2061
|
+
const perpetualTradingAddress = PERPETUAL_TRADING[agent.chain];
|
|
2062
|
+
const bondingCurveAddress = BONDING_CURVE_MARKET[agent.chain];
|
|
2063
|
+
if (perpetualTradingAddress === "0x0000000000000000000000000000000000000000") {
|
|
2064
|
+
throw new Error(
|
|
2065
|
+
`PikePerps not available on ${agent.chain}. Only available on testnet.`
|
|
2066
|
+
);
|
|
2067
|
+
}
|
|
2068
|
+
if (agent.demo) {
|
|
2069
|
+
return {
|
|
2070
|
+
token: tokenAddress,
|
|
2071
|
+
currentPrice: BigInt("100000000"),
|
|
2072
|
+
// $1.00 scaled by 1e8
|
|
2073
|
+
hasPrice: true,
|
|
2074
|
+
isListed: true,
|
|
2075
|
+
curveProgress: BigInt("5000"),
|
|
2076
|
+
// 50%
|
|
2077
|
+
recentTrades: [
|
|
2078
|
+
{
|
|
2079
|
+
positionId: 1n,
|
|
2080
|
+
trader: "0x0000000000000000000000000000000000000001",
|
|
2081
|
+
token: tokenAddress,
|
|
2082
|
+
isLong: true,
|
|
2083
|
+
size: BigInt("1000000000000000000"),
|
|
2084
|
+
margin: BigInt("100000000000000000"),
|
|
2085
|
+
leverage: 10n,
|
|
2086
|
+
entryPrice: BigInt("100000000"),
|
|
2087
|
+
timestamp: Math.floor(Date.now() / 1e3) - 300,
|
|
2088
|
+
txHash: "0xdemo_trade_hash",
|
|
2089
|
+
blockNumber: 1000n
|
|
2090
|
+
}
|
|
2091
|
+
]
|
|
2092
|
+
};
|
|
2093
|
+
}
|
|
2094
|
+
let currentPrice = 0n;
|
|
2095
|
+
let hasPrice = false;
|
|
2096
|
+
try {
|
|
2097
|
+
const [price, hasPriceResult] = await agent.client.readContract({
|
|
2098
|
+
address: perpetualTradingAddress,
|
|
2099
|
+
abi: PERPETUAL_TRADING_ABI,
|
|
2100
|
+
functionName: "getCurrentPrice",
|
|
2101
|
+
args: [tokenAddress]
|
|
2102
|
+
});
|
|
2103
|
+
currentPrice = price;
|
|
2104
|
+
hasPrice = hasPriceResult;
|
|
2105
|
+
} catch {
|
|
2106
|
+
}
|
|
2107
|
+
let isListed = false;
|
|
2108
|
+
let curveProgress = 0n;
|
|
2109
|
+
if (bondingCurveAddress !== "0x0000000000000000000000000000000000000000") {
|
|
2110
|
+
try {
|
|
2111
|
+
isListed = await agent.client.readContract({
|
|
2112
|
+
address: bondingCurveAddress,
|
|
2113
|
+
abi: BONDING_CURVE_MARKET_ABI,
|
|
2114
|
+
functionName: "isListed",
|
|
2115
|
+
args: [tokenAddress]
|
|
2116
|
+
});
|
|
2117
|
+
if (isListed) {
|
|
2118
|
+
curveProgress = await agent.client.readContract({
|
|
2119
|
+
address: bondingCurveAddress,
|
|
2120
|
+
abi: BONDING_CURVE_MARKET_ABI,
|
|
2121
|
+
functionName: "getCurveProgress",
|
|
2122
|
+
args: [tokenAddress]
|
|
2123
|
+
});
|
|
2124
|
+
}
|
|
2125
|
+
} catch {
|
|
2126
|
+
}
|
|
2127
|
+
}
|
|
2128
|
+
const recentTrades = [];
|
|
2129
|
+
try {
|
|
2130
|
+
const currentBlock = await agent.client.getBlockNumber();
|
|
2131
|
+
const fromBlock = currentBlock > 1000n ? currentBlock - 1000n : 0n;
|
|
2132
|
+
const logs = await agent.client.getLogs({
|
|
2133
|
+
address: perpetualTradingAddress,
|
|
2134
|
+
event: parseAbiItem(
|
|
2135
|
+
"event PositionOpened(uint256 indexed positionId, address indexed user, address indexed token, bool isLong, uint256 size, uint256 margin, uint256 leverage, uint256 entryPrice)"
|
|
2136
|
+
),
|
|
2137
|
+
args: {
|
|
2138
|
+
token: tokenAddress
|
|
2139
|
+
},
|
|
2140
|
+
fromBlock,
|
|
2141
|
+
toBlock: currentBlock
|
|
2142
|
+
});
|
|
2143
|
+
const blockCache = /* @__PURE__ */ new Map();
|
|
2144
|
+
for (const log of logs.slice(-limit)) {
|
|
2145
|
+
let timestamp = 0;
|
|
2146
|
+
if (!blockCache.has(log.blockNumber)) {
|
|
2147
|
+
try {
|
|
2148
|
+
const block = await agent.client.getBlock({
|
|
2149
|
+
blockNumber: log.blockNumber
|
|
2150
|
+
});
|
|
2151
|
+
timestamp = Number(block.timestamp);
|
|
2152
|
+
blockCache.set(log.blockNumber, timestamp);
|
|
2153
|
+
} catch {
|
|
2154
|
+
timestamp = Math.floor(Date.now() / 1e3);
|
|
2155
|
+
}
|
|
2156
|
+
} else {
|
|
2157
|
+
timestamp = blockCache.get(log.blockNumber) || 0;
|
|
2158
|
+
}
|
|
2159
|
+
recentTrades.push({
|
|
2160
|
+
positionId: BigInt(log.topics[1] || "0"),
|
|
2161
|
+
trader: log.topics[2],
|
|
2162
|
+
token: tokenAddress,
|
|
2163
|
+
isLong: log.args.isLong || false,
|
|
2164
|
+
size: log.args.size || 0n,
|
|
2165
|
+
margin: log.args.margin || 0n,
|
|
2166
|
+
leverage: log.args.leverage || 0n,
|
|
2167
|
+
entryPrice: log.args.entryPrice || 0n,
|
|
2168
|
+
timestamp,
|
|
2169
|
+
txHash: log.transactionHash,
|
|
2170
|
+
blockNumber: log.blockNumber
|
|
2171
|
+
});
|
|
2172
|
+
}
|
|
2173
|
+
} catch (error) {
|
|
2174
|
+
console.warn("Failed to fetch recent trades:", error);
|
|
2175
|
+
}
|
|
2176
|
+
return {
|
|
2177
|
+
token: tokenAddress,
|
|
2178
|
+
currentPrice,
|
|
2179
|
+
hasPrice,
|
|
2180
|
+
isListed,
|
|
2181
|
+
curveProgress,
|
|
2182
|
+
recentTrades
|
|
2183
|
+
};
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
// src/constants/pyth/index.ts
|
|
2187
|
+
var pyth_exports = {};
|
|
2188
|
+
__export(pyth_exports, {
|
|
2189
|
+
HERMES_ENDPOINT: () => HERMES_ENDPOINT,
|
|
2190
|
+
PYTH_ABI: () => PYTH_ABI,
|
|
2191
|
+
PYTH_CONTRACT: () => PYTH_CONTRACT,
|
|
2192
|
+
PYTH_PRICE_FEED_IDS: () => PYTH_PRICE_FEED_IDS
|
|
2193
|
+
});
|
|
2194
|
+
var PYTH_CONTRACT = {
|
|
2195
|
+
mainnet: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729",
|
|
2196
|
+
testnet: "0x98046Bd286715D3B0BC227Dd7a956b83D8978603"
|
|
2197
|
+
};
|
|
2198
|
+
var HERMES_ENDPOINT = {
|
|
2199
|
+
mainnet: "https://hermes.pyth.network",
|
|
2200
|
+
testnet: "https://hermes.pyth.network"
|
|
2201
|
+
};
|
|
2202
|
+
var PYTH_PRICE_FEED_IDS = {
|
|
2203
|
+
// === Major Cryptocurrencies ===
|
|
2204
|
+
"BTC/USD": "e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43",
|
|
2205
|
+
"ETH/USD": "ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace",
|
|
2206
|
+
"SOL/USD": "ef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d",
|
|
2207
|
+
"BNB/USD": "2f95862b045670cd22bee3114c39763a4a08beeb663b145d283c31d7d1101c4f",
|
|
2208
|
+
"XRP/USD": "ec5d399846a9209f3fe5881d70aae9268c94339ff9817e8d18ff19fa05eea1c8",
|
|
2209
|
+
"ADA/USD": "2a01deaec9e51a579277b34b122399984d0bbf57e2458a7e42fecd2829867a0d",
|
|
2210
|
+
"DOGE/USD": "dcef50dd0a4cd2dcc17e45df1676dcb336a11a61c69df7a0299b0150c672d25c",
|
|
2211
|
+
"DOT/USD": "ca3eed9b267293f6595901c734c7525ce8ef49adafe8284571c8e17d6c926346",
|
|
2212
|
+
"AVAX/USD": "93da3352f9f1d105fdfe4971cfa80e9dd777bfc5d0f683ebb6e1294b92137bb7",
|
|
2213
|
+
"MATIC/USD": "5de33440f6b7d0d7d70f0a7b2a6c0e0b8e5d2f7c8a9b0c1d2e3f4a5b6c7d8e9f",
|
|
2214
|
+
"LINK/USD": "8ac0c70fff57e9aefdf5edf44b51d62c2d433653cbb2cf5cc06bb115af04d221",
|
|
2215
|
+
"ATOM/USD": "b00b60f88b03a6a625a8d1c048c3f66653edf217439cb6a1cbab0c1c5e8c52bd",
|
|
2216
|
+
"LTC/USD": "6e3f3fa8253588df9326580180233eb791e03b443a3ba7a1d892e73874e19a54",
|
|
2217
|
+
"UNI/USD": "78d185a741d07edb3412b09008b7c5cfb9bbbd7d568bf00ba737b456ba171501",
|
|
2218
|
+
"NEAR/USD": "c415de8d2eba7db216527dff4b60e8f3a5311c740dadb233e13e12547e226750",
|
|
2219
|
+
"TRX/USD": "67aed5a24fdad045475e7195c98a98aea119c763f272d4523f5bac93a4f33c2b",
|
|
2220
|
+
// === Layer 2 & Scaling ===
|
|
2221
|
+
"ARB/USD": "3fa4252848f9f0a1480be62745a4629d9eb1322aebab8a791e344b3b9c1adcf5",
|
|
2222
|
+
"OP/USD": "385f64d993f7b77d8182ed5003d97c60aa3361f3cecfe711544d2d59165e9bdf",
|
|
2223
|
+
"MNT/USD": "4e3037c822d852d79af3ac80e35eb420ee3b870dca49f9344a38ef4773fb0585",
|
|
2224
|
+
"IMX/USD": "941320a8989414a6d2c757c8c6c52b3e7e0b7e4e4c5bb8a3c8e7a0f3e0f0f0f0",
|
|
2225
|
+
"STRK/USD": "6a182399ff70ccf3e06024898942028204125a819e519a335ffa4579e66cd870",
|
|
2226
|
+
// === DeFi Tokens ===
|
|
2227
|
+
"AAVE/USD": "2b9ab1e972a281585084148ba1389800799bd4be63b957507db1349314e47445",
|
|
2228
|
+
"CRV/USD": "a19d04ac696c7a6616d291c7e5d1377cc8be437c327b75adb5dc1bad745fcae8",
|
|
2229
|
+
"MKR/USD": "9375299e31c0deb9c6bc378e6329aab44cb48ec655552a70d4b9050346a30378",
|
|
2230
|
+
"SNX/USD": "39d020f60982ed892abbcd4a06a276a9f9b7bfbce003204c110b6e488f502da3",
|
|
2231
|
+
"COMP/USD": "4a8e42861cabc5ecb50996f92e7cfa2bce3fd0a2423b0c44c9b423fb2bd25478",
|
|
2232
|
+
"LDO/USD": "c63e2a7f37a04e5e614c07238bedb25dcc38927e77a90a4b21a7a2e1d7f0d2e3",
|
|
2233
|
+
"1INCH/USD": "63f341689d98a12ef60a5cff1d7f85c70a9e17bf1575f0e7c0b2512d48b1c8b3",
|
|
2234
|
+
"SUSHI/USD": "26e4f737fde0263a9eea10ae63ac36dcedab2aaf629f1e31a28a28dd0e0d2b0c",
|
|
2235
|
+
"YFI/USD": "425f4b198ab2504936886c1e93511bb6720fbcf2045a4f3c0723bb213846022f",
|
|
2236
|
+
"BAL/USD": "07ad7b4a7662d19a6bc675f6b467172d2f3947fa653ca97555a9b20236406628",
|
|
2237
|
+
"CAKE/USD": "2356af9529a1064d1d2a2e3e4ab6d6e6f6e6f6e6f6e6f6e6f6e6f6e6f6e6f6e6",
|
|
2238
|
+
"GMX/USD": "b962539d0fcb272a494d65ea56f94851c2bcf8823935da05bd628916e2e9edbf",
|
|
2239
|
+
"PENDLE/USD": "9a4df90b25497f66b1afb012467e316e801ca3d839456db028892fe8c70c8016",
|
|
2240
|
+
"JOE/USD": "1e8a156c8a23c1e56f2d9d7f0e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e",
|
|
2241
|
+
// === Stablecoins ===
|
|
2242
|
+
"USDC/USD": "eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a",
|
|
2243
|
+
"USDT/USD": "2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b",
|
|
2244
|
+
"DAI/USD": "b0948a5e5313200c632b51bb5ca32f6de0d36e9950a942d19751e833f70dabfd",
|
|
2245
|
+
"FRAX/USD": "c3d5d8d6d0c0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0",
|
|
2246
|
+
"BUSD/USD": "5bc91f13e412c07599167bae86f07543f076a638962b8d6017ec19dab4a82814",
|
|
2247
|
+
"TUSD/USD": "433faaa801ecda2c0bbfa8f4e2d85fd4c310e2c1e5f8f8e6e5f5f5f5f5f5f5f5",
|
|
2248
|
+
"LUSD/USD": "d892ae586f4e0fbeee4d64f29ed6e89b1b3e2e2e2e2e2e2e2e2e2e2e2e2e2e2e",
|
|
2249
|
+
// === Wrapped & LST Tokens ===
|
|
2250
|
+
"WETH/USD": "ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace",
|
|
2251
|
+
"WBTC/USD": "c9d8b075a5c69303365ae23633d4e085199bf5c520a3b90fed1322a0342ffc33",
|
|
2252
|
+
"stETH/USD": "846ae1bdb6300b817cee5fdee2a6da192775030db5615b94a465f53bd40850b5",
|
|
2253
|
+
"cbETH/USD": "15ecddd26d49e1a8f1de9376ebebc03916ede873447c1255d2d5891b92ce5717",
|
|
2254
|
+
"rETH/USD": "a0255134973f4fdf2f8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
|
|
2255
|
+
"mETH/USD": "4c9c6f9f0cde13fced52dc1927c8c06a91b1a65ab77b9e1ec1c614963ce90dd4",
|
|
2256
|
+
"wstETH/USD": "6df640f3b8963d8f8358f791f352b8364513f6ab1cca5ed3f1f7b5448980e784",
|
|
2257
|
+
// === Meme Coins ===
|
|
2258
|
+
"SHIB/USD": "f0d57deca57b3da2fe63a493f4c25925fdfd8edf834b20f93e1f84dbd1504d4a",
|
|
2259
|
+
"PEPE/USD": "d69731a2e74ac1ce884fc3890f7ee324b6deb66147055249568869ed700882e4",
|
|
2260
|
+
"FLOKI/USD": "6b1381ce7e874dc5410b197ac8348162c0dd6c0d4c9cd6322c28a6f7f4d1a2d2",
|
|
2261
|
+
"BONK/USD": "72b021217ca3fe68922a19aaf990109cb9d84e9ad004b4d2025ad6f529314419",
|
|
2262
|
+
"WIF/USD": "4ca4beeca86f0d164160323817a4e42b10010a724c2217c6ee41b54cd4cc61fc",
|
|
2263
|
+
// === Gaming & Metaverse ===
|
|
2264
|
+
"AXS/USD": "b0d8f5e3f3a7c0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0",
|
|
2265
|
+
"SAND/USD": "f4040ec3e5b71c241a7e1a9a1e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e",
|
|
2266
|
+
"MANA/USD": "2b15e4bded7f5e5d5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
|
|
2267
|
+
"GALA/USD": "e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3e3",
|
|
2268
|
+
"APE/USD": "15add95022ae13563a11992e727c91bdb6b55bc183d9d747436c80a483d8c864",
|
|
2269
|
+
"ENJ/USD": "5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a",
|
|
2270
|
+
// === Infrastructure & Oracles ===
|
|
2271
|
+
"FIL/USD": "150ac9b959aee0051e4091f0ef5216d941f590e1c5e7f91cf7635b5c11628c0e",
|
|
2272
|
+
"GRT/USD": "4d1f8dae0d96236fb98e8f47571a70f41c8b8f2f6d6c0e0e0e0e0e0e0e0e0e0e",
|
|
2273
|
+
"RNDR/USD": "ab7347771135fc733f8f38db462ba085ed3309955f42554a14fa13e855ac0e2f",
|
|
2274
|
+
"INJ/USD": "7a5bc1d2b56ad029048cd63964b3ad2776eadf812edc1a43a31406cb54bff592",
|
|
2275
|
+
"AR/USD": "8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c",
|
|
2276
|
+
"THETA/USD": "4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a",
|
|
2277
|
+
"PYTH/USD": "0bbf28e9a841a1cc788f6a361b17ca072d0ea3098a1e5df1c3922d06719579ff",
|
|
2278
|
+
// === AI & Data ===
|
|
2279
|
+
"FET/USD": "b49ee9d8ccf9b6e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0",
|
|
2280
|
+
"OCEAN/USD": "2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d",
|
|
2281
|
+
"TAO/USD": "410f41de235f2dbdf41f1a808c1e15f6a9e7d6a7b8c9d0e1f2a3b4c5d6e7f8a9",
|
|
2282
|
+
// === Exchange Tokens ===
|
|
2283
|
+
"FTT/USD": "6c75e52531ec5fd3ef253f6062956a8508a2f03fa0a209fb7dbc0d0f3d6f6f6f",
|
|
2284
|
+
"CRO/USD": "b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7b7",
|
|
2285
|
+
"OKB/USD": "23d7315113f5b1d3ba7a83604c44b94d79f4fd69af77f804fc7f920a6dc65744",
|
|
2286
|
+
// === Forex Pairs ===
|
|
2287
|
+
"EUR/USD": "a995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b",
|
|
2288
|
+
"GBP/USD": "84c2dde9633d93d1bcad84e7dc41c9d56578b7ec52fabedc1f335d673df0a7c1",
|
|
2289
|
+
"JPY/USD": "ef2c98c804ba503c6a707e38be4dfbb16683775f195b091252bf24693042fd52",
|
|
2290
|
+
"AUD/USD": "67a6f93030f4217f2e8f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f",
|
|
2291
|
+
"CAD/USD": "9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a9a",
|
|
2292
|
+
// === Commodities ===
|
|
2293
|
+
"XAU/USD": "765d2ba906dbc32ca17cc11f5310a89e9ee1f6420508c63861f2f8ba4ee34bb2",
|
|
2294
|
+
"XAG/USD": "f2fb02c32b055c805e7238d628e5e9dadef274376114eb1f012337cabe93871e",
|
|
2295
|
+
"WTI/USD": "c9c8e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9e9",
|
|
2296
|
+
"BRENT/USD": "d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8d8",
|
|
2297
|
+
// === US Equities ===
|
|
2298
|
+
"AAPL/USD": "49f6b65cb1de6b10eaf75e7c03ca029c306d0357e91b5311b175084a5ad55688",
|
|
2299
|
+
"NVDA/USD": "b1073854ed24cbc755dc527418f52b7d271f6cc967bbf8d8129112b18860a593",
|
|
2300
|
+
"TSLA/USD": "16dad506d7db8da01c87581c87ca897a012a153557d4d578c3b9c9e1bc0632f1",
|
|
2301
|
+
"GOOGL/USD": "b7e3904c08ddd9c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0",
|
|
2302
|
+
"AMZN/USD": "c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6c6",
|
|
2303
|
+
"MSFT/USD": "d0ca23c1cc005e004ccf1db5bf76aeb6a49218f43dac3d4b275e92de12ea4b77",
|
|
2304
|
+
"META/USD": "a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4a4",
|
|
2305
|
+
"COIN/USD": "9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b9b",
|
|
2306
|
+
"SPY/USD": "19e09bb805456ada3979a7d1cbb4b6d63babc3a0f8e8a9b3c4d5e6f7a8b9c0d1",
|
|
2307
|
+
"QQQ/USD": "2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e"
|
|
2308
|
+
};
|
|
2309
|
+
var PYTH_ABI = [
|
|
2310
|
+
{
|
|
2311
|
+
inputs: [{ name: "id", type: "bytes32" }],
|
|
2312
|
+
name: "getPrice",
|
|
2313
|
+
outputs: [
|
|
2314
|
+
{
|
|
2315
|
+
components: [
|
|
2316
|
+
{ name: "price", type: "int64" },
|
|
2317
|
+
{ name: "conf", type: "uint64" },
|
|
2318
|
+
{ name: "expo", type: "int32" },
|
|
2319
|
+
{ name: "publishTime", type: "uint256" }
|
|
2320
|
+
],
|
|
2321
|
+
name: "",
|
|
2322
|
+
type: "tuple"
|
|
2323
|
+
}
|
|
2324
|
+
],
|
|
2325
|
+
stateMutability: "view",
|
|
2326
|
+
type: "function"
|
|
2327
|
+
},
|
|
2328
|
+
{
|
|
2329
|
+
inputs: [{ name: "id", type: "bytes32" }],
|
|
2330
|
+
name: "getPriceNoOlderThan",
|
|
2331
|
+
outputs: [
|
|
2332
|
+
{
|
|
2333
|
+
components: [
|
|
2334
|
+
{ name: "price", type: "int64" },
|
|
2335
|
+
{ name: "conf", type: "uint64" },
|
|
2336
|
+
{ name: "expo", type: "int32" },
|
|
2337
|
+
{ name: "publishTime", type: "uint256" }
|
|
2338
|
+
],
|
|
2339
|
+
name: "",
|
|
2340
|
+
type: "tuple"
|
|
2341
|
+
}
|
|
2342
|
+
],
|
|
2343
|
+
stateMutability: "view",
|
|
2344
|
+
type: "function"
|
|
2345
|
+
},
|
|
2346
|
+
{
|
|
2347
|
+
inputs: [
|
|
2348
|
+
{ name: "id", type: "bytes32" },
|
|
2349
|
+
{ name: "age", type: "uint256" }
|
|
2350
|
+
],
|
|
2351
|
+
name: "getPriceNoOlderThan",
|
|
2352
|
+
outputs: [
|
|
2353
|
+
{
|
|
2354
|
+
components: [
|
|
2355
|
+
{ name: "price", type: "int64" },
|
|
2356
|
+
{ name: "conf", type: "uint64" },
|
|
2357
|
+
{ name: "expo", type: "int32" },
|
|
2358
|
+
{ name: "publishTime", type: "uint256" }
|
|
2359
|
+
],
|
|
2360
|
+
name: "",
|
|
2361
|
+
type: "tuple"
|
|
2362
|
+
}
|
|
2363
|
+
],
|
|
2364
|
+
stateMutability: "view",
|
|
2365
|
+
type: "function"
|
|
2366
|
+
},
|
|
2367
|
+
{
|
|
2368
|
+
inputs: [{ name: "id", type: "bytes32" }],
|
|
2369
|
+
name: "getPriceUnsafe",
|
|
2370
|
+
outputs: [
|
|
2371
|
+
{
|
|
2372
|
+
components: [
|
|
2373
|
+
{ name: "price", type: "int64" },
|
|
2374
|
+
{ name: "conf", type: "uint64" },
|
|
2375
|
+
{ name: "expo", type: "int32" },
|
|
2376
|
+
{ name: "publishTime", type: "uint256" }
|
|
2377
|
+
],
|
|
2378
|
+
name: "",
|
|
2379
|
+
type: "tuple"
|
|
2380
|
+
}
|
|
2381
|
+
],
|
|
2382
|
+
stateMutability: "view",
|
|
2383
|
+
type: "function"
|
|
2384
|
+
},
|
|
2385
|
+
{
|
|
2386
|
+
inputs: [{ name: "id", type: "bytes32" }],
|
|
2387
|
+
name: "getEmaPrice",
|
|
2388
|
+
outputs: [
|
|
2389
|
+
{
|
|
2390
|
+
components: [
|
|
2391
|
+
{ name: "price", type: "int64" },
|
|
2392
|
+
{ name: "conf", type: "uint64" },
|
|
2393
|
+
{ name: "expo", type: "int32" },
|
|
2394
|
+
{ name: "publishTime", type: "uint256" }
|
|
2395
|
+
],
|
|
2396
|
+
name: "",
|
|
2397
|
+
type: "tuple"
|
|
2398
|
+
}
|
|
2399
|
+
],
|
|
2400
|
+
stateMutability: "view",
|
|
2401
|
+
type: "function"
|
|
2402
|
+
},
|
|
2403
|
+
{
|
|
2404
|
+
inputs: [{ name: "updateData", type: "bytes[]" }],
|
|
2405
|
+
name: "updatePriceFeeds",
|
|
2406
|
+
outputs: [],
|
|
2407
|
+
stateMutability: "payable",
|
|
2408
|
+
type: "function"
|
|
2409
|
+
},
|
|
2410
|
+
{
|
|
2411
|
+
inputs: [{ name: "updateData", type: "bytes[]" }],
|
|
2412
|
+
name: "getUpdateFee",
|
|
2413
|
+
outputs: [{ name: "feeAmount", type: "uint256" }],
|
|
2414
|
+
stateMutability: "view",
|
|
2415
|
+
type: "function"
|
|
2416
|
+
},
|
|
2417
|
+
{
|
|
2418
|
+
inputs: [{ name: "id", type: "bytes32" }],
|
|
2419
|
+
name: "priceFeedExists",
|
|
2420
|
+
outputs: [{ name: "", type: "bool" }],
|
|
2421
|
+
stateMutability: "view",
|
|
2422
|
+
type: "function"
|
|
2423
|
+
},
|
|
2424
|
+
{
|
|
2425
|
+
inputs: [
|
|
2426
|
+
{ name: "updateData", type: "bytes[]" },
|
|
2427
|
+
{ name: "priceIds", type: "bytes32[]" },
|
|
2428
|
+
{ name: "minPublishTime", type: "uint64" },
|
|
2429
|
+
{ name: "maxPublishTime", type: "uint64" }
|
|
2430
|
+
],
|
|
2431
|
+
name: "parsePriceFeedUpdates",
|
|
2432
|
+
outputs: [
|
|
2433
|
+
{
|
|
2434
|
+
components: [
|
|
2435
|
+
{ name: "id", type: "bytes32" },
|
|
2436
|
+
{
|
|
2437
|
+
components: [
|
|
2438
|
+
{ name: "price", type: "int64" },
|
|
2439
|
+
{ name: "conf", type: "uint64" },
|
|
2440
|
+
{ name: "expo", type: "int32" },
|
|
2441
|
+
{ name: "publishTime", type: "uint256" }
|
|
2442
|
+
],
|
|
2443
|
+
name: "price",
|
|
2444
|
+
type: "tuple"
|
|
2445
|
+
},
|
|
2446
|
+
{
|
|
2447
|
+
components: [
|
|
2448
|
+
{ name: "price", type: "int64" },
|
|
2449
|
+
{ name: "conf", type: "uint64" },
|
|
2450
|
+
{ name: "expo", type: "int32" },
|
|
2451
|
+
{ name: "publishTime", type: "uint256" }
|
|
2452
|
+
],
|
|
2453
|
+
name: "emaPrice",
|
|
2454
|
+
type: "tuple"
|
|
2455
|
+
}
|
|
2456
|
+
],
|
|
2457
|
+
name: "",
|
|
2458
|
+
type: "tuple[]"
|
|
2459
|
+
}
|
|
2460
|
+
],
|
|
2461
|
+
stateMutability: "payable",
|
|
2462
|
+
type: "function"
|
|
2463
|
+
}
|
|
2464
|
+
];
|
|
2465
|
+
|
|
2466
|
+
// src/tools/pyth/getPrice.ts
|
|
2467
|
+
async function pythGetPrice(agent, priceFeedIdOrPair) {
|
|
2468
|
+
const pythAddress = PYTH_CONTRACT[agent.chain];
|
|
2469
|
+
let priceFeedId = priceFeedIdOrPair;
|
|
2470
|
+
let pair = priceFeedIdOrPair;
|
|
2471
|
+
if (priceFeedIdOrPair in PYTH_PRICE_FEED_IDS) {
|
|
2472
|
+
priceFeedId = PYTH_PRICE_FEED_IDS[priceFeedIdOrPair];
|
|
2473
|
+
pair = priceFeedIdOrPair;
|
|
2474
|
+
} else {
|
|
2475
|
+
const foundPair = Object.entries(PYTH_PRICE_FEED_IDS).find(
|
|
2476
|
+
([, id]) => id === priceFeedIdOrPair.replace("0x", "")
|
|
2477
|
+
);
|
|
2478
|
+
if (foundPair) {
|
|
2479
|
+
pair = foundPair[0];
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
const feedId = priceFeedId.startsWith("0x") ? priceFeedId : `0x${priceFeedId}`;
|
|
2483
|
+
if (agent.demo) {
|
|
2484
|
+
return createMockPythResponse(pair, feedId);
|
|
2485
|
+
}
|
|
2486
|
+
try {
|
|
2487
|
+
const priceData = await agent.client.readContract({
|
|
2488
|
+
address: pythAddress,
|
|
2489
|
+
abi: PYTH_ABI,
|
|
2490
|
+
functionName: "getPriceUnsafe",
|
|
2491
|
+
args: [feedId]
|
|
2492
|
+
});
|
|
2493
|
+
const price = Number(priceData.price);
|
|
2494
|
+
const confidence = Number(priceData.conf);
|
|
2495
|
+
const exponent = priceData.expo;
|
|
2496
|
+
const publishTime = Number(priceData.publishTime);
|
|
2497
|
+
const formattedPrice = formatPythPrice(price, exponent);
|
|
2498
|
+
return {
|
|
2499
|
+
priceFeedId: feedId,
|
|
2500
|
+
pair,
|
|
2501
|
+
price: priceData.price.toString(),
|
|
2502
|
+
confidence: priceData.conf.toString(),
|
|
2503
|
+
exponent,
|
|
2504
|
+
publishTime,
|
|
2505
|
+
formattedPrice
|
|
2506
|
+
};
|
|
2507
|
+
} catch (error) {
|
|
2508
|
+
throw new Error(
|
|
2509
|
+
`Failed to fetch price from Pyth: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
2510
|
+
);
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
async function pythGetEmaPrice(agent, priceFeedIdOrPair) {
|
|
2514
|
+
const pythAddress = PYTH_CONTRACT[agent.chain];
|
|
2515
|
+
let priceFeedId = priceFeedIdOrPair;
|
|
2516
|
+
let pair = priceFeedIdOrPair;
|
|
2517
|
+
if (priceFeedIdOrPair in PYTH_PRICE_FEED_IDS) {
|
|
2518
|
+
priceFeedId = PYTH_PRICE_FEED_IDS[priceFeedIdOrPair];
|
|
2519
|
+
pair = priceFeedIdOrPair;
|
|
2520
|
+
}
|
|
2521
|
+
const feedId = priceFeedId.startsWith("0x") ? priceFeedId : `0x${priceFeedId}`;
|
|
2522
|
+
if (agent.demo) {
|
|
2523
|
+
return createMockPythResponse(pair, feedId);
|
|
2524
|
+
}
|
|
2525
|
+
try {
|
|
2526
|
+
const priceData = await agent.client.readContract({
|
|
2527
|
+
address: pythAddress,
|
|
2528
|
+
abi: PYTH_ABI,
|
|
2529
|
+
functionName: "getEmaPrice",
|
|
2530
|
+
args: [feedId]
|
|
2531
|
+
});
|
|
2532
|
+
const formattedPrice = formatPythPrice(
|
|
2533
|
+
Number(priceData.price),
|
|
2534
|
+
priceData.expo
|
|
2535
|
+
);
|
|
2536
|
+
return {
|
|
2537
|
+
priceFeedId: feedId,
|
|
2538
|
+
pair,
|
|
2539
|
+
price: priceData.price.toString(),
|
|
2540
|
+
confidence: priceData.conf.toString(),
|
|
2541
|
+
exponent: priceData.expo,
|
|
2542
|
+
publishTime: Number(priceData.publishTime),
|
|
2543
|
+
formattedPrice
|
|
2544
|
+
};
|
|
2545
|
+
} catch (error) {
|
|
2546
|
+
throw new Error(
|
|
2547
|
+
`Failed to fetch EMA price from Pyth: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
2548
|
+
);
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
function formatPythPrice(price, exponent) {
|
|
2552
|
+
const adjustedPrice = price * Math.pow(10, exponent);
|
|
2553
|
+
if (adjustedPrice >= 1) {
|
|
2554
|
+
return adjustedPrice.toFixed(2);
|
|
2555
|
+
} else {
|
|
2556
|
+
return adjustedPrice.toFixed(8);
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
function createMockPythResponse(pair, feedId) {
|
|
2560
|
+
const mockPrices = {
|
|
2561
|
+
// Major Crypto
|
|
2562
|
+
"BTC/USD": 97500,
|
|
2563
|
+
"ETH/USD": 3450,
|
|
2564
|
+
"SOL/USD": 185,
|
|
2565
|
+
"BNB/USD": 680,
|
|
2566
|
+
"XRP/USD": 2.35,
|
|
2567
|
+
"ADA/USD": 0.95,
|
|
2568
|
+
"DOGE/USD": 0.32,
|
|
2569
|
+
"DOT/USD": 7.2,
|
|
2570
|
+
"AVAX/USD": 38,
|
|
2571
|
+
"MATIC/USD": 0.48,
|
|
2572
|
+
"LINK/USD": 22,
|
|
2573
|
+
"ATOM/USD": 9.5,
|
|
2574
|
+
"LTC/USD": 105,
|
|
2575
|
+
"UNI/USD": 13.5,
|
|
2576
|
+
"NEAR/USD": 5.2,
|
|
2577
|
+
"TRX/USD": 0.25,
|
|
2578
|
+
// L2
|
|
2579
|
+
"ARB/USD": 0.85,
|
|
2580
|
+
"OP/USD": 1.95,
|
|
2581
|
+
"MNT/USD": 0.85,
|
|
2582
|
+
"STRK/USD": 0.45,
|
|
2583
|
+
// DeFi
|
|
2584
|
+
"AAVE/USD": 285,
|
|
2585
|
+
"CRV/USD": 0.52,
|
|
2586
|
+
"MKR/USD": 1850,
|
|
2587
|
+
"SNX/USD": 2.8,
|
|
2588
|
+
"LDO/USD": 1.85,
|
|
2589
|
+
"GMX/USD": 28,
|
|
2590
|
+
"PENDLE/USD": 4.2,
|
|
2591
|
+
// Stablecoins
|
|
2592
|
+
"USDC/USD": 1,
|
|
2593
|
+
"USDT/USD": 1,
|
|
2594
|
+
"DAI/USD": 1,
|
|
2595
|
+
// LST
|
|
2596
|
+
"mETH/USD": 3500,
|
|
2597
|
+
"stETH/USD": 3450,
|
|
2598
|
+
"wstETH/USD": 4100,
|
|
2599
|
+
// Meme
|
|
2600
|
+
"SHIB/USD": 22e-6,
|
|
2601
|
+
"PEPE/USD": 18e-6,
|
|
2602
|
+
"BONK/USD": 28e-6,
|
|
2603
|
+
"WIF/USD": 1.85,
|
|
2604
|
+
// Commodities
|
|
2605
|
+
"XAU/USD": 2650,
|
|
2606
|
+
"XAG/USD": 31,
|
|
2607
|
+
// Forex
|
|
2608
|
+
"EUR/USD": 1.08,
|
|
2609
|
+
"GBP/USD": 1.27,
|
|
2610
|
+
"JPY/USD": 67e-4,
|
|
2611
|
+
// Equities
|
|
2612
|
+
"AAPL/USD": 248,
|
|
2613
|
+
"NVDA/USD": 138,
|
|
2614
|
+
"TSLA/USD": 385,
|
|
2615
|
+
"MSFT/USD": 425
|
|
2616
|
+
};
|
|
2617
|
+
const price = mockPrices[pair] || 100;
|
|
2618
|
+
const decimals = price < 0.01 ? 8 : price < 1 ? 4 : 2;
|
|
2619
|
+
return {
|
|
2620
|
+
priceFeedId: feedId,
|
|
2621
|
+
pair,
|
|
2622
|
+
price: Math.floor(price * 1e8).toString(),
|
|
2623
|
+
confidence: "50000",
|
|
2624
|
+
exponent: -8,
|
|
2625
|
+
publishTime: Math.floor(Date.now() / 1e3),
|
|
2626
|
+
formattedPrice: price.toFixed(decimals)
|
|
2627
|
+
};
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2630
|
+
// src/tools/pyth/getMultiplePrices.ts
|
|
2631
|
+
async function pythGetMultiplePrices(agent, pairs) {
|
|
2632
|
+
const pythAddress = PYTH_CONTRACT[agent.chain];
|
|
2633
|
+
const results = [];
|
|
2634
|
+
for (const pairOrId of pairs) {
|
|
2635
|
+
let priceFeedId = pairOrId;
|
|
2636
|
+
let pair = pairOrId;
|
|
2637
|
+
if (pairOrId in PYTH_PRICE_FEED_IDS) {
|
|
2638
|
+
priceFeedId = PYTH_PRICE_FEED_IDS[pairOrId];
|
|
2639
|
+
pair = pairOrId;
|
|
2640
|
+
} else {
|
|
2641
|
+
const foundPair = Object.entries(PYTH_PRICE_FEED_IDS).find(
|
|
2642
|
+
([, id]) => id === pairOrId.replace("0x", "")
|
|
2643
|
+
);
|
|
2644
|
+
if (foundPair) {
|
|
2645
|
+
pair = foundPair[0];
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
const feedId = priceFeedId.startsWith("0x") ? priceFeedId : `0x${priceFeedId}`;
|
|
2649
|
+
if (agent.demo) {
|
|
2650
|
+
results.push(createMockPythResponse2(pair, feedId));
|
|
2651
|
+
continue;
|
|
2652
|
+
}
|
|
2653
|
+
try {
|
|
2654
|
+
const priceData = await agent.client.readContract({
|
|
2655
|
+
address: pythAddress,
|
|
2656
|
+
abi: PYTH_ABI,
|
|
2657
|
+
functionName: "getPriceUnsafe",
|
|
2658
|
+
args: [feedId]
|
|
2659
|
+
});
|
|
2660
|
+
const formattedPrice = formatPythPrice2(
|
|
2661
|
+
Number(priceData.price),
|
|
2662
|
+
priceData.expo
|
|
2663
|
+
);
|
|
2664
|
+
results.push({
|
|
2665
|
+
priceFeedId: feedId,
|
|
2666
|
+
pair,
|
|
2667
|
+
price: priceData.price.toString(),
|
|
2668
|
+
confidence: priceData.conf.toString(),
|
|
2669
|
+
exponent: priceData.expo,
|
|
2670
|
+
publishTime: Number(priceData.publishTime),
|
|
2671
|
+
formattedPrice
|
|
2672
|
+
});
|
|
2673
|
+
} catch (error) {
|
|
2674
|
+
results.push({
|
|
2675
|
+
priceFeedId: feedId,
|
|
2676
|
+
pair,
|
|
2677
|
+
price: "0",
|
|
2678
|
+
confidence: "0",
|
|
2679
|
+
exponent: 0,
|
|
2680
|
+
publishTime: 0,
|
|
2681
|
+
formattedPrice: "Error fetching price"
|
|
2682
|
+
});
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
return results;
|
|
2686
|
+
}
|
|
2687
|
+
function pythGetSupportedPriceFeeds() {
|
|
2688
|
+
return { ...PYTH_PRICE_FEED_IDS };
|
|
2689
|
+
}
|
|
2690
|
+
async function pythPriceFeedExists(agent, priceFeedIdOrPair) {
|
|
2691
|
+
const pythAddress = PYTH_CONTRACT[agent.chain];
|
|
2692
|
+
let priceFeedId = priceFeedIdOrPair;
|
|
2693
|
+
if (priceFeedIdOrPair in PYTH_PRICE_FEED_IDS) {
|
|
2694
|
+
priceFeedId = PYTH_PRICE_FEED_IDS[priceFeedIdOrPair];
|
|
2695
|
+
}
|
|
2696
|
+
const feedId = priceFeedId.startsWith("0x") ? priceFeedId : `0x${priceFeedId}`;
|
|
2697
|
+
if (agent.demo) {
|
|
2698
|
+
return priceFeedIdOrPair in PYTH_PRICE_FEED_IDS;
|
|
2699
|
+
}
|
|
2700
|
+
try {
|
|
2701
|
+
const exists = await agent.client.readContract({
|
|
2702
|
+
address: pythAddress,
|
|
2703
|
+
abi: PYTH_ABI,
|
|
2704
|
+
functionName: "priceFeedExists",
|
|
2705
|
+
args: [feedId]
|
|
2706
|
+
});
|
|
2707
|
+
return exists;
|
|
2708
|
+
} catch {
|
|
2709
|
+
return false;
|
|
2710
|
+
}
|
|
2711
|
+
}
|
|
2712
|
+
function formatPythPrice2(price, exponent) {
|
|
2713
|
+
const adjustedPrice = price * Math.pow(10, exponent);
|
|
2714
|
+
if (adjustedPrice >= 1) {
|
|
2715
|
+
return adjustedPrice.toFixed(2);
|
|
2716
|
+
}
|
|
2717
|
+
return adjustedPrice.toFixed(8);
|
|
2718
|
+
}
|
|
2719
|
+
function createMockPythResponse2(pair, feedId) {
|
|
2720
|
+
const mockPrices = {
|
|
2721
|
+
// Major Crypto
|
|
2722
|
+
"BTC/USD": 97500,
|
|
2723
|
+
"ETH/USD": 3450,
|
|
2724
|
+
"SOL/USD": 185,
|
|
2725
|
+
"BNB/USD": 680,
|
|
2726
|
+
"XRP/USD": 2.35,
|
|
2727
|
+
"ADA/USD": 0.95,
|
|
2728
|
+
"DOGE/USD": 0.32,
|
|
2729
|
+
"DOT/USD": 7.2,
|
|
2730
|
+
"AVAX/USD": 38,
|
|
2731
|
+
"MATIC/USD": 0.48,
|
|
2732
|
+
"LINK/USD": 22,
|
|
2733
|
+
"ATOM/USD": 9.5,
|
|
2734
|
+
"LTC/USD": 105,
|
|
2735
|
+
"UNI/USD": 13.5,
|
|
2736
|
+
"NEAR/USD": 5.2,
|
|
2737
|
+
"TRX/USD": 0.25,
|
|
2738
|
+
// L2
|
|
2739
|
+
"ARB/USD": 0.85,
|
|
2740
|
+
"OP/USD": 1.95,
|
|
2741
|
+
"MNT/USD": 0.85,
|
|
2742
|
+
"STRK/USD": 0.45,
|
|
2743
|
+
// DeFi
|
|
2744
|
+
"AAVE/USD": 285,
|
|
2745
|
+
"CRV/USD": 0.52,
|
|
2746
|
+
"MKR/USD": 1850,
|
|
2747
|
+
"SNX/USD": 2.8,
|
|
2748
|
+
"LDO/USD": 1.85,
|
|
2749
|
+
"GMX/USD": 28,
|
|
2750
|
+
"PENDLE/USD": 4.2,
|
|
2751
|
+
// Stablecoins
|
|
2752
|
+
"USDC/USD": 1,
|
|
2753
|
+
"USDT/USD": 1,
|
|
2754
|
+
"DAI/USD": 1,
|
|
2755
|
+
// LST
|
|
2756
|
+
"mETH/USD": 3500,
|
|
2757
|
+
"stETH/USD": 3450,
|
|
2758
|
+
"wstETH/USD": 4100,
|
|
2759
|
+
// Meme
|
|
2760
|
+
"SHIB/USD": 22e-6,
|
|
2761
|
+
"PEPE/USD": 18e-6,
|
|
2762
|
+
"BONK/USD": 28e-6,
|
|
2763
|
+
"WIF/USD": 1.85,
|
|
2764
|
+
// Commodities
|
|
2765
|
+
"XAU/USD": 2650,
|
|
2766
|
+
"XAG/USD": 31,
|
|
2767
|
+
// Forex
|
|
2768
|
+
"EUR/USD": 1.08,
|
|
2769
|
+
"GBP/USD": 1.27,
|
|
2770
|
+
"JPY/USD": 67e-4,
|
|
2771
|
+
// Equities
|
|
2772
|
+
"AAPL/USD": 248,
|
|
2773
|
+
"NVDA/USD": 138,
|
|
2774
|
+
"TSLA/USD": 385,
|
|
2775
|
+
"MSFT/USD": 425
|
|
2776
|
+
};
|
|
2777
|
+
const price = mockPrices[pair] || 100;
|
|
2778
|
+
const decimals = price < 0.01 ? 8 : price < 1 ? 4 : 2;
|
|
2779
|
+
return {
|
|
2780
|
+
priceFeedId: feedId,
|
|
2781
|
+
pair,
|
|
2782
|
+
price: Math.floor(price * 1e8).toString(),
|
|
2783
|
+
confidence: "50000",
|
|
2784
|
+
exponent: -8,
|
|
2785
|
+
publishTime: Math.floor(Date.now() / 1e3),
|
|
2786
|
+
formattedPrice: price.toFixed(decimals)
|
|
2787
|
+
};
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2790
|
+
// src/constants/token-launchpad/index.ts
|
|
2791
|
+
var token_launchpad_exports = {};
|
|
2792
|
+
__export(token_launchpad_exports, {
|
|
2793
|
+
ERC20_ABI: () => ERC20_ABI
|
|
2794
|
+
});
|
|
2795
|
+
var ERC20_ABI = [
|
|
2796
|
+
{
|
|
2797
|
+
inputs: [],
|
|
2798
|
+
name: "name",
|
|
2799
|
+
outputs: [{ name: "", type: "string" }],
|
|
2800
|
+
stateMutability: "view",
|
|
2801
|
+
type: "function"
|
|
2802
|
+
},
|
|
2803
|
+
{
|
|
2804
|
+
inputs: [],
|
|
2805
|
+
name: "symbol",
|
|
2806
|
+
outputs: [{ name: "", type: "string" }],
|
|
2807
|
+
stateMutability: "view",
|
|
2808
|
+
type: "function"
|
|
2809
|
+
},
|
|
2810
|
+
{
|
|
2811
|
+
inputs: [],
|
|
2812
|
+
name: "decimals",
|
|
2813
|
+
outputs: [{ name: "", type: "uint8" }],
|
|
2814
|
+
stateMutability: "view",
|
|
2815
|
+
type: "function"
|
|
2816
|
+
},
|
|
2817
|
+
{
|
|
2818
|
+
inputs: [],
|
|
2819
|
+
name: "totalSupply",
|
|
2820
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
2821
|
+
stateMutability: "view",
|
|
2822
|
+
type: "function"
|
|
2823
|
+
},
|
|
2824
|
+
{
|
|
2825
|
+
inputs: [{ name: "account", type: "address" }],
|
|
2826
|
+
name: "balanceOf",
|
|
2827
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
2828
|
+
stateMutability: "view",
|
|
2829
|
+
type: "function"
|
|
2830
|
+
},
|
|
2831
|
+
{
|
|
2832
|
+
inputs: [
|
|
2833
|
+
{ name: "to", type: "address" },
|
|
2834
|
+
{ name: "amount", type: "uint256" }
|
|
2835
|
+
],
|
|
2836
|
+
name: "transfer",
|
|
2837
|
+
outputs: [{ name: "", type: "bool" }],
|
|
2838
|
+
stateMutability: "nonpayable",
|
|
2839
|
+
type: "function"
|
|
2840
|
+
}
|
|
2841
|
+
];
|
|
2842
|
+
|
|
2843
|
+
// src/tools/token-launchpad/deployToken.ts
|
|
2844
|
+
var ERC20_BYTECODE = "0x608060405234801561001057600080fd5b5060405161089a38038061089a833981016040819052610032916101db565b8251839083906100499060039060208501906100b4565b50805161005d9060049060208401906100b4565b50505061007a33826100756012600a6102eb565b610081565b5050610359565b6001600160a01b0382166100ab5760405163ec442f0560e01b815260006004820152602401604051809103906000fd5b6100b760008383610140565b5050565b8280546100c09061030c565b90600052602060002090601f0160209004810192826100e2576000855561012e565b82601f106100f357805160ff191683800117855561012e565b8280016001018555821561012e579182015b8281111561012e578251825591602001919060010190610105565b5061013a92915061013e565b5090565b5b8082111561013a576000815560010161013f565b6001600160a01b038316610174578060026000828254610160919061034b565b9091555061019f9050565b6001600160a01b0383166000908152602081905260408120805483929061019c908490610346565b90915550505b6001600160a01b0382166101c1576002805482900390556101e6565b6001600160a01b03821660009081526020819052604081208054839290610169908490610346565b816001600160a01b0316836001600160a01b03166000805160206108228339815191528360405161021991815260200190565b60405180910390a3505050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561025757818101518382015260200161023f565b83811115610268576000848401525b50505050565b600082601f83011261027e578081fd5b81516001600160401b038082111561029857610298610226565b604051601f8301601f19908116603f011681019082821181831017156102c0576102c0610226565b816040528381528660208588010111156102d8578485fd5b6102e9846020830160208901610240565b9695505050505050565b60008060006060848603121561030757600080fd5b83516001600160401b038082111561031d578586fd5b6103298783880161026e565b9450602086015191508082111561033e578384fd5b5061034b8682870161026e565b925050604084015190509250925092565b634e487b7160e01b600052601160045260246000fd5b600181815b808511156103ad57816000190482111561039357610393610372565b808516156103a057918102915b93841c939080029061037c565b509250929050565b6000826103c457506001610460565b816103d157506000610460565b81600181146103e757600281146103f15761040d565b6001915050610460565b60ff84111561040257610402610372565b50506001821b610460565b5060208310610133831016604e8410600b8410161715610430575081810a610460565b61043a8383610377565b806000190482111561044e5761044e610372565b029392505050565b600061046283836103b5565b9392505050565b61046b610482565b600082821015610479576104796103a2565b50039056fe";
|
|
2845
|
+
var RWA_BYTECODE = "0x608060405234801561001057600080fd5b5060405161089a38038061089a833981016040819052610032916101db565b8251839083906100499060039060208501906100b4565b50805161005d9060049060208401906100b4565b50505061007a33826100756012600a6102eb565b610081565b5050610359565b6001600160a01b0382166100ab5760405163ec442f0560e01b815260006004820152602401604051809103906000fd5b6100b760008383610140565b5050565b8280546100c09061030c565b90600052602060002090601f0160209004810192826100e2576000855561012e565b82601f106100f357805160ff191683800117855561012e565b8280016001018555821561012e579182015b8281111561012e578251825591602001919060010190610105565b5061013a92915061013e565b5090565b5b8082111561013a576000815560010161013f565b6001600160a01b038316610174578060026000828254610160919061034b565b9091555061019f9050565b6001600160a01b0383166000908152602081905260408120805483929061019c908490610346565b90915550505b6001600160a01b0382166101c1576002805482900390556101e6565b6001600160a01b03821660009081526020819052604081208054839290610169908490610346565b816001600160a01b0316836001600160a01b03166000805160206108228339815191528360405161021991815260200190565b60405180910390a3505050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561025757818101518382015260200161023f565b83811115610268576000848401525b50505050565b600082601f83011261027e578081fd5b81516001600160401b038082111561029857610298610226565b604051601f8301601f19908116603f011681019082821181831017156102c0576102c0610226565b816040528381528660208588010111156102d8578485fd5b6102e9846020830160208901610240565b9695505050505050565b60008060006060848603121561030757600080fd5b83516001600160401b038082111561031d578586fd5b6103298783880161026e565b9450602086015191508082111561033e578384fd5b5061034b8682870161026e565b925050604084015190509250925092565b634e487b7160e01b600052601160045260246000fd5b600181815b808511156103ad57816000190482111561039357610393610372565b808516156103a057918102915b93841c939080029061037c565b509250929050565b6000826103c457506001610460565b816103d157506000610460565b81600181146103e757600281146103f15761040d565b6001915050610460565b60ff84111561040257610402610372565b50506001821b610460565b5060208310610133831016604e8410600b8410161715610430575081810a610460565b61043a8383610377565b806000190482111561044e5761044e610372565b029392505050565b600061046283836103b5565b9392505050565b61046b610482565b600082821015610479576104796103a2565b50039056fe";
|
|
2846
|
+
async function deployToken(agent, name, symbol, supply, tokenType = "standard", assetType, assetId) {
|
|
2847
|
+
const decimals = 18;
|
|
2848
|
+
const supplyInWei = parseUnits(supply, decimals).toString();
|
|
2849
|
+
if (agent.demo) {
|
|
2850
|
+
return {
|
|
2851
|
+
tokenAddress: `0xDEMO${tokenType === "rwa" ? "RWA" : "TKN"}00000000000000000001`,
|
|
2852
|
+
txHash: DEMO_TX_HASH,
|
|
2853
|
+
name,
|
|
2854
|
+
symbol,
|
|
2855
|
+
decimals,
|
|
2856
|
+
totalSupply: supplyInWei,
|
|
2857
|
+
mintedTo: agent.account.address,
|
|
2858
|
+
tokenType,
|
|
2859
|
+
assetType,
|
|
2860
|
+
assetId
|
|
2861
|
+
};
|
|
2862
|
+
}
|
|
2863
|
+
if (!name?.trim()) throw new Error("Token name required");
|
|
2864
|
+
if (!symbol?.trim()) throw new Error("Token symbol required");
|
|
2865
|
+
if (!supply || Number(supply) <= 0) throw new Error("Supply must be > 0");
|
|
2866
|
+
const args = encodeAbiParameters(
|
|
2867
|
+
parseAbiParameters("string, string, uint256"),
|
|
2868
|
+
[name, symbol, BigInt(supplyInWei)]
|
|
2869
|
+
);
|
|
2870
|
+
const bytecode = tokenType === "rwa" ? RWA_BYTECODE : ERC20_BYTECODE;
|
|
2871
|
+
const deployData = bytecode + args.slice(2);
|
|
2872
|
+
const txHash = await agent.client.sendTransaction({ data: deployData });
|
|
2873
|
+
const receipt = await agent.client.waitForTransactionReceipt({ hash: txHash });
|
|
2874
|
+
if (!receipt.contractAddress) {
|
|
2875
|
+
throw new Error("Deployment failed - no contract address");
|
|
2876
|
+
}
|
|
2877
|
+
return {
|
|
2878
|
+
tokenAddress: receipt.contractAddress,
|
|
2879
|
+
txHash,
|
|
2880
|
+
name,
|
|
2881
|
+
symbol,
|
|
2882
|
+
decimals,
|
|
2883
|
+
totalSupply: supplyInWei,
|
|
2884
|
+
mintedTo: agent.account.address,
|
|
2885
|
+
tokenType,
|
|
2886
|
+
assetType,
|
|
2887
|
+
assetId
|
|
2888
|
+
};
|
|
2889
|
+
}
|
|
2890
|
+
async function deployStandardToken(agent, name, symbol, supply) {
|
|
2891
|
+
return deployToken(agent, name, symbol, supply, "standard");
|
|
2892
|
+
}
|
|
2893
|
+
async function deployRWAToken(agent, name, symbol, supply, assetType, assetId) {
|
|
2894
|
+
return deployToken(agent, name, symbol, supply, "rwa", assetType, assetId);
|
|
2895
|
+
}
|
|
2896
|
+
async function getTokenInfo(agent, tokenAddress, holder) {
|
|
2897
|
+
if (agent.demo) {
|
|
2898
|
+
return {
|
|
2899
|
+
address: tokenAddress,
|
|
2900
|
+
name: "Demo Token",
|
|
2901
|
+
symbol: "DEMO",
|
|
2902
|
+
decimals: 18,
|
|
2903
|
+
totalSupply: "1000000000000000000000000",
|
|
2904
|
+
balance: holder ? "1000000000000000000000" : void 0
|
|
2905
|
+
};
|
|
2906
|
+
}
|
|
2907
|
+
const [name, symbol, decimals, totalSupply] = await Promise.all([
|
|
2908
|
+
agent.client.readContract({ address: tokenAddress, abi: erc20Abi$1, functionName: "name" }),
|
|
2909
|
+
agent.client.readContract({ address: tokenAddress, abi: erc20Abi$1, functionName: "symbol" }),
|
|
2910
|
+
agent.client.readContract({ address: tokenAddress, abi: erc20Abi$1, functionName: "decimals" }),
|
|
2911
|
+
agent.client.readContract({ address: tokenAddress, abi: erc20Abi$1, functionName: "totalSupply" })
|
|
2912
|
+
]);
|
|
2913
|
+
const result = {
|
|
2914
|
+
address: tokenAddress,
|
|
2915
|
+
name,
|
|
2916
|
+
symbol,
|
|
2917
|
+
decimals,
|
|
2918
|
+
totalSupply: totalSupply.toString()
|
|
2919
|
+
};
|
|
2920
|
+
if (holder) {
|
|
2921
|
+
const balance = await agent.client.readContract({
|
|
2922
|
+
address: tokenAddress,
|
|
2923
|
+
abi: erc20Abi$1,
|
|
2924
|
+
functionName: "balanceOf",
|
|
2925
|
+
args: [holder]
|
|
2926
|
+
});
|
|
2927
|
+
result.balance = balance.toString();
|
|
2928
|
+
}
|
|
2929
|
+
return result;
|
|
2930
|
+
}
|
|
2931
|
+
async function getTokenBalance(agent, tokenAddress, holder) {
|
|
2932
|
+
if (agent.demo) return "1000000000000000000000";
|
|
2933
|
+
const balance = await agent.client.readContract({
|
|
2934
|
+
address: tokenAddress,
|
|
2935
|
+
abi: erc20Abi$1,
|
|
2936
|
+
functionName: "balanceOf",
|
|
2937
|
+
args: [holder || agent.account.address]
|
|
2938
|
+
});
|
|
2939
|
+
return balance.toString();
|
|
2940
|
+
}
|
|
2941
|
+
async function transferToken(agent, tokenAddress, to, amount) {
|
|
2942
|
+
if (agent.demo) return DEMO_TX_HASH;
|
|
2943
|
+
const data = encodeFunctionData({
|
|
2944
|
+
abi: erc20Abi$1,
|
|
2945
|
+
functionName: "transfer",
|
|
2946
|
+
args: [to, BigInt(amount)]
|
|
2947
|
+
});
|
|
2948
|
+
const txHash = await agent.client.sendTransaction({ to: tokenAddress, data });
|
|
2949
|
+
await agent.client.waitForTransactionReceipt({ hash: txHash });
|
|
2950
|
+
return txHash;
|
|
2951
|
+
}
|
|
2952
|
+
|
|
2953
|
+
// src/constants/nft-launchpad/index.ts
|
|
2954
|
+
var nft_launchpad_exports = {};
|
|
2955
|
+
__export(nft_launchpad_exports, {
|
|
2956
|
+
ERC721_ABI: () => ERC721_ABI
|
|
2957
|
+
});
|
|
2958
|
+
var ERC721_ABI = [
|
|
2959
|
+
// Constructor-related
|
|
2960
|
+
{
|
|
2961
|
+
inputs: [
|
|
2962
|
+
{ name: "name", type: "string" },
|
|
2963
|
+
{ name: "symbol", type: "string" },
|
|
2964
|
+
{ name: "baseURI", type: "string" },
|
|
2965
|
+
{ name: "maxSupply", type: "uint256" }
|
|
2966
|
+
],
|
|
2967
|
+
stateMutability: "nonpayable",
|
|
2968
|
+
type: "constructor"
|
|
2969
|
+
},
|
|
2970
|
+
// View functions
|
|
2971
|
+
{
|
|
2972
|
+
inputs: [],
|
|
2973
|
+
name: "name",
|
|
2974
|
+
outputs: [{ name: "", type: "string" }],
|
|
2975
|
+
stateMutability: "view",
|
|
2976
|
+
type: "function"
|
|
2977
|
+
},
|
|
2978
|
+
{
|
|
2979
|
+
inputs: [],
|
|
2980
|
+
name: "symbol",
|
|
2981
|
+
outputs: [{ name: "", type: "string" }],
|
|
2982
|
+
stateMutability: "view",
|
|
2983
|
+
type: "function"
|
|
2984
|
+
},
|
|
2985
|
+
{
|
|
2986
|
+
inputs: [],
|
|
2987
|
+
name: "totalSupply",
|
|
2988
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
2989
|
+
stateMutability: "view",
|
|
2990
|
+
type: "function"
|
|
2991
|
+
},
|
|
2992
|
+
{
|
|
2993
|
+
inputs: [{ name: "tokenId", type: "uint256" }],
|
|
2994
|
+
name: "tokenURI",
|
|
2995
|
+
outputs: [{ name: "", type: "string" }],
|
|
2996
|
+
stateMutability: "view",
|
|
2997
|
+
type: "function"
|
|
2998
|
+
},
|
|
2999
|
+
{
|
|
3000
|
+
inputs: [{ name: "tokenId", type: "uint256" }],
|
|
3001
|
+
name: "ownerOf",
|
|
3002
|
+
outputs: [{ name: "", type: "address" }],
|
|
3003
|
+
stateMutability: "view",
|
|
3004
|
+
type: "function"
|
|
3005
|
+
},
|
|
3006
|
+
{
|
|
3007
|
+
inputs: [{ name: "owner", type: "address" }],
|
|
3008
|
+
name: "balanceOf",
|
|
3009
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
3010
|
+
stateMutability: "view",
|
|
3011
|
+
type: "function"
|
|
3012
|
+
},
|
|
3013
|
+
{
|
|
3014
|
+
inputs: [{ name: "tokenId", type: "uint256" }],
|
|
3015
|
+
name: "getApproved",
|
|
3016
|
+
outputs: [{ name: "", type: "address" }],
|
|
3017
|
+
stateMutability: "view",
|
|
3018
|
+
type: "function"
|
|
3019
|
+
},
|
|
3020
|
+
{
|
|
3021
|
+
inputs: [
|
|
3022
|
+
{ name: "owner", type: "address" },
|
|
3023
|
+
{ name: "operator", type: "address" }
|
|
3024
|
+
],
|
|
3025
|
+
name: "isApprovedForAll",
|
|
3026
|
+
outputs: [{ name: "", type: "bool" }],
|
|
3027
|
+
stateMutability: "view",
|
|
3028
|
+
type: "function"
|
|
3029
|
+
},
|
|
3030
|
+
// State changing functions
|
|
3031
|
+
{
|
|
3032
|
+
inputs: [{ name: "to", type: "address" }],
|
|
3033
|
+
name: "mint",
|
|
3034
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
3035
|
+
stateMutability: "nonpayable",
|
|
3036
|
+
type: "function"
|
|
3037
|
+
},
|
|
3038
|
+
{
|
|
3039
|
+
inputs: [
|
|
3040
|
+
{ name: "to", type: "address" },
|
|
3041
|
+
{ name: "quantity", type: "uint256" }
|
|
3042
|
+
],
|
|
3043
|
+
name: "batchMint",
|
|
3044
|
+
outputs: [{ name: "startTokenId", type: "uint256" }],
|
|
3045
|
+
stateMutability: "nonpayable",
|
|
3046
|
+
type: "function"
|
|
3047
|
+
},
|
|
3048
|
+
{
|
|
3049
|
+
inputs: [
|
|
3050
|
+
{ name: "to", type: "address" },
|
|
3051
|
+
{ name: "tokenId", type: "uint256" }
|
|
3052
|
+
],
|
|
3053
|
+
name: "approve",
|
|
3054
|
+
outputs: [],
|
|
3055
|
+
stateMutability: "nonpayable",
|
|
3056
|
+
type: "function"
|
|
3057
|
+
},
|
|
3058
|
+
{
|
|
3059
|
+
inputs: [
|
|
3060
|
+
{ name: "operator", type: "address" },
|
|
3061
|
+
{ name: "approved", type: "bool" }
|
|
3062
|
+
],
|
|
3063
|
+
name: "setApprovalForAll",
|
|
3064
|
+
outputs: [],
|
|
3065
|
+
stateMutability: "nonpayable",
|
|
3066
|
+
type: "function"
|
|
3067
|
+
},
|
|
3068
|
+
{
|
|
3069
|
+
inputs: [
|
|
3070
|
+
{ name: "from", type: "address" },
|
|
3071
|
+
{ name: "to", type: "address" },
|
|
3072
|
+
{ name: "tokenId", type: "uint256" }
|
|
3073
|
+
],
|
|
3074
|
+
name: "transferFrom",
|
|
3075
|
+
outputs: [],
|
|
3076
|
+
stateMutability: "nonpayable",
|
|
3077
|
+
type: "function"
|
|
3078
|
+
},
|
|
3079
|
+
{
|
|
3080
|
+
inputs: [
|
|
3081
|
+
{ name: "from", type: "address" },
|
|
3082
|
+
{ name: "to", type: "address" },
|
|
3083
|
+
{ name: "tokenId", type: "uint256" }
|
|
3084
|
+
],
|
|
3085
|
+
name: "safeTransferFrom",
|
|
3086
|
+
outputs: [],
|
|
3087
|
+
stateMutability: "nonpayable",
|
|
3088
|
+
type: "function"
|
|
3089
|
+
},
|
|
3090
|
+
{
|
|
3091
|
+
inputs: [
|
|
3092
|
+
{ name: "from", type: "address" },
|
|
3093
|
+
{ name: "to", type: "address" },
|
|
3094
|
+
{ name: "tokenId", type: "uint256" },
|
|
3095
|
+
{ name: "data", type: "bytes" }
|
|
3096
|
+
],
|
|
3097
|
+
name: "safeTransferFrom",
|
|
3098
|
+
outputs: [],
|
|
3099
|
+
stateMutability: "nonpayable",
|
|
3100
|
+
type: "function"
|
|
3101
|
+
},
|
|
3102
|
+
// Events
|
|
3103
|
+
{
|
|
3104
|
+
anonymous: false,
|
|
3105
|
+
inputs: [
|
|
3106
|
+
{ indexed: true, name: "from", type: "address" },
|
|
3107
|
+
{ indexed: true, name: "to", type: "address" },
|
|
3108
|
+
{ indexed: true, name: "tokenId", type: "uint256" }
|
|
3109
|
+
],
|
|
3110
|
+
name: "Transfer",
|
|
3111
|
+
type: "event"
|
|
3112
|
+
},
|
|
3113
|
+
{
|
|
3114
|
+
anonymous: false,
|
|
3115
|
+
inputs: [
|
|
3116
|
+
{ indexed: true, name: "owner", type: "address" },
|
|
3117
|
+
{ indexed: true, name: "approved", type: "address" },
|
|
3118
|
+
{ indexed: true, name: "tokenId", type: "uint256" }
|
|
3119
|
+
],
|
|
3120
|
+
name: "Approval",
|
|
3121
|
+
type: "event"
|
|
3122
|
+
},
|
|
3123
|
+
{
|
|
3124
|
+
anonymous: false,
|
|
3125
|
+
inputs: [
|
|
3126
|
+
{ indexed: true, name: "owner", type: "address" },
|
|
3127
|
+
{ indexed: true, name: "operator", type: "address" },
|
|
3128
|
+
{ indexed: false, name: "approved", type: "bool" }
|
|
3129
|
+
],
|
|
3130
|
+
name: "ApprovalForAll",
|
|
3131
|
+
type: "event"
|
|
3132
|
+
}
|
|
3133
|
+
];
|
|
3134
|
+
|
|
3135
|
+
// src/tools/nft-launchpad/deployCollection.ts
|
|
3136
|
+
var ERC721_CREATION_CODE = `0x608060405234801561001057600080fd5b506040516112a03803806112a0833981016040819052610032916101e5565b83838383600061004283826102f4565b50600161004f82826102f4565b5050600680546001600160a01b0319163317905550600782905560088190555050505050506103b3565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261009f57600080fd5b81516001600160401b03808211156100b9576100b9610079565b604051601f8301601f19908116603f011681019082821181831017156100e1576100e1610079565b816040528381526020925086838588010111156100fd57600080fd5b600091505b8382101561011f5785820183015181830184015290820190610102565b6000928101909201929092529392505050565b60008060008060808587031215610148578384fd5b84516001600160401b038082111561015e578586fd5b61016a8883890161008f565b9550602087015191508082111561017f578485fd5b5061018c8782880161008f565b9350506040850151915060608501519050929550929550929292909250565b600181811c908216806101bf57607f821691505b6020821081036101df57634e487b7160e01b600052602260045260246000fd5b50919050565b600080600080608085870312156101fa578384fd5b84516001600160401b0380821115610210578586fd5b61021c8883890161008f565b95506020870151915080821115610231578485fd5b5061023e8782880161008f565b935050604085015191506060850151905092959194509250565b601f82111561029f57600081815260208120601f850160051c8101602086101561027f5750805b601f850160051c820191505b8181101561029e5782815560010161028b565b505050505050565b81516001600160401b038111156102bf576102bf610079565b6102d3816102cd84546101ab565b84610258565b602080601f83116001811461030857600084156102f05750858301515b600019600386901b1c1916600185901b17855561029e565b600085815260208120601f198616915b8281101561033757888601518255948401946001909101908401610318565b50858210156103555787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600082601f83011261037657600080fd5b81356001600160401b0381111561038f5761038f610079565b6040516020601f19601f85011681018181106001600160401b03821117156103b9576103b9610079565b6040528281528484830111156103ce57600080fd5b8282602083013760009201829052509392505050565b600080600080608085870312156103f9578384fd5b84356001600160401b038082111561040f578586fd5b61041b88838901610365565b95506020870135915080821115610430578485fd5b5061043d87828801610365565b935050604085013591506060850135905092959194509250565b610ede806103c26000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80636352211e11610097578063a22cb46511610066578063a22cb465146101f3578063b88d4fde14610206578063c87b56dd14610219578063e985e9c51461022c57600080fd5b80636352211e146101a75780636a627842146101ba57806370a08231146101cd57806395d89b41146101eb57600080fd5b8063095ea7b3116100d3578063095ea7b31461016257806318160ddd1461017757806323b872dd1461018157806342842e0e1461019457600080fd5b806301ffc9a7146100fa57806306fdde0314610122578063081812fc14610137575b600080fd5b61010d610108366004610b4a565b610268565b60405190151581526020015b60405180910390f35b61012a6102ba565b6040516101199190610bb7565b61014a610145366004610bca565b61034c565b6040516001600160a01b039091168152602001610119565b610175610170366004610bff565b610373565b005b6005545b604051908152602001610119565b61017561018f366004610c29565b61048d565b6101756101a2366004610c29565b6104be565b61014a6101b5366004610bca565b6104d9565b61017b6101c8366004610c65565b610539565b61017b6101db366004610c65565b6001600160a01b031660009081526003602052604090205490565b61012a6105d6565b610175610201366004610c80565b6105e5565b610175610214366004610cd2565b6105f4565b61012a610227366004610bca565b61062c565b61010d61023a366004610dae565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b60006001600160e01b031982166380ac58cd60e01b148061029957506001600160e01b03198216635b5e139f60e01b145b806102b457506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600080546102c990610de1565b80601f01602080910402602001604051908101604052809291908181526020018280546102f590610de1565b80156103425780601f1061031757610100808354040283529160200191610342565b820191906000526020600020905b81548152906001019060200180831161032557829003601f168201915b5050505050905090565b600061035782610697565b506000908152600260205260409020546001600160a01b031690565b600061037e826104d9565b9050806001600160a01b0316836001600160a01b0316036103f05760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b038216148061040c575061040c813361023a565b61047e5760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c00000060648201526084016103e7565b61048883836106f6565b505050565b6104973382610764565b6104b35760405162461bcd60e51b81526004016103e790610e1b565b6104888383836107c3565b61048883838360405180602001604052806000815250610930565b6000818152600260205260408120546001600160a01b0316806102b45760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016103e7565b6006546000906001600160a01b031633146105965760405162461bcd60e51b815260206004820152601960248201527f4f6e6c79206f776e65722063616e206d696e7420746f6b656e730000000000006044820152606401610e7565b600580549060006105a683610e68565b91905055905060075460001480156105bf575060075481115b156105c957600080fd5b6105d38382610944565b50919050565b6060600180546102c990610de1565b6105f033838361095e565b5050565b6105fe3383610764565b61061a5760405162461bcd60e51b81526004016103e790610e1b565b61062684848484610a2c565b50505050565b606061063782610697565b600061064e60408051602081019091526000815290565b9050600081511161066e5760405180602001604052806000815250610690565b8061067884610a5f565b604051602001610689929190610e81565b6040519091905056fe60005b838110156106ae578181015183820152602001610696565b50506000910152565b60006102b4826001600160a01b03163b151590565b806001600160a01b0316826001600160a01b0316036107225760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f76616c20746f2073656c660000000000000000604482015260640160405180910390fd5b6001600160a01b03838116600081815260046020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0382166107b25760405162461bcd60e51b815260206004820152601160248201527045524337323: 696e76616c6964206164647260781b604482015260640160405180910390fd5b6000818152600260205260408120546001600160a01b0316906107d490610aff565b6001600160a01b0384166000908152600360205260408120805460019290610807908490610eb0565b909155505060008281526002602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000818152600260205260408120546001600160a01b031661092c5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840160405180910390fd5b6000610937836104d9565b9050806001600160a01b0316846001600160a01b031614806109725750836001600160a01b03166109678461034c565b6001600160a01b0316145b8061098257506109828185610b23565b949350505050565b61098d8484846107c3565b61099984848484610b4c565b6106265760405162461bcd60e51b81526004016103e790610ec3565b6105f08282604051806020016040528060008152506109d3836109b5565b6109bf8383610a2c565b6109cc6000848484610b4c565b5050505050565b816001600160a01b0316836001600160a01b0316036109fe5760405162461bcd60e51b81526004016103e790610f0c565b6001600160a01b0382811660008181526004602090815260408083209487168084529482529182902080548615157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909116179055905190825290917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3191015b60405180910390a3505050565b610a376107c3565b610a4384848484610c25565b5050505050565b60606000610a5783610c58565b600101905060008167ffffffffffffffff811115610a7757610a77610cbc565b6040519080825280601f01601f191660200182016040528015610aa1576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610aab57509392505050565b600060001982015b6000838152600260205260409020546001600160a01b0316610b085750919050565b8015610b145792915050565b82610b1e81610f4f565b935050610b07565b6001600160a01b03918216600090815260046020908152604080832093909416825291909152205460ff1690565b60006001600160a01b0384163b15610c1a57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610b90903390899088908890600401610f66565b6020604051808303816000875af1925050508015610bcb575060408051601f3d908101601f19168201909252610bc891810190610f99565b60015b610c00573d808015610bf9576040519150601f19603f3d011682016040523d82523d6000602084013e610bfe565b606091505b505080515f03610c185760405162461bcd60e51b81526004016103e790610ec3565b505b6001600160e01b031916630a85bd0160e11b149050610982565b506001949350505050565b610c318484846107c3565b610c3d84848484610b4c565b6106265760405162461bcd60e51b81526004016103e790610ec3565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610c975772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610cc3576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610ce157662386f26fc10000830492506010015b6305f5e1008310610cf9576305f5e100830492506008015b6127108310610d0d57612710830492506004015b60648310610d1f576064830492506002015b600a83106102b45760010192915050565b6001600160e01b031981168114610d4657600080fd5b50565b600060208284031215610d5a578081fd5b8135610d6581610d30565b9392505050565b60005b83811015610d87578181015183820152602001610d6f565b50506000910152565b60008151808452610da8816020860160208601610d6c565b601f01601f19169290920160200192915050565b602081526000610d656020830184610d90565b600060208284031215610de0578081fd5b5035919050565b80356001600160a01b0381168114610dfe57600080fd5b919050565b60008060408385031215610e15578081fd5b610e1e83610de7565b946020939093013593505050565b600080600060608486031215610e40578081fd5b610e4984610de7565b9250610e5760208501610de7565b9150604084013590509250925092565b600060208284031215610e78578081fd5b610d6582610de7565b60008060408385031215610e93578182fd5b610e9c83610de7565b915060208301358015158114610eb0578182fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600082601f830112610ee1578081fd5b813567ffffffffffffffff80821115610efc57610efc610ebb565b604051601f8301601f19908116603f01168101908282118183101715610f2457610f24610ebb565b81604052838152866020858801011115610f3c578485fd5b83602087016020830137600060208583010152809450505050509291505056fea264697066735822122000000000000000000000000000000000000000000000000000000000000000064736f6c63430008150033`;
|
|
3137
|
+
async function deployNFTCollection(agent, config) {
|
|
3138
|
+
const { name, symbol, baseURI, maxSupply = 0 } = config;
|
|
3139
|
+
if (agent.demo) {
|
|
3140
|
+
return {
|
|
3141
|
+
collectionAddress: "0xDEMO000000000000000000000000000000000002",
|
|
3142
|
+
txHash: DEMO_TX_HASH,
|
|
3143
|
+
name,
|
|
3144
|
+
symbol,
|
|
3145
|
+
baseURI,
|
|
3146
|
+
maxSupply,
|
|
3147
|
+
deployer: agent.account.address
|
|
3148
|
+
};
|
|
3149
|
+
}
|
|
3150
|
+
if (!name || name.length === 0) {
|
|
3151
|
+
throw new Error("Collection name is required");
|
|
3152
|
+
}
|
|
3153
|
+
if (!symbol || symbol.length === 0) {
|
|
3154
|
+
throw new Error("Collection symbol is required");
|
|
3155
|
+
}
|
|
3156
|
+
if (!baseURI) {
|
|
3157
|
+
throw new Error("Base URI is required for token metadata");
|
|
3158
|
+
}
|
|
3159
|
+
const constructorArgs = encodeAbiParameters(
|
|
3160
|
+
parseAbiParameters(
|
|
3161
|
+
"string name, string symbol, string baseURI, uint256 maxSupply"
|
|
3162
|
+
),
|
|
3163
|
+
[name, symbol, baseURI, BigInt(maxSupply)]
|
|
3164
|
+
);
|
|
3165
|
+
const deploymentBytecode = ERC721_CREATION_CODE + constructorArgs.slice(2);
|
|
3166
|
+
const txHash = await agent.client.sendTransaction({
|
|
3167
|
+
data: deploymentBytecode
|
|
3168
|
+
});
|
|
3169
|
+
const receipt = await agent.client.waitForTransactionReceipt({ hash: txHash });
|
|
3170
|
+
if (!receipt.contractAddress) {
|
|
3171
|
+
throw new Error(
|
|
3172
|
+
"NFT Collection deployment failed - no contract address returned"
|
|
3173
|
+
);
|
|
3174
|
+
}
|
|
3175
|
+
return {
|
|
3176
|
+
collectionAddress: receipt.contractAddress,
|
|
3177
|
+
txHash,
|
|
3178
|
+
name,
|
|
3179
|
+
symbol,
|
|
3180
|
+
baseURI,
|
|
3181
|
+
maxSupply,
|
|
3182
|
+
deployer: agent.account.address
|
|
3183
|
+
};
|
|
3184
|
+
}
|
|
3185
|
+
async function deployNFTCollectionWithPreset(agent, preset, name, symbol, baseURI) {
|
|
3186
|
+
const presetConfigs = {
|
|
3187
|
+
pfp: 1e4,
|
|
3188
|
+
// Profile picture collections
|
|
3189
|
+
art: 1e3,
|
|
3190
|
+
// Art collections
|
|
3191
|
+
membership: 100,
|
|
3192
|
+
// Membership/pass collections
|
|
3193
|
+
unlimited: 0
|
|
3194
|
+
// Unlimited supply
|
|
3195
|
+
};
|
|
3196
|
+
return deployNFTCollection(agent, {
|
|
3197
|
+
name,
|
|
3198
|
+
symbol,
|
|
3199
|
+
baseURI,
|
|
3200
|
+
maxSupply: presetConfigs[preset]
|
|
3201
|
+
});
|
|
3202
|
+
}
|
|
3203
|
+
async function mintNFT(agent, collectionAddress, to) {
|
|
3204
|
+
const recipient = to || agent.account.address;
|
|
3205
|
+
if (agent.demo) {
|
|
3206
|
+
return {
|
|
3207
|
+
txHash: DEMO_TX_HASH,
|
|
3208
|
+
tokenId: "1",
|
|
3209
|
+
collectionAddress,
|
|
3210
|
+
to: recipient
|
|
3211
|
+
};
|
|
3212
|
+
}
|
|
3213
|
+
const data = encodeFunctionData({
|
|
3214
|
+
abi: ERC721_ABI,
|
|
3215
|
+
functionName: "mint",
|
|
3216
|
+
args: [recipient]
|
|
3217
|
+
});
|
|
3218
|
+
const txHash = await agent.client.sendTransaction({
|
|
3219
|
+
to: collectionAddress,
|
|
3220
|
+
data
|
|
3221
|
+
});
|
|
3222
|
+
const receipt = await agent.client.waitForTransactionReceipt({ hash: txHash });
|
|
3223
|
+
let tokenId = "0";
|
|
3224
|
+
for (const log of receipt.logs) {
|
|
3225
|
+
if (log.topics[0] === "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") {
|
|
3226
|
+
if (log.topics[3]) {
|
|
3227
|
+
tokenId = BigInt(log.topics[3]).toString();
|
|
3228
|
+
}
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
return {
|
|
3232
|
+
txHash,
|
|
3233
|
+
tokenId,
|
|
3234
|
+
collectionAddress,
|
|
3235
|
+
to: recipient
|
|
3236
|
+
};
|
|
3237
|
+
}
|
|
3238
|
+
async function batchMintNFT(agent, collectionAddress, to, quantity) {
|
|
3239
|
+
if (agent.demo) {
|
|
3240
|
+
return {
|
|
3241
|
+
txHash: DEMO_TX_HASH,
|
|
3242
|
+
startTokenId: "1",
|
|
3243
|
+
quantity
|
|
3244
|
+
};
|
|
3245
|
+
}
|
|
3246
|
+
const data = encodeFunctionData({
|
|
3247
|
+
abi: ERC721_ABI,
|
|
3248
|
+
functionName: "batchMint",
|
|
3249
|
+
args: [to, BigInt(quantity)]
|
|
3250
|
+
});
|
|
3251
|
+
const txHash = await agent.client.sendTransaction({
|
|
3252
|
+
to: collectionAddress,
|
|
3253
|
+
data
|
|
3254
|
+
});
|
|
3255
|
+
const receipt = await agent.client.waitForTransactionReceipt({ hash: txHash });
|
|
3256
|
+
let startTokenId = "1";
|
|
3257
|
+
for (const log of receipt.logs) {
|
|
3258
|
+
if (log.topics[0] === "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") {
|
|
3259
|
+
if (log.topics[3]) {
|
|
3260
|
+
startTokenId = BigInt(log.topics[3]).toString();
|
|
3261
|
+
break;
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
return {
|
|
3266
|
+
txHash,
|
|
3267
|
+
startTokenId,
|
|
3268
|
+
quantity
|
|
3269
|
+
};
|
|
3270
|
+
}
|
|
3271
|
+
async function getNFTCollectionInfo(agent, collectionAddress, holderAddress) {
|
|
3272
|
+
if (agent.demo) {
|
|
3273
|
+
return {
|
|
3274
|
+
address: collectionAddress,
|
|
3275
|
+
name: "Demo NFT Collection",
|
|
3276
|
+
symbol: "DEMO",
|
|
3277
|
+
totalSupply: "100",
|
|
3278
|
+
balanceOf: holderAddress ? "5" : void 0
|
|
3279
|
+
};
|
|
3280
|
+
}
|
|
3281
|
+
const [name, symbol, totalSupply] = await Promise.all([
|
|
3282
|
+
agent.client.readContract({
|
|
3283
|
+
address: collectionAddress,
|
|
3284
|
+
abi: ERC721_ABI,
|
|
3285
|
+
functionName: "name"
|
|
3286
|
+
}),
|
|
3287
|
+
agent.client.readContract({
|
|
3288
|
+
address: collectionAddress,
|
|
3289
|
+
abi: ERC721_ABI,
|
|
3290
|
+
functionName: "symbol"
|
|
3291
|
+
}),
|
|
3292
|
+
agent.client.readContract({
|
|
3293
|
+
address: collectionAddress,
|
|
3294
|
+
abi: ERC721_ABI,
|
|
3295
|
+
functionName: "totalSupply"
|
|
3296
|
+
})
|
|
3297
|
+
]);
|
|
3298
|
+
const result = {
|
|
3299
|
+
address: collectionAddress,
|
|
3300
|
+
name,
|
|
3301
|
+
symbol,
|
|
3302
|
+
totalSupply: totalSupply.toString()
|
|
3303
|
+
};
|
|
3304
|
+
if (holderAddress) {
|
|
3305
|
+
const balance = await agent.client.readContract({
|
|
3306
|
+
address: collectionAddress,
|
|
3307
|
+
abi: ERC721_ABI,
|
|
3308
|
+
functionName: "balanceOf",
|
|
3309
|
+
args: [holderAddress]
|
|
3310
|
+
});
|
|
3311
|
+
result.balanceOf = balance.toString();
|
|
3312
|
+
}
|
|
3313
|
+
return result;
|
|
3314
|
+
}
|
|
3315
|
+
async function getNFTTokenInfo(agent, collectionAddress, tokenId) {
|
|
3316
|
+
if (agent.demo) {
|
|
3317
|
+
return {
|
|
3318
|
+
collectionAddress,
|
|
3319
|
+
tokenId,
|
|
3320
|
+
owner: agent.account.address,
|
|
3321
|
+
tokenURI: `https://example.com/metadata/${tokenId}.json`
|
|
3322
|
+
};
|
|
3323
|
+
}
|
|
3324
|
+
const [owner, tokenURI] = await Promise.all([
|
|
3325
|
+
agent.client.readContract({
|
|
3326
|
+
address: collectionAddress,
|
|
3327
|
+
abi: ERC721_ABI,
|
|
3328
|
+
functionName: "ownerOf",
|
|
3329
|
+
args: [BigInt(tokenId)]
|
|
3330
|
+
}),
|
|
3331
|
+
agent.client.readContract({
|
|
3332
|
+
address: collectionAddress,
|
|
3333
|
+
abi: ERC721_ABI,
|
|
3334
|
+
functionName: "tokenURI",
|
|
3335
|
+
args: [BigInt(tokenId)]
|
|
3336
|
+
})
|
|
3337
|
+
]);
|
|
3338
|
+
return {
|
|
3339
|
+
collectionAddress,
|
|
3340
|
+
tokenId,
|
|
3341
|
+
owner,
|
|
3342
|
+
tokenURI
|
|
3343
|
+
};
|
|
3344
|
+
}
|
|
3345
|
+
async function getNFTBalance(agent, collectionAddress, holderAddress) {
|
|
3346
|
+
const address = holderAddress || agent.account.address;
|
|
3347
|
+
if (agent.demo) {
|
|
3348
|
+
return "5";
|
|
3349
|
+
}
|
|
3350
|
+
const balance = await agent.client.readContract({
|
|
3351
|
+
address: collectionAddress,
|
|
3352
|
+
abi: ERC721_ABI,
|
|
3353
|
+
functionName: "balanceOf",
|
|
3354
|
+
args: [address]
|
|
3355
|
+
});
|
|
3356
|
+
return balance.toString();
|
|
3357
|
+
}
|
|
3358
|
+
async function isNFTOwner(agent, collectionAddress, tokenId, ownerAddress) {
|
|
3359
|
+
const address = ownerAddress || agent.account.address;
|
|
3360
|
+
if (agent.demo) {
|
|
3361
|
+
return true;
|
|
3362
|
+
}
|
|
3363
|
+
try {
|
|
3364
|
+
const owner = await agent.client.readContract({
|
|
3365
|
+
address: collectionAddress,
|
|
3366
|
+
abi: ERC721_ABI,
|
|
3367
|
+
functionName: "ownerOf",
|
|
3368
|
+
args: [BigInt(tokenId)]
|
|
3369
|
+
});
|
|
3370
|
+
return owner.toLowerCase() === address.toLowerCase();
|
|
3371
|
+
} catch {
|
|
3372
|
+
return false;
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
async function transferNFT(agent, collectionAddress, to, tokenId) {
|
|
3376
|
+
if (agent.demo) {
|
|
3377
|
+
return DEMO_TX_HASH;
|
|
3378
|
+
}
|
|
3379
|
+
const data = encodeFunctionData({
|
|
3380
|
+
abi: ERC721_ABI,
|
|
3381
|
+
functionName: "transferFrom",
|
|
3382
|
+
args: [agent.account.address, to, BigInt(tokenId)]
|
|
3383
|
+
});
|
|
3384
|
+
const txHash = await agent.client.sendTransaction({
|
|
3385
|
+
to: collectionAddress,
|
|
3386
|
+
data
|
|
3387
|
+
});
|
|
3388
|
+
await agent.client.waitForTransactionReceipt({ hash: txHash });
|
|
3389
|
+
return txHash;
|
|
3390
|
+
}
|
|
3391
|
+
async function safeTransferNFT(agent, collectionAddress, to, tokenId) {
|
|
3392
|
+
if (agent.demo) {
|
|
3393
|
+
return DEMO_TX_HASH;
|
|
3394
|
+
}
|
|
3395
|
+
const data = encodeFunctionData({
|
|
3396
|
+
abi: ERC721_ABI,
|
|
3397
|
+
functionName: "safeTransferFrom",
|
|
3398
|
+
args: [agent.account.address, to, BigInt(tokenId)]
|
|
3399
|
+
});
|
|
3400
|
+
const txHash = await agent.client.sendTransaction({
|
|
3401
|
+
to: collectionAddress,
|
|
3402
|
+
data
|
|
3403
|
+
});
|
|
3404
|
+
await agent.client.waitForTransactionReceipt({ hash: txHash });
|
|
3405
|
+
return txHash;
|
|
3406
|
+
}
|
|
3407
|
+
async function approveNFT(agent, collectionAddress, approved, tokenId) {
|
|
3408
|
+
if (agent.demo) {
|
|
3409
|
+
return DEMO_TX_HASH;
|
|
3410
|
+
}
|
|
3411
|
+
const data = encodeFunctionData({
|
|
3412
|
+
abi: ERC721_ABI,
|
|
3413
|
+
functionName: "approve",
|
|
3414
|
+
args: [approved, BigInt(tokenId)]
|
|
3415
|
+
});
|
|
3416
|
+
const txHash = await agent.client.sendTransaction({
|
|
3417
|
+
to: collectionAddress,
|
|
3418
|
+
data
|
|
3419
|
+
});
|
|
3420
|
+
await agent.client.waitForTransactionReceipt({ hash: txHash });
|
|
3421
|
+
return txHash;
|
|
3422
|
+
}
|
|
3423
|
+
async function setApprovalForAllNFT(agent, collectionAddress, operator, approved) {
|
|
3424
|
+
if (agent.demo) {
|
|
3425
|
+
return DEMO_TX_HASH;
|
|
3426
|
+
}
|
|
3427
|
+
const data = encodeFunctionData({
|
|
3428
|
+
abi: ERC721_ABI,
|
|
3429
|
+
functionName: "setApprovalForAll",
|
|
3430
|
+
args: [operator, approved]
|
|
3431
|
+
});
|
|
3432
|
+
const txHash = await agent.client.sendTransaction({
|
|
3433
|
+
to: collectionAddress,
|
|
3434
|
+
data
|
|
3435
|
+
});
|
|
3436
|
+
await agent.client.waitForTransactionReceipt({ hash: txHash });
|
|
3437
|
+
return txHash;
|
|
3438
|
+
}
|
|
3439
|
+
|
|
3440
|
+
// src/tools/okx/getSwapQuote.ts
|
|
3441
|
+
var getSwapQuote = async (agent, from, to, amount, slippagePercentage) => {
|
|
3442
|
+
if (agent.demo) {
|
|
3443
|
+
return createMockQuoteResponse("OKX", amount);
|
|
3444
|
+
}
|
|
3445
|
+
const chainIndex = agent.chain === "mainnet" ? "5000" : "5003";
|
|
3446
|
+
return getSwapTransaction(from, to, amount, chainIndex, slippagePercentage);
|
|
3447
|
+
};
|
|
3448
|
+
|
|
3449
|
+
// src/utils/x402/index.ts
|
|
3450
|
+
var DEFAULT_PLATFORM_URL = "https://mantle-devkit.vercel.app";
|
|
3451
|
+
var cachedConfig = null;
|
|
3452
|
+
var validationPromise = null;
|
|
3453
|
+
function getPlatformBaseUrl() {
|
|
3454
|
+
if (typeof process !== "undefined" && process.env) {
|
|
3455
|
+
return process.env.PLATFORM_URL || process.env.NEXT_PUBLIC_PLATFORM_URL || DEFAULT_PLATFORM_URL;
|
|
3456
|
+
}
|
|
3457
|
+
return DEFAULT_PLATFORM_URL;
|
|
3458
|
+
}
|
|
3459
|
+
async function validateAppId(appId) {
|
|
3460
|
+
const baseUrl2 = getPlatformBaseUrl();
|
|
3461
|
+
const url = `${baseUrl2}/api/v1/validate?appId=${encodeURIComponent(appId)}`;
|
|
3462
|
+
const response = await fetch(url, {
|
|
3463
|
+
method: "GET",
|
|
3464
|
+
headers: { "Content-Type": "application/json" }
|
|
3465
|
+
});
|
|
3466
|
+
if (!response.ok) {
|
|
3467
|
+
if (response.status === 404) {
|
|
3468
|
+
throw new Error(
|
|
3469
|
+
"Platform: Project not found. Invalid APP_ID. Please check your APP_ID configuration."
|
|
3470
|
+
);
|
|
3471
|
+
}
|
|
3472
|
+
if (response.status === 401) {
|
|
3473
|
+
throw new Error(
|
|
3474
|
+
"Platform: Unauthorized. Invalid APP_ID. Please verify your APP_ID."
|
|
3475
|
+
);
|
|
3476
|
+
}
|
|
3477
|
+
throw new Error(
|
|
3478
|
+
`Platform: Validation failed: ${response.status} ${response.statusText}`
|
|
3479
|
+
);
|
|
3480
|
+
}
|
|
3481
|
+
const data = await response.json();
|
|
3482
|
+
if (!data.appId || !data.payTo || !data.network) {
|
|
3483
|
+
throw new Error("Platform: Invalid response - missing required fields");
|
|
3484
|
+
}
|
|
3485
|
+
if (data.status !== "ACTIVE") {
|
|
3486
|
+
throw new Error(
|
|
3487
|
+
`Platform: Project is not active. Current status: ${data.status}`
|
|
3488
|
+
);
|
|
3489
|
+
}
|
|
3490
|
+
return {
|
|
3491
|
+
appId: data.appId,
|
|
3492
|
+
name: data.name,
|
|
3493
|
+
payTo: data.payTo,
|
|
3494
|
+
network: data.network,
|
|
3495
|
+
status: data.status
|
|
3496
|
+
};
|
|
3497
|
+
}
|
|
3498
|
+
async function initializePlatform() {
|
|
3499
|
+
if (cachedConfig) {
|
|
3500
|
+
return cachedConfig;
|
|
3501
|
+
}
|
|
3502
|
+
if (validationPromise) {
|
|
3503
|
+
return validationPromise;
|
|
3504
|
+
}
|
|
3505
|
+
let appId;
|
|
3506
|
+
if (typeof process !== "undefined" && process.env) {
|
|
3507
|
+
appId = process.env.APP_ID || process.env.NEXT_PUBLIC_APP_ID;
|
|
3508
|
+
}
|
|
3509
|
+
if (!appId || typeof appId !== "string" || appId.trim().length === 0) {
|
|
3510
|
+
throw new Error(
|
|
3511
|
+
"APP_ID is required. Set it in your .env file:\nAPP_ID=your_app_id_here"
|
|
3512
|
+
);
|
|
3513
|
+
}
|
|
3514
|
+
validationPromise = validateAppId(appId.trim());
|
|
3515
|
+
try {
|
|
3516
|
+
cachedConfig = await validationPromise;
|
|
3517
|
+
return cachedConfig;
|
|
3518
|
+
} catch (error) {
|
|
3519
|
+
validationPromise = null;
|
|
3520
|
+
throw error;
|
|
3521
|
+
}
|
|
3522
|
+
}
|
|
3523
|
+
function getProjectConfig() {
|
|
3524
|
+
if (!cachedConfig) {
|
|
3525
|
+
throw new Error(
|
|
3526
|
+
"Platform not initialized. Call initializePlatform() first."
|
|
3527
|
+
);
|
|
3528
|
+
}
|
|
3529
|
+
return cachedConfig;
|
|
3530
|
+
}
|
|
3531
|
+
async function getUserAccountData(agent, userAddress) {
|
|
3532
|
+
const lendingPoolAddress = LENDING_POOL[agent.chain];
|
|
3533
|
+
const address = userAddress || agent.account.address;
|
|
3534
|
+
if (lendingPoolAddress === "0x0000000000000000000000000000000000000000") {
|
|
3535
|
+
throw new Error(
|
|
3536
|
+
`Lendle LendingPool not configured for ${agent.chain}. Only available on mainnet.`
|
|
3537
|
+
);
|
|
3538
|
+
}
|
|
3539
|
+
const result = await agent.client.readContract({
|
|
3540
|
+
address: lendingPoolAddress,
|
|
3541
|
+
abi: LENDING_POOL_ABI,
|
|
3542
|
+
functionName: "getUserAccountData",
|
|
3543
|
+
args: [address]
|
|
3544
|
+
});
|
|
3545
|
+
return {
|
|
3546
|
+
totalCollateralETH: result[0],
|
|
3547
|
+
totalDebtETH: result[1],
|
|
3548
|
+
availableBorrowsETH: result[2],
|
|
3549
|
+
currentLiquidationThreshold: result[3],
|
|
3550
|
+
ltv: result[4],
|
|
3551
|
+
healthFactor: result[5]
|
|
3552
|
+
};
|
|
3553
|
+
}
|
|
3554
|
+
var MNTAgentKit = class {
|
|
3555
|
+
account;
|
|
3556
|
+
client;
|
|
3557
|
+
chain;
|
|
3558
|
+
demo;
|
|
3559
|
+
projectConfig;
|
|
3560
|
+
constructor(privateKey, chain) {
|
|
3561
|
+
this.account = privateKeyToAccount(privateKey);
|
|
3562
|
+
this.demo = chain === "testnet-demo";
|
|
3563
|
+
this.chain = chain === "testnet-demo" ? "testnet" : chain;
|
|
3564
|
+
this.client = createWalletClient({
|
|
3565
|
+
chain: this.chain == "mainnet" ? mantle : mantleSepoliaTestnet,
|
|
3566
|
+
transport: http(),
|
|
3567
|
+
account: this.account
|
|
3568
|
+
}).extend(publicActions).extend(erc7811Actions());
|
|
3569
|
+
}
|
|
3570
|
+
/**
|
|
3571
|
+
* Initialize the agent with platform validation
|
|
3572
|
+
*
|
|
3573
|
+
* Validates APP_ID with the platform API.
|
|
3574
|
+
* Must be called after creating the agent instance.
|
|
3575
|
+
*
|
|
3576
|
+
* @returns The initialized agent instance
|
|
3577
|
+
* @throws Error if APP_ID is not set or validation fails
|
|
3578
|
+
*
|
|
3579
|
+
* @example
|
|
3580
|
+
* ```typescript
|
|
3581
|
+
* const agent = new MNTAgentKit(privateKey, "mainnet");
|
|
3582
|
+
* await agent.initialize(); // Validates APP_ID
|
|
3583
|
+
* ```
|
|
3584
|
+
*/
|
|
3585
|
+
async initialize() {
|
|
3586
|
+
this.projectConfig = await initializePlatform();
|
|
3587
|
+
return this;
|
|
3588
|
+
}
|
|
3589
|
+
async sendTransaction(to, amount) {
|
|
3590
|
+
return await sendTransaction(this, to, amount);
|
|
3591
|
+
}
|
|
3592
|
+
// OKX DEX Aggregator
|
|
3593
|
+
async getSwapQuote(fromTokenAddress, toTokenAddress, amount, slippagePercentage = "0.5") {
|
|
3594
|
+
return await getSwapQuote(
|
|
3595
|
+
this,
|
|
3596
|
+
fromTokenAddress,
|
|
3597
|
+
toTokenAddress,
|
|
3598
|
+
amount,
|
|
3599
|
+
slippagePercentage
|
|
3600
|
+
);
|
|
3601
|
+
}
|
|
3602
|
+
async executeSwap(fromTokenAddress, toTokenAddress, amount, slippagePercentage = "0.5") {
|
|
3603
|
+
return await executeSwap(
|
|
3604
|
+
this,
|
|
3605
|
+
fromTokenAddress,
|
|
3606
|
+
toTokenAddress,
|
|
3607
|
+
amount,
|
|
3608
|
+
slippagePercentage
|
|
3609
|
+
);
|
|
3610
|
+
}
|
|
3611
|
+
// OpenOcean DEX Aggregator
|
|
3612
|
+
async getOpenOceanQuote(fromToken, toToken, amount) {
|
|
3613
|
+
return await getOpenOceanQuote(this, fromToken, toToken, amount);
|
|
3614
|
+
}
|
|
3615
|
+
async swapOnOpenOcean(fromToken, toToken, amount, slippage = 0.5) {
|
|
3616
|
+
return await swapOnOpenOcean(
|
|
3617
|
+
this,
|
|
3618
|
+
fromToken,
|
|
3619
|
+
toToken,
|
|
3620
|
+
amount,
|
|
3621
|
+
slippage.toString()
|
|
3622
|
+
);
|
|
3623
|
+
}
|
|
3624
|
+
// 1inch DEX Aggregator
|
|
3625
|
+
async get1inchQuote(fromToken, toToken, amount) {
|
|
3626
|
+
return await get1inchQuote(this, fromToken, toToken, amount);
|
|
3627
|
+
}
|
|
3628
|
+
async swapOn1inch(fromToken, toToken, amount, slippage = 0.5) {
|
|
3629
|
+
return await swapOn1inch(
|
|
3630
|
+
this,
|
|
3631
|
+
fromToken,
|
|
3632
|
+
toToken,
|
|
3633
|
+
amount,
|
|
3634
|
+
slippage.toString()
|
|
3635
|
+
);
|
|
3636
|
+
}
|
|
3637
|
+
// Uniswap V3 DEX
|
|
3638
|
+
async getUniswapQuote(fromToken, toToken, amount) {
|
|
3639
|
+
return await getUniswapQuote(this, fromToken, toToken, amount);
|
|
3640
|
+
}
|
|
3641
|
+
async swapOnUniswap(fromToken, toToken, amount, slippage = 0.5) {
|
|
3642
|
+
return await swapOnUniswap(
|
|
3643
|
+
this,
|
|
3644
|
+
fromToken,
|
|
3645
|
+
toToken,
|
|
3646
|
+
amount,
|
|
1521
3647
|
slippage.toString()
|
|
1522
3648
|
);
|
|
1523
3649
|
}
|
|
@@ -1540,6 +3666,24 @@ var MNTAgentKit = class {
|
|
|
1540
3666
|
async lendleRepay(tokenAddress, amount, rateMode = 2, onBehalfOf) {
|
|
1541
3667
|
return await lendleRepay(this, tokenAddress, amount, rateMode, onBehalfOf);
|
|
1542
3668
|
}
|
|
3669
|
+
/**
|
|
3670
|
+
* Get user account data from Lendle LendingPool
|
|
3671
|
+
* Returns overall position including total collateral, debt, and health factor
|
|
3672
|
+
* @param userAddress - User wallet address (optional, defaults to agent account)
|
|
3673
|
+
* @returns User account data with collateral, debt, available borrows, and health factor
|
|
3674
|
+
*/
|
|
3675
|
+
async lendleGetUserAccountData(userAddress) {
|
|
3676
|
+
return await getUserAccountData(this, userAddress);
|
|
3677
|
+
}
|
|
3678
|
+
/**
|
|
3679
|
+
* Get all Lendle positions for a user (per-token breakdown)
|
|
3680
|
+
* Returns detailed supply and borrow amounts for each asset
|
|
3681
|
+
* @param userAddress - User wallet address (optional, defaults to agent account)
|
|
3682
|
+
* @returns Array of positions with supply/borrow amounts per asset
|
|
3683
|
+
*/
|
|
3684
|
+
async lendleGetPositions(userAddress) {
|
|
3685
|
+
return await lendleGetPositions(this, userAddress);
|
|
3686
|
+
}
|
|
1543
3687
|
// Agni Finance DEX (#1 on Mantle)
|
|
1544
3688
|
async agniSwap(tokenIn, tokenOut, amountIn, slippagePercent = 0.5, feeTier) {
|
|
1545
3689
|
return await agniSwap(
|
|
@@ -1568,6 +3712,33 @@ var MNTAgentKit = class {
|
|
|
1568
3712
|
}
|
|
1569
3713
|
return METH_TOKEN[this.chain];
|
|
1570
3714
|
}
|
|
3715
|
+
/**
|
|
3716
|
+
* Get mETH staking position for a user
|
|
3717
|
+
* Returns mETH balance and WETH balance for comparison
|
|
3718
|
+
* @param userAddress - User wallet address (optional, defaults to agent account)
|
|
3719
|
+
* @returns mETH position with balances
|
|
3720
|
+
*/
|
|
3721
|
+
async methGetPosition(userAddress) {
|
|
3722
|
+
return await methGetPosition(this, userAddress);
|
|
3723
|
+
}
|
|
3724
|
+
/**
|
|
3725
|
+
* Swap WETH to mETH using DEX aggregator
|
|
3726
|
+
* @param amount - Amount of WETH to swap (in wei as string)
|
|
3727
|
+
* @param slippage - Slippage tolerance percentage (default 0.5%)
|
|
3728
|
+
* @returns Transaction hash
|
|
3729
|
+
*/
|
|
3730
|
+
async swapToMeth(amount, slippage = 0.5) {
|
|
3731
|
+
return await swapToMeth(this, amount, slippage);
|
|
3732
|
+
}
|
|
3733
|
+
/**
|
|
3734
|
+
* Swap mETH to WETH using DEX aggregator
|
|
3735
|
+
* @param amount - Amount of mETH to swap (in wei as string)
|
|
3736
|
+
* @param slippage - Slippage tolerance percentage (default 0.5%)
|
|
3737
|
+
* @returns Transaction hash
|
|
3738
|
+
*/
|
|
3739
|
+
async swapFromMeth(amount, slippage = 0.5) {
|
|
3740
|
+
return await swapFromMeth(this, amount, slippage);
|
|
3741
|
+
}
|
|
1571
3742
|
// Squid Router Cross-chain
|
|
1572
3743
|
async getSquidRoute(fromToken, toToken, fromChain, toChain, amount, slippage = 1) {
|
|
1573
3744
|
return await getSquidRoute(
|
|
@@ -1591,8 +3762,269 @@ var MNTAgentKit = class {
|
|
|
1591
3762
|
slippage
|
|
1592
3763
|
);
|
|
1593
3764
|
}
|
|
3765
|
+
// PikePerps - Perpetual Trading
|
|
3766
|
+
/**
|
|
3767
|
+
* Open a long position on PikePerps
|
|
3768
|
+
* @param tokenAddress - Token to trade (meme token address)
|
|
3769
|
+
* @param margin - Margin amount in wei (as string)
|
|
3770
|
+
* @param leverage - Leverage multiplier (1-100, default 10)
|
|
3771
|
+
* @returns Position ID and transaction hash
|
|
3772
|
+
*/
|
|
3773
|
+
async pikeperpsOpenLong(tokenAddress, margin, leverage = 10) {
|
|
3774
|
+
return await pikeperpsOpenLong(this, tokenAddress, margin, leverage);
|
|
3775
|
+
}
|
|
3776
|
+
/**
|
|
3777
|
+
* Open a short position on PikePerps
|
|
3778
|
+
* @param tokenAddress - Token to trade (meme token address)
|
|
3779
|
+
* @param margin - Margin amount in wei (as string)
|
|
3780
|
+
* @param leverage - Leverage multiplier (1-100, default 10)
|
|
3781
|
+
* @returns Position ID and transaction hash
|
|
3782
|
+
*/
|
|
3783
|
+
async pikeperpsOpenShort(tokenAddress, margin, leverage = 10) {
|
|
3784
|
+
return await pikeperpsOpenShort(this, tokenAddress, margin, leverage);
|
|
3785
|
+
}
|
|
3786
|
+
/**
|
|
3787
|
+
* Close an existing position on PikePerps
|
|
3788
|
+
* @param positionId - Position ID to close
|
|
3789
|
+
* @returns Transaction hash
|
|
3790
|
+
*/
|
|
3791
|
+
async pikeperpsClosePosition(positionId) {
|
|
3792
|
+
return await pikeperpsClosePosition(this, positionId);
|
|
3793
|
+
}
|
|
3794
|
+
/**
|
|
3795
|
+
* Get all positions for a user on PikePerps
|
|
3796
|
+
* Returns detailed position data including PnL and liquidation prices
|
|
3797
|
+
* @param userAddress - User wallet address (optional, defaults to agent account)
|
|
3798
|
+
* @returns Array of positions with PnL and liquidation data
|
|
3799
|
+
*/
|
|
3800
|
+
async pikeperpsGetPositions(userAddress) {
|
|
3801
|
+
return await pikeperpsGetPositions(this, userAddress);
|
|
3802
|
+
}
|
|
3803
|
+
/**
|
|
3804
|
+
* Get market data for a token on PikePerps
|
|
3805
|
+
* Returns current price and recent trades
|
|
3806
|
+
* @param tokenAddress - Token address to get market data for
|
|
3807
|
+
* @param limit - Maximum number of recent trades to return (default 20)
|
|
3808
|
+
* @returns Market data with price and recent trades
|
|
3809
|
+
*/
|
|
3810
|
+
async pikeperpsGetMarketData(tokenAddress, limit = 20) {
|
|
3811
|
+
return await pikeperpsGetMarketData(this, tokenAddress, limit);
|
|
3812
|
+
}
|
|
3813
|
+
// ===== Pyth Network Price Feeds =====
|
|
3814
|
+
/**
|
|
3815
|
+
* Get real-time price from Pyth Network
|
|
3816
|
+
* @param priceFeedIdOrPair - Price feed ID or pair name (e.g., "ETH/USD", "BTC/USD", "MNT/USD")
|
|
3817
|
+
* @returns Price data with formatted price
|
|
3818
|
+
*/
|
|
3819
|
+
async pythGetPrice(priceFeedIdOrPair) {
|
|
3820
|
+
return await pythGetPrice(this, priceFeedIdOrPair);
|
|
3821
|
+
}
|
|
3822
|
+
/**
|
|
3823
|
+
* Get EMA (Exponential Moving Average) price from Pyth
|
|
3824
|
+
* @param priceFeedIdOrPair - Price feed ID or pair name
|
|
3825
|
+
* @returns EMA price data
|
|
3826
|
+
*/
|
|
3827
|
+
async pythGetEmaPrice(priceFeedIdOrPair) {
|
|
3828
|
+
return await pythGetEmaPrice(this, priceFeedIdOrPair);
|
|
3829
|
+
}
|
|
3830
|
+
/**
|
|
3831
|
+
* Get multiple prices from Pyth in a single call
|
|
3832
|
+
* @param pairs - Array of pair names or price feed IDs
|
|
3833
|
+
* @returns Array of price responses
|
|
3834
|
+
*/
|
|
3835
|
+
async pythGetMultiplePrices(pairs) {
|
|
3836
|
+
return await pythGetMultiplePrices(this, pairs);
|
|
3837
|
+
}
|
|
3838
|
+
/**
|
|
3839
|
+
* Get all supported Pyth price feed IDs
|
|
3840
|
+
* @returns Object mapping pair names to price feed IDs
|
|
3841
|
+
*/
|
|
3842
|
+
pythGetSupportedPriceFeeds() {
|
|
3843
|
+
return pythGetSupportedPriceFeeds();
|
|
3844
|
+
}
|
|
3845
|
+
/**
|
|
3846
|
+
* Check if a price feed exists on Pyth
|
|
3847
|
+
* @param priceFeedIdOrPair - Price feed ID or pair name
|
|
3848
|
+
* @returns Boolean indicating if feed exists
|
|
3849
|
+
*/
|
|
3850
|
+
async pythPriceFeedExists(priceFeedIdOrPair) {
|
|
3851
|
+
return await pythPriceFeedExists(this, priceFeedIdOrPair);
|
|
3852
|
+
}
|
|
3853
|
+
// ===== Token Launchpad =====
|
|
3854
|
+
/**
|
|
3855
|
+
* Deploy a new token (ERC20 or RWA) - supply minted to your address
|
|
3856
|
+
* @param name - Token name
|
|
3857
|
+
* @param symbol - Token symbol
|
|
3858
|
+
* @param supply - Total supply (human readable, e.g., "1000000")
|
|
3859
|
+
* @param tokenType - "standard" or "rwa"
|
|
3860
|
+
* @param assetType - For RWA: asset category
|
|
3861
|
+
* @param assetId - For RWA: external asset ID
|
|
3862
|
+
*/
|
|
3863
|
+
async deployToken(name, symbol, supply, tokenType = "standard", assetType, assetId) {
|
|
3864
|
+
return await deployToken(this, name, symbol, supply, tokenType, assetType, assetId);
|
|
3865
|
+
}
|
|
3866
|
+
/**
|
|
3867
|
+
* Deploy a standard ERC20 token
|
|
3868
|
+
* @param name - Token name
|
|
3869
|
+
* @param symbol - Token symbol
|
|
3870
|
+
* @param supply - Total supply (e.g., "1000000" for 1M tokens)
|
|
3871
|
+
*/
|
|
3872
|
+
async deployStandardToken(name, symbol, supply) {
|
|
3873
|
+
return await deployStandardToken(this, name, symbol, supply);
|
|
3874
|
+
}
|
|
3875
|
+
/**
|
|
3876
|
+
* Deploy an RWA (Real World Asset) token
|
|
3877
|
+
* @param name - Token name (e.g., "Manhattan Property Token")
|
|
3878
|
+
* @param symbol - Token symbol (e.g., "MPT")
|
|
3879
|
+
* @param supply - Total supply for fractional ownership
|
|
3880
|
+
* @param assetType - Asset category: "Real Estate", "Commodities", "Securities", "Art"
|
|
3881
|
+
* @param assetId - External reference ID for the underlying asset
|
|
3882
|
+
*/
|
|
3883
|
+
async deployRWAToken(name, symbol, supply, assetType, assetId) {
|
|
3884
|
+
return await deployRWAToken(this, name, symbol, supply, assetType, assetId);
|
|
3885
|
+
}
|
|
3886
|
+
/**
|
|
3887
|
+
* Get token information
|
|
3888
|
+
*/
|
|
3889
|
+
async getTokenInfo(tokenAddress, holder) {
|
|
3890
|
+
return await getTokenInfo(this, tokenAddress, holder);
|
|
3891
|
+
}
|
|
3892
|
+
/**
|
|
3893
|
+
* Get token balance
|
|
3894
|
+
*/
|
|
3895
|
+
async getTokenBalance(tokenAddress, holder) {
|
|
3896
|
+
return await getTokenBalance(this, tokenAddress, holder);
|
|
3897
|
+
}
|
|
3898
|
+
/**
|
|
3899
|
+
* Transfer tokens
|
|
3900
|
+
*/
|
|
3901
|
+
async transferToken(tokenAddress, to, amount) {
|
|
3902
|
+
return await transferToken(this, tokenAddress, to, amount);
|
|
3903
|
+
}
|
|
3904
|
+
// ===== NFT Launchpad =====
|
|
3905
|
+
/**
|
|
3906
|
+
* Deploy a new ERC721 NFT collection on Mantle Network
|
|
3907
|
+
* @param config - Collection configuration (name, symbol, baseURI, maxSupply)
|
|
3908
|
+
* @returns Collection deployment result with contract address
|
|
3909
|
+
*/
|
|
3910
|
+
async deployNFTCollection(config) {
|
|
3911
|
+
return await deployNFTCollection(this, config);
|
|
3912
|
+
}
|
|
3913
|
+
/**
|
|
3914
|
+
* Deploy an NFT collection with preset configurations
|
|
3915
|
+
* @param preset - Preset type: "pfp" (10000), "art" (1000), "membership" (100), "unlimited"
|
|
3916
|
+
* @param name - Collection name
|
|
3917
|
+
* @param symbol - Collection symbol
|
|
3918
|
+
* @param baseURI - Base URI for metadata
|
|
3919
|
+
* @returns Collection deployment result
|
|
3920
|
+
*/
|
|
3921
|
+
async deployNFTCollectionWithPreset(preset, name, symbol, baseURI) {
|
|
3922
|
+
return await deployNFTCollectionWithPreset(
|
|
3923
|
+
this,
|
|
3924
|
+
preset,
|
|
3925
|
+
name,
|
|
3926
|
+
symbol,
|
|
3927
|
+
baseURI
|
|
3928
|
+
);
|
|
3929
|
+
}
|
|
3930
|
+
/**
|
|
3931
|
+
* Mint a single NFT from a collection
|
|
3932
|
+
* @param collectionAddress - NFT collection contract address
|
|
3933
|
+
* @param to - Recipient address (defaults to agent address)
|
|
3934
|
+
* @returns Mint result with token ID
|
|
3935
|
+
*/
|
|
3936
|
+
async mintNFT(collectionAddress, to) {
|
|
3937
|
+
return await mintNFT(this, collectionAddress, to);
|
|
3938
|
+
}
|
|
3939
|
+
/**
|
|
3940
|
+
* Batch mint multiple NFTs from a collection
|
|
3941
|
+
* @param collectionAddress - NFT collection contract address
|
|
3942
|
+
* @param to - Recipient address
|
|
3943
|
+
* @param quantity - Number of NFTs to mint
|
|
3944
|
+
* @returns Mint result with starting token ID
|
|
3945
|
+
*/
|
|
3946
|
+
async batchMintNFT(collectionAddress, to, quantity) {
|
|
3947
|
+
return await batchMintNFT(this, collectionAddress, to, quantity);
|
|
3948
|
+
}
|
|
3949
|
+
/**
|
|
3950
|
+
* Get information about an NFT collection
|
|
3951
|
+
* @param collectionAddress - NFT collection contract address
|
|
3952
|
+
* @param holderAddress - Optional address to get balance for
|
|
3953
|
+
* @returns Collection information
|
|
3954
|
+
*/
|
|
3955
|
+
async getNFTCollectionInfo(collectionAddress, holderAddress) {
|
|
3956
|
+
return await getNFTCollectionInfo(this, collectionAddress, holderAddress);
|
|
3957
|
+
}
|
|
3958
|
+
/**
|
|
3959
|
+
* Get information about a specific NFT token
|
|
3960
|
+
* @param collectionAddress - NFT collection contract address
|
|
3961
|
+
* @param tokenId - Token ID
|
|
3962
|
+
* @returns Token information
|
|
3963
|
+
*/
|
|
3964
|
+
async getNFTTokenInfo(collectionAddress, tokenId) {
|
|
3965
|
+
return await getNFTTokenInfo(this, collectionAddress, tokenId);
|
|
3966
|
+
}
|
|
3967
|
+
/**
|
|
3968
|
+
* Get NFT balance for an address
|
|
3969
|
+
* @param collectionAddress - NFT collection contract address
|
|
3970
|
+
* @param holderAddress - Address to check (defaults to agent address)
|
|
3971
|
+
* @returns Balance as string
|
|
3972
|
+
*/
|
|
3973
|
+
async getNFTBalance(collectionAddress, holderAddress) {
|
|
3974
|
+
return await getNFTBalance(this, collectionAddress, holderAddress);
|
|
3975
|
+
}
|
|
3976
|
+
/**
|
|
3977
|
+
* Check if an address owns a specific NFT
|
|
3978
|
+
* @param collectionAddress - NFT collection contract address
|
|
3979
|
+
* @param tokenId - Token ID to check
|
|
3980
|
+
* @param ownerAddress - Address to verify ownership
|
|
3981
|
+
* @returns Boolean indicating ownership
|
|
3982
|
+
*/
|
|
3983
|
+
async isNFTOwner(collectionAddress, tokenId, ownerAddress) {
|
|
3984
|
+
return await isNFTOwner(this, collectionAddress, tokenId, ownerAddress);
|
|
3985
|
+
}
|
|
3986
|
+
/**
|
|
3987
|
+
* Transfer an NFT to another address
|
|
3988
|
+
* @param collectionAddress - NFT collection contract address
|
|
3989
|
+
* @param to - Recipient address
|
|
3990
|
+
* @param tokenId - Token ID to transfer
|
|
3991
|
+
* @returns Transaction hash
|
|
3992
|
+
*/
|
|
3993
|
+
async transferNFT(collectionAddress, to, tokenId) {
|
|
3994
|
+
return await transferNFT(this, collectionAddress, to, tokenId);
|
|
3995
|
+
}
|
|
3996
|
+
/**
|
|
3997
|
+
* Safe transfer an NFT (checks if recipient can receive)
|
|
3998
|
+
* @param collectionAddress - NFT collection contract address
|
|
3999
|
+
* @param to - Recipient address
|
|
4000
|
+
* @param tokenId - Token ID to transfer
|
|
4001
|
+
* @returns Transaction hash
|
|
4002
|
+
*/
|
|
4003
|
+
async safeTransferNFT(collectionAddress, to, tokenId) {
|
|
4004
|
+
return await safeTransferNFT(this, collectionAddress, to, tokenId);
|
|
4005
|
+
}
|
|
4006
|
+
/**
|
|
4007
|
+
* Approve an address to transfer a specific NFT
|
|
4008
|
+
* @param collectionAddress - NFT collection contract address
|
|
4009
|
+
* @param approved - Address to approve
|
|
4010
|
+
* @param tokenId - Token ID to approve
|
|
4011
|
+
* @returns Transaction hash
|
|
4012
|
+
*/
|
|
4013
|
+
async approveNFT(collectionAddress, approved, tokenId) {
|
|
4014
|
+
return await approveNFT(this, collectionAddress, approved, tokenId);
|
|
4015
|
+
}
|
|
4016
|
+
/**
|
|
4017
|
+
* Set approval for all NFTs in a collection
|
|
4018
|
+
* @param collectionAddress - NFT collection contract address
|
|
4019
|
+
* @param operator - Operator address
|
|
4020
|
+
* @param approved - Whether to approve or revoke
|
|
4021
|
+
* @returns Transaction hash
|
|
4022
|
+
*/
|
|
4023
|
+
async setApprovalForAllNFT(collectionAddress, operator, approved) {
|
|
4024
|
+
return await setApprovalForAllNFT(this, collectionAddress, operator, approved);
|
|
4025
|
+
}
|
|
1594
4026
|
};
|
|
1595
4027
|
|
|
1596
|
-
export { agni_exports as AgniConstants, lendle_exports as LendleConstants, METH_TOKEN, MNTAgentKit, merchantmoe_exports as MerchantMoeConstants, meth_exports as MethConstants, okx_exports as OKXConstants, oneinch_exports as OneInchConstants, openocean_exports as OpenOceanConstants, squid_exports as SquidConstants, uniswap_exports as UniswapConstants, agniSwap, approveToken, crossChainSwapViaSquid, executeSwap, get1inchQuote, getOpenOceanQuote, getProjectConfig, getSquidRoute, getUniswapQuote, initializePlatform, lendleBorrow, lendleRepay, lendleSupply, lendleWithdraw, merchantMoeSwap, sendTransaction, swapOn1inch, swapOnOpenOcean, swapOnUniswap };
|
|
4028
|
+
export { agni_exports as AgniConstants, lendle_exports as LendleConstants, METH_TOKEN, MNTAgentKit, merchantmoe_exports as MerchantMoeConstants, meth_exports as MethConstants, nft_launchpad_exports as NFTLaunchpadConstants, okx_exports as OKXConstants, oneinch_exports as OneInchConstants, openocean_exports as OpenOceanConstants, pikeperps_exports as PikePerpsConstants, pyth_exports as PythConstants, squid_exports as SquidConstants, token_launchpad_exports as TokenLaunchpadConstants, uniswap_exports as UniswapConstants, agniSwap, approveNFT, approveToken, batchMintNFT, crossChainSwapViaSquid, deployNFTCollection, deployNFTCollectionWithPreset, deployRWAToken, deployStandardToken, deployToken, executeSwap, get1inchQuote, getNFTBalance, getNFTCollectionInfo, getNFTTokenInfo, getOpenOceanQuote, getProjectConfig, getSquidRoute, getTokenBalance, getTokenInfo, getUniswapQuote, initializePlatform, isNFTOwner, lendleBorrow, lendleGetPositions, lendleRepay, lendleSupply, lendleWithdraw, merchantMoeSwap, methGetPosition, mintNFT, pikeperpsClosePosition, pikeperpsGetMarketData, pikeperpsGetPositions, pikeperpsOpenLong, pikeperpsOpenShort, pythGetEmaPrice, pythGetMultiplePrices, pythGetPrice, pythGetSupportedPriceFeeds, pythPriceFeedExists, safeTransferNFT, sendTransaction, setApprovalForAllNFT, swapFromMeth, swapOn1inch, swapOnOpenOcean, swapOnUniswap, swapToMeth, transferNFT, transferToken };
|
|
1597
4029
|
//# sourceMappingURL=index.js.map
|
|
1598
4030
|
//# sourceMappingURL=index.js.map
|