@agether/agether 2.11.0 → 2.12.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/package.json +2 -2
- package/src/index.ts +170 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agether/agether",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.0",
|
|
4
4
|
"description": "OpenClaw plugin for Agether — onchain credit for AI agents on Ethereum & Base",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"openclaw": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
]
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@agether/sdk": "^2.
|
|
12
|
+
"@agether/sdk": "^2.14.0",
|
|
13
13
|
"axios": "^1.6.0",
|
|
14
14
|
"ethers": "^6.9.0"
|
|
15
15
|
},
|
package/src/index.ts
CHANGED
|
@@ -958,6 +958,176 @@ export default function register(api: any) {
|
|
|
958
958
|
},
|
|
959
959
|
});
|
|
960
960
|
|
|
961
|
+
// ═══════════════════════════════════════════════════════
|
|
962
|
+
// TOOL: morpho_search (Morpho GraphQL search — find any token)
|
|
963
|
+
// ═══════════════════════════════════════════════════════
|
|
964
|
+
api.registerTool({
|
|
965
|
+
name: "morpho_search",
|
|
966
|
+
description:
|
|
967
|
+
"Search Morpho markets by token name. Use this when the user asks about a specific token " +
|
|
968
|
+
"(e.g. 'ezETH', 'wstETH', 'rETH', 'cbBTC') to find all markets where it appears. " +
|
|
969
|
+
"No hardcoded list — searches Morpho's full market registry.",
|
|
970
|
+
parameters: {
|
|
971
|
+
type: "object",
|
|
972
|
+
properties: {
|
|
973
|
+
token: { type: "string", description: "Token name or symbol to search for (e.g. 'WETH', 'ezETH', 'wstETH')" },
|
|
974
|
+
asCollateral: { type: "boolean", description: "Only show markets where token is used as collateral (default: false)" },
|
|
975
|
+
asLoanToken: { type: "boolean", description: "Only show markets where token is the loan asset (default: false)" },
|
|
976
|
+
},
|
|
977
|
+
required: ["token"],
|
|
978
|
+
},
|
|
979
|
+
async execute(_id: string, params: { token: string; asCollateral?: boolean; asLoanToken?: boolean }) {
|
|
980
|
+
try {
|
|
981
|
+
const cfg = getConfig(api);
|
|
982
|
+
const client = createMorphoClient(cfg);
|
|
983
|
+
const results = await client.searchMarkets(params.token, {
|
|
984
|
+
asCollateral: params.asCollateral,
|
|
985
|
+
asLoanToken: params.asLoanToken,
|
|
986
|
+
});
|
|
987
|
+
|
|
988
|
+
if (results.length === 0) return ok(`No markets found for "${params.token}" on this chain.`);
|
|
989
|
+
|
|
990
|
+
const formatted = results.map((r: any) => ({
|
|
991
|
+
collateral: r.collateralToken,
|
|
992
|
+
loan: r.loanToken,
|
|
993
|
+
lltv: r.lltv,
|
|
994
|
+
supplyApy: `${(r.supplyApy * 100).toFixed(2)}%`,
|
|
995
|
+
borrowApy: `${(r.borrowApy * 100).toFixed(2)}%`,
|
|
996
|
+
utilization: `${(r.utilization * 100).toFixed(1)}%`,
|
|
997
|
+
totalSupply: `$${r.totalSupplyUsd.toFixed(0)}`,
|
|
998
|
+
totalBorrow: `$${r.totalBorrowUsd.toFixed(0)}`,
|
|
999
|
+
}));
|
|
1000
|
+
|
|
1001
|
+
return ok(JSON.stringify(formatted, null, 2));
|
|
1002
|
+
} catch (e) { return fail(e); }
|
|
1003
|
+
},
|
|
1004
|
+
});
|
|
1005
|
+
|
|
1006
|
+
// ═══════════════════════════════════════════════════════
|
|
1007
|
+
// TOOL: morpho_borrowing_options (wallet scan → matching markets)
|
|
1008
|
+
// ═══════════════════════════════════════════════════════
|
|
1009
|
+
api.registerTool({
|
|
1010
|
+
name: "morpho_borrowing_options",
|
|
1011
|
+
description:
|
|
1012
|
+
"Find what the agent can borrow. " +
|
|
1013
|
+
"Without arguments: scans wallet for all tokens with balance > 0, then finds Morpho markets " +
|
|
1014
|
+
"where each token can be used as collateral. " +
|
|
1015
|
+
"With 'collateral' argument: finds all markets for that specific collateral token. " +
|
|
1016
|
+
"Use this when user asks 'what can I borrow?', 'where can I put X as collateral?', " +
|
|
1017
|
+
"'what can I borrow with my WETH?'",
|
|
1018
|
+
parameters: {
|
|
1019
|
+
type: "object",
|
|
1020
|
+
properties: {
|
|
1021
|
+
collateral: {
|
|
1022
|
+
type: "string",
|
|
1023
|
+
description: "Specific collateral token to check (e.g. 'WETH', 'ezETH'). If omitted, scans wallet for all tokens.",
|
|
1024
|
+
},
|
|
1025
|
+
},
|
|
1026
|
+
required: [],
|
|
1027
|
+
},
|
|
1028
|
+
async execute(_id: string, params: { collateral?: string }) {
|
|
1029
|
+
try {
|
|
1030
|
+
const cfg = getConfig(api);
|
|
1031
|
+
const client = createMorphoClient(cfg);
|
|
1032
|
+
const options = await client.findBorrowingOptions(params.collateral);
|
|
1033
|
+
|
|
1034
|
+
if (options.length === 0) {
|
|
1035
|
+
if (params.collateral) {
|
|
1036
|
+
return ok(`No borrowing markets found for ${params.collateral} as collateral on this chain.`);
|
|
1037
|
+
}
|
|
1038
|
+
return ok("No tokens with balance > 0 found in the agent wallet, or no matching Morpho markets exist.");
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
// Format for LLM readability
|
|
1042
|
+
const formatted = options.map(opt => ({
|
|
1043
|
+
collateralToken: opt.collateralToken,
|
|
1044
|
+
walletBalance: opt.collateralBalance,
|
|
1045
|
+
availableMarkets: opt.markets.map(m => ({
|
|
1046
|
+
borrow: m.loanToken,
|
|
1047
|
+
borrowApy: m.borrowApy,
|
|
1048
|
+
lltv: m.lltv,
|
|
1049
|
+
utilization: m.utilization,
|
|
1050
|
+
availableLiquidity: m.availableLiquidity,
|
|
1051
|
+
})),
|
|
1052
|
+
}));
|
|
1053
|
+
|
|
1054
|
+
return ok(JSON.stringify(formatted, null, 2));
|
|
1055
|
+
} catch (e) { return fail(e); }
|
|
1056
|
+
},
|
|
1057
|
+
});
|
|
1058
|
+
|
|
1059
|
+
// ═══════════════════════════════════════════════════════
|
|
1060
|
+
// TOOL: morpho_supply_options (find lending opportunities)
|
|
1061
|
+
// ═══════════════════════════════════════════════════════
|
|
1062
|
+
api.registerTool({
|
|
1063
|
+
name: "morpho_supply_options",
|
|
1064
|
+
description:
|
|
1065
|
+
"Find supply/lending opportunities for a specific loan token. " +
|
|
1066
|
+
"Use when user asks 'what can I supply to earn WETH?', 'where can I lend USDC?', " +
|
|
1067
|
+
"'what supply APY is available for USDC?'. " +
|
|
1068
|
+
"Shows all markets where the specified token is the loan asset (user supplies it to earn yield).",
|
|
1069
|
+
parameters: {
|
|
1070
|
+
type: "object",
|
|
1071
|
+
properties: {
|
|
1072
|
+
loanToken: { type: "string", description: "The token to supply/lend (e.g. 'USDC', 'WETH')" },
|
|
1073
|
+
},
|
|
1074
|
+
required: ["loanToken"],
|
|
1075
|
+
},
|
|
1076
|
+
async execute(_id: string, params: { loanToken: string }) {
|
|
1077
|
+
try {
|
|
1078
|
+
const cfg = getConfig(api);
|
|
1079
|
+
const client = createMorphoClient(cfg);
|
|
1080
|
+
const options = await client.findSupplyOptions(params.loanToken);
|
|
1081
|
+
|
|
1082
|
+
if (options.length === 0) return ok(`No supply markets found for ${params.loanToken} on this chain.`);
|
|
1083
|
+
|
|
1084
|
+
const formatted = options.map((m: any) => ({
|
|
1085
|
+
collateral: m.collateralToken,
|
|
1086
|
+
loan: m.loanToken,
|
|
1087
|
+
supplyApy: m.supplyApy,
|
|
1088
|
+
lltv: m.lltv,
|
|
1089
|
+
utilization: m.utilization,
|
|
1090
|
+
totalSupply: m.totalSupply,
|
|
1091
|
+
}));
|
|
1092
|
+
|
|
1093
|
+
return ok(JSON.stringify(formatted, null, 2));
|
|
1094
|
+
} catch (e) { return fail(e); }
|
|
1095
|
+
},
|
|
1096
|
+
});
|
|
1097
|
+
|
|
1098
|
+
// ═══════════════════════════════════════════════════════
|
|
1099
|
+
// TOOL: morpho_wallet_tokens (scan wallet for all token balances)
|
|
1100
|
+
// ═══════════════════════════════════════════════════════
|
|
1101
|
+
api.registerTool({
|
|
1102
|
+
name: "morpho_wallet_tokens",
|
|
1103
|
+
description:
|
|
1104
|
+
"Scan the agent's wallet for all ERC-20 tokens that exist in Morpho markets. " +
|
|
1105
|
+
"Shows every token with balance > 0. Use this when user asks 'what tokens do I have?', " +
|
|
1106
|
+
"'what's in my wallet?', 'what can I use?'.",
|
|
1107
|
+
parameters: {
|
|
1108
|
+
type: "object",
|
|
1109
|
+
properties: {},
|
|
1110
|
+
required: [],
|
|
1111
|
+
},
|
|
1112
|
+
async execute(_id: string) {
|
|
1113
|
+
try {
|
|
1114
|
+
const cfg = getConfig(api);
|
|
1115
|
+
const client = createMorphoClient(cfg);
|
|
1116
|
+
const tokens = await client.getWalletTokenBalances();
|
|
1117
|
+
|
|
1118
|
+
if (tokens.length === 0) return ok("No tokens with balance > 0 found in the agent wallet.");
|
|
1119
|
+
|
|
1120
|
+
const formatted = tokens.map(t => ({
|
|
1121
|
+
token: t.symbol,
|
|
1122
|
+
balance: t.balanceFormatted,
|
|
1123
|
+
address: t.address,
|
|
1124
|
+
}));
|
|
1125
|
+
|
|
1126
|
+
return ok(JSON.stringify(formatted, null, 2));
|
|
1127
|
+
} catch (e) { return fail(e); }
|
|
1128
|
+
},
|
|
1129
|
+
});
|
|
1130
|
+
|
|
961
1131
|
// ═══════════════════════════════════════════════════════
|
|
962
1132
|
// TOOL: agether_score (backend API — x402 gated)
|
|
963
1133
|
// ═══════════════════════════════════════════════════════
|