@exagent/sdk 0.1.3 → 0.1.5
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/dist/index.d.mts +474 -607
- package/dist/index.d.ts +474 -607
- package/dist/index.js +692 -453
- package/dist/index.mjs +689 -458
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
-
}) : x)(function(x) {
|
|
4
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
-
});
|
|
7
|
-
|
|
8
1
|
// src/client.ts
|
|
9
2
|
import {
|
|
10
3
|
createPublicClient,
|
|
@@ -24,7 +17,10 @@ var EXAGENT_REGISTRY_ABI = [
|
|
|
24
17
|
name: "registerAgent",
|
|
25
18
|
inputs: [
|
|
26
19
|
{ name: "name", type: "string" },
|
|
27
|
-
{ name: "metadataURI", type: "string" }
|
|
20
|
+
{ name: "metadataURI", type: "string" },
|
|
21
|
+
{ name: "riskUniverse", type: "uint8" },
|
|
22
|
+
{ name: "maxPositionSizeBps", type: "uint256" },
|
|
23
|
+
{ name: "maxDailyLossBps", type: "uint256" }
|
|
28
24
|
],
|
|
29
25
|
outputs: [{ name: "agentId", type: "uint256" }],
|
|
30
26
|
stateMutability: "nonpayable"
|
|
@@ -254,6 +250,62 @@ var EXAGENT_REGISTRY_ABI = [
|
|
|
254
250
|
outputs: [{ name: "", type: "bytes32" }],
|
|
255
251
|
stateMutability: "view"
|
|
256
252
|
},
|
|
253
|
+
// Mainnet: Agent retirement
|
|
254
|
+
{
|
|
255
|
+
type: "function",
|
|
256
|
+
name: "retireAgent",
|
|
257
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
258
|
+
outputs: [],
|
|
259
|
+
stateMutability: "nonpayable"
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
type: "function",
|
|
263
|
+
name: "retired",
|
|
264
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
265
|
+
outputs: [{ type: "bool" }],
|
|
266
|
+
stateMutability: "view"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
type: "function",
|
|
270
|
+
name: "isRetired",
|
|
271
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
272
|
+
outputs: [{ type: "bool" }],
|
|
273
|
+
stateMutability: "view"
|
|
274
|
+
},
|
|
275
|
+
// Mainnet: Risk universe token whitelists
|
|
276
|
+
{
|
|
277
|
+
type: "function",
|
|
278
|
+
name: "isTradeAllowed",
|
|
279
|
+
inputs: [
|
|
280
|
+
{ name: "agentId", type: "uint256" },
|
|
281
|
+
{ name: "token", type: "address" },
|
|
282
|
+
{ name: "aggregator", type: "address" }
|
|
283
|
+
],
|
|
284
|
+
outputs: [{ type: "bool" }],
|
|
285
|
+
stateMutability: "view"
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
type: "function",
|
|
289
|
+
name: "getRiskUniverse",
|
|
290
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
291
|
+
outputs: [{ type: "uint8" }],
|
|
292
|
+
stateMutability: "view"
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
type: "function",
|
|
296
|
+
name: "tradeCount",
|
|
297
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
298
|
+
outputs: [{ type: "uint256" }],
|
|
299
|
+
stateMutability: "view"
|
|
300
|
+
},
|
|
301
|
+
// Events
|
|
302
|
+
{
|
|
303
|
+
type: "event",
|
|
304
|
+
name: "AgentRetired",
|
|
305
|
+
inputs: [
|
|
306
|
+
{ name: "agentId", type: "uint256", indexed: true }
|
|
307
|
+
]
|
|
308
|
+
},
|
|
257
309
|
{
|
|
258
310
|
type: "event",
|
|
259
311
|
name: "ConfigUpdated",
|
|
@@ -264,7 +316,16 @@ var EXAGENT_REGISTRY_ABI = [
|
|
|
264
316
|
{ name: "epochId", type: "uint256", indexed: false },
|
|
265
317
|
{ name: "blockNumber", type: "uint256", indexed: false }
|
|
266
318
|
]
|
|
267
|
-
}
|
|
319
|
+
},
|
|
320
|
+
// Custom errors
|
|
321
|
+
{ type: "error", name: "OwnerAlreadyHasAgent", inputs: [{ name: "existingAgentId", type: "uint256" }] },
|
|
322
|
+
{ type: "error", name: "InvalidMetadataURI", inputs: [] },
|
|
323
|
+
{ type: "error", name: "InvalidName", inputs: [] },
|
|
324
|
+
{ type: "error", name: "InvalidRiskUniverse", inputs: [] },
|
|
325
|
+
{ type: "error", name: "InvalidTradingConfig", inputs: [] },
|
|
326
|
+
{ type: "error", name: "NameAlreadyTaken", inputs: [] },
|
|
327
|
+
{ type: "error", name: "AgentNotOwner", inputs: [] },
|
|
328
|
+
{ type: "error", name: "AgentIsRetired", inputs: [] }
|
|
268
329
|
];
|
|
269
330
|
var ExagentRegistry = class {
|
|
270
331
|
address;
|
|
@@ -285,9 +346,12 @@ var ExagentRegistry = class {
|
|
|
285
346
|
* Register a new agent
|
|
286
347
|
* @param name Unique agent name (3-32 chars, alphanumeric + spaces/hyphens/underscores)
|
|
287
348
|
* @param metadataURI IPFS URI for agent metadata
|
|
349
|
+
* @param riskUniverse Risk tier: 0=Core, 1=Established, 2=Derivatives, 3=Emerging, 4=Frontier
|
|
350
|
+
* @param maxPositionSizeBps Maximum position size in basis points (1-10000)
|
|
351
|
+
* @param maxDailyLossBps Maximum daily loss in basis points (1-10000)
|
|
288
352
|
* @returns Transaction hash
|
|
289
353
|
*/
|
|
290
|
-
async register(name, metadataURI) {
|
|
354
|
+
async register(name, metadataURI, riskUniverse = 1, maxPositionSizeBps = 1000n, maxDailyLossBps = 500n) {
|
|
291
355
|
if (!this.walletClient || !this.account) throw new Error("Wallet client and account required for write operations");
|
|
292
356
|
const hash = await this.walletClient.writeContract({
|
|
293
357
|
account: this.account,
|
|
@@ -295,7 +359,7 @@ var ExagentRegistry = class {
|
|
|
295
359
|
address: this.address,
|
|
296
360
|
abi: EXAGENT_REGISTRY_ABI,
|
|
297
361
|
functionName: "registerAgent",
|
|
298
|
-
args: [name, metadataURI]
|
|
362
|
+
args: [name, metadataURI, riskUniverse, maxPositionSizeBps, maxDailyLossBps]
|
|
299
363
|
});
|
|
300
364
|
return hash;
|
|
301
365
|
}
|
|
@@ -630,8 +694,84 @@ var ExagentRegistry = class {
|
|
|
630
694
|
* @returns keccak256 hash of the config
|
|
631
695
|
*/
|
|
632
696
|
static calculateConfigHash(provider, model) {
|
|
633
|
-
|
|
634
|
-
|
|
697
|
+
return keccak256(encodePacked(["string", "string"], [provider, model]));
|
|
698
|
+
}
|
|
699
|
+
// ============ Agent Retirement ============
|
|
700
|
+
/**
|
|
701
|
+
* Retire an agent — marks it as retired, unlinks all wallets, allows new agent registration
|
|
702
|
+
* @param agentId The agent's ID
|
|
703
|
+
* @returns Transaction hash
|
|
704
|
+
*/
|
|
705
|
+
async retireAgent(agentId) {
|
|
706
|
+
if (!this.walletClient || !this.account) throw new Error("Wallet client and account required for write operations");
|
|
707
|
+
const hash = await this.walletClient.writeContract({
|
|
708
|
+
account: this.account,
|
|
709
|
+
chain: this.chain,
|
|
710
|
+
address: this.address,
|
|
711
|
+
abi: EXAGENT_REGISTRY_ABI,
|
|
712
|
+
functionName: "retireAgent",
|
|
713
|
+
args: [agentId]
|
|
714
|
+
});
|
|
715
|
+
return hash;
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Check if an agent is retired
|
|
719
|
+
* @param agentId The agent's ID
|
|
720
|
+
* @returns True if agent is retired
|
|
721
|
+
*/
|
|
722
|
+
async isRetired(agentId) {
|
|
723
|
+
const result = await this.publicClient.readContract({
|
|
724
|
+
address: this.address,
|
|
725
|
+
abi: EXAGENT_REGISTRY_ABI,
|
|
726
|
+
functionName: "isRetired",
|
|
727
|
+
args: [agentId]
|
|
728
|
+
});
|
|
729
|
+
return result;
|
|
730
|
+
}
|
|
731
|
+
// ============ Risk Universe Token Eligibility ============
|
|
732
|
+
/**
|
|
733
|
+
* Check if a token trade is allowed for an agent's risk universe
|
|
734
|
+
* @param agentId The agent's ID
|
|
735
|
+
* @param token The token address to check
|
|
736
|
+
* @param aggregator The aggregator being used (for trusted aggregator bypass)
|
|
737
|
+
* @returns True if the trade is allowed
|
|
738
|
+
*/
|
|
739
|
+
async isTradeAllowed(agentId, token, aggregator) {
|
|
740
|
+
const result = await this.publicClient.readContract({
|
|
741
|
+
address: this.address,
|
|
742
|
+
abi: EXAGENT_REGISTRY_ABI,
|
|
743
|
+
functionName: "isTradeAllowed",
|
|
744
|
+
args: [agentId, token, aggregator]
|
|
745
|
+
});
|
|
746
|
+
return result;
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Get the risk universe for an agent
|
|
750
|
+
* @param agentId The agent's ID
|
|
751
|
+
* @returns Risk universe (0=Core, 1=Established, 2=Derivatives, 3=Emerging, 4=Frontier)
|
|
752
|
+
*/
|
|
753
|
+
async getRiskUniverse(agentId) {
|
|
754
|
+
const result = await this.publicClient.readContract({
|
|
755
|
+
address: this.address,
|
|
756
|
+
abi: EXAGENT_REGISTRY_ABI,
|
|
757
|
+
functionName: "getRiskUniverse",
|
|
758
|
+
args: [agentId]
|
|
759
|
+
});
|
|
760
|
+
return Number(result);
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Get trade count for an agent
|
|
764
|
+
* @param agentId The agent's ID
|
|
765
|
+
* @returns Number of recorded trades
|
|
766
|
+
*/
|
|
767
|
+
async getTradeCount(agentId) {
|
|
768
|
+
const result = await this.publicClient.readContract({
|
|
769
|
+
address: this.address,
|
|
770
|
+
abi: EXAGENT_REGISTRY_ABI,
|
|
771
|
+
functionName: "tradeCount",
|
|
772
|
+
args: [agentId]
|
|
773
|
+
});
|
|
774
|
+
return result;
|
|
635
775
|
}
|
|
636
776
|
};
|
|
637
777
|
|
|
@@ -722,6 +862,9 @@ var ExagentVault = class {
|
|
|
722
862
|
this.address = vaultAddress;
|
|
723
863
|
this.publicClient = publicClient;
|
|
724
864
|
this.walletClient = walletClient;
|
|
865
|
+
if (!chain) {
|
|
866
|
+
throw new Error("Chain parameter is required");
|
|
867
|
+
}
|
|
725
868
|
this.chain = chain;
|
|
726
869
|
this.account = account;
|
|
727
870
|
}
|
|
@@ -1068,17 +1211,34 @@ var ExagentVault = class {
|
|
|
1068
1211
|
var EXAGENT_STAKING_ABI = [
|
|
1069
1212
|
// ============ State Variables ============
|
|
1070
1213
|
{ type: "function", name: "exaToken", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
1071
|
-
{ type: "function", name: "
|
|
1214
|
+
{ type: "function", name: "totalDeposited", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1215
|
+
{ type: "function", name: "totalLocked", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1072
1216
|
{ type: "function", name: "totalVeEXA", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1073
|
-
{ type: "function", name: "
|
|
1217
|
+
{ type: "function", name: "totalEffectiveVeEXA", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1074
1218
|
// ============ Constants ============
|
|
1075
1219
|
{ type: "function", name: "MIN_LOCK_DURATION", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1076
1220
|
{ type: "function", name: "MAX_LOCK_DURATION", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1221
|
+
{ type: "function", name: "VAULT_ACCESS_THRESHOLD", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1077
1222
|
{ type: "function", name: "PRECISION", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1078
|
-
// ============
|
|
1223
|
+
// ============ Phase 1: Deposit / Withdraw ============
|
|
1224
|
+
{
|
|
1225
|
+
type: "function",
|
|
1226
|
+
name: "deposit",
|
|
1227
|
+
inputs: [{ name: "amount", type: "uint256" }],
|
|
1228
|
+
outputs: [],
|
|
1229
|
+
stateMutability: "nonpayable"
|
|
1230
|
+
},
|
|
1231
|
+
{
|
|
1232
|
+
type: "function",
|
|
1233
|
+
name: "withdraw",
|
|
1234
|
+
inputs: [{ name: "amount", type: "uint256" }],
|
|
1235
|
+
outputs: [],
|
|
1236
|
+
stateMutability: "nonpayable"
|
|
1237
|
+
},
|
|
1238
|
+
// ============ Phase 2: Lock / Unlock ============
|
|
1079
1239
|
{
|
|
1080
1240
|
type: "function",
|
|
1081
|
-
name: "
|
|
1241
|
+
name: "lock",
|
|
1082
1242
|
inputs: [
|
|
1083
1243
|
{ name: "amount", type: "uint256" },
|
|
1084
1244
|
{ name: "lockDuration", type: "uint256" }
|
|
@@ -1086,7 +1246,6 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1086
1246
|
outputs: [],
|
|
1087
1247
|
stateMutability: "nonpayable"
|
|
1088
1248
|
},
|
|
1089
|
-
{ type: "function", name: "unstake", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1090
1249
|
{
|
|
1091
1250
|
type: "function",
|
|
1092
1251
|
name: "extendLock",
|
|
@@ -1094,6 +1253,8 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1094
1253
|
outputs: [],
|
|
1095
1254
|
stateMutability: "nonpayable"
|
|
1096
1255
|
},
|
|
1256
|
+
{ type: "function", name: "unlock", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1257
|
+
{ type: "function", name: "emergencyWithdraw", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1097
1258
|
// ============ Reward Functions ============
|
|
1098
1259
|
{ type: "function", name: "claimRewards", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1099
1260
|
{ type: "function", name: "claimRewardsMulti", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
@@ -1104,26 +1265,17 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1104
1265
|
outputs: [],
|
|
1105
1266
|
stateMutability: "nonpayable"
|
|
1106
1267
|
},
|
|
1107
|
-
// ============
|
|
1108
|
-
{
|
|
1109
|
-
type: "function",
|
|
1110
|
-
name: "delegate",
|
|
1111
|
-
inputs: [{ name: "agentId", type: "uint256" }],
|
|
1112
|
-
outputs: [],
|
|
1113
|
-
stateMutability: "nonpayable"
|
|
1114
|
-
},
|
|
1115
|
-
{ type: "function", name: "undelegate", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1268
|
+
// ============ View Functions ============
|
|
1116
1269
|
{
|
|
1117
1270
|
type: "function",
|
|
1118
|
-
name: "
|
|
1119
|
-
inputs: [{ name: "
|
|
1120
|
-
outputs: [],
|
|
1121
|
-
stateMutability: "
|
|
1271
|
+
name: "depositedAmount",
|
|
1272
|
+
inputs: [{ name: "user", type: "address" }],
|
|
1273
|
+
outputs: [{ type: "uint256" }],
|
|
1274
|
+
stateMutability: "view"
|
|
1122
1275
|
},
|
|
1123
|
-
// ============ View Functions ============
|
|
1124
1276
|
{
|
|
1125
1277
|
type: "function",
|
|
1126
|
-
name: "
|
|
1278
|
+
name: "locks",
|
|
1127
1279
|
inputs: [{ name: "user", type: "address" }],
|
|
1128
1280
|
outputs: [
|
|
1129
1281
|
{ name: "amount", type: "uint256" },
|
|
@@ -1140,6 +1292,13 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1140
1292
|
outputs: [{ type: "uint256" }],
|
|
1141
1293
|
stateMutability: "view"
|
|
1142
1294
|
},
|
|
1295
|
+
{
|
|
1296
|
+
type: "function",
|
|
1297
|
+
name: "getEffectiveVeEXA",
|
|
1298
|
+
inputs: [{ name: "user", type: "address" }],
|
|
1299
|
+
outputs: [{ type: "uint256" }],
|
|
1300
|
+
stateMutability: "view"
|
|
1301
|
+
},
|
|
1143
1302
|
{
|
|
1144
1303
|
type: "function",
|
|
1145
1304
|
name: "calculateVeEXA",
|
|
@@ -1169,61 +1328,40 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1169
1328
|
},
|
|
1170
1329
|
{
|
|
1171
1330
|
type: "function",
|
|
1172
|
-
name: "
|
|
1331
|
+
name: "getEarningsTier",
|
|
1173
1332
|
inputs: [{ name: "user", type: "address" }],
|
|
1174
|
-
outputs: [{ type: "uint256" }],
|
|
1175
|
-
stateMutability: "view"
|
|
1176
|
-
},
|
|
1177
|
-
{
|
|
1178
|
-
type: "function",
|
|
1179
|
-
name: "getAgentDelegation",
|
|
1180
|
-
inputs: [{ name: "agentId", type: "uint256" }],
|
|
1181
1333
|
outputs: [
|
|
1182
|
-
{ name: "
|
|
1183
|
-
{ name: "
|
|
1334
|
+
{ name: "multiplierBps", type: "uint256" },
|
|
1335
|
+
{ name: "tierName", type: "string" }
|
|
1184
1336
|
],
|
|
1185
1337
|
stateMutability: "view"
|
|
1186
1338
|
},
|
|
1187
1339
|
{
|
|
1188
1340
|
type: "function",
|
|
1189
|
-
name: "
|
|
1341
|
+
name: "getEmergencyWithdrawPenalty",
|
|
1190
1342
|
inputs: [{ name: "user", type: "address" }],
|
|
1191
|
-
outputs: [{ name: "
|
|
1343
|
+
outputs: [{ name: "penaltyBps", type: "uint256" }],
|
|
1192
1344
|
stateMutability: "view"
|
|
1193
1345
|
},
|
|
1194
1346
|
{
|
|
1195
1347
|
type: "function",
|
|
1196
|
-
name: "
|
|
1197
|
-
inputs: [],
|
|
1198
|
-
outputs: [{ type: "address[]" }],
|
|
1199
|
-
stateMutability: "view"
|
|
1200
|
-
},
|
|
1201
|
-
{
|
|
1202
|
-
type: "function",
|
|
1203
|
-
name: "delegatedTo",
|
|
1348
|
+
name: "hasVaultAccess",
|
|
1204
1349
|
inputs: [{ name: "user", type: "address" }],
|
|
1205
|
-
outputs: [{ type: "
|
|
1350
|
+
outputs: [{ type: "bool" }],
|
|
1206
1351
|
stateMutability: "view"
|
|
1207
1352
|
},
|
|
1208
1353
|
{
|
|
1209
1354
|
type: "function",
|
|
1210
|
-
name: "
|
|
1355
|
+
name: "getUnlockedBalance",
|
|
1211
1356
|
inputs: [{ name: "user", type: "address" }],
|
|
1212
1357
|
outputs: [{ type: "uint256" }],
|
|
1213
1358
|
stateMutability: "view"
|
|
1214
1359
|
},
|
|
1215
1360
|
{
|
|
1216
1361
|
type: "function",
|
|
1217
|
-
name: "
|
|
1218
|
-
inputs: [
|
|
1219
|
-
outputs: [{ type: "
|
|
1220
|
-
stateMutability: "view"
|
|
1221
|
-
},
|
|
1222
|
-
{
|
|
1223
|
-
type: "function",
|
|
1224
|
-
name: "agentDelegatorCount",
|
|
1225
|
-
inputs: [{ name: "agentId", type: "uint256" }],
|
|
1226
|
-
outputs: [{ type: "uint256" }],
|
|
1362
|
+
name: "getRewardTokens",
|
|
1363
|
+
inputs: [],
|
|
1364
|
+
outputs: [{ type: "address[]" }],
|
|
1227
1365
|
stateMutability: "view"
|
|
1228
1366
|
},
|
|
1229
1367
|
{
|
|
@@ -1236,35 +1374,36 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1236
1374
|
// ============ Events ============
|
|
1237
1375
|
{
|
|
1238
1376
|
type: "event",
|
|
1239
|
-
name: "
|
|
1377
|
+
name: "Deposited",
|
|
1240
1378
|
inputs: [
|
|
1241
1379
|
{ name: "user", type: "address", indexed: true },
|
|
1242
1380
|
{ name: "amount", type: "uint256", indexed: false },
|
|
1243
|
-
{ name: "
|
|
1244
|
-
{ name: "unlockTime", type: "uint256", indexed: false },
|
|
1245
|
-
{ name: "vEXABalance", type: "uint256", indexed: false }
|
|
1381
|
+
{ name: "totalDeposited", type: "uint256", indexed: false }
|
|
1246
1382
|
]
|
|
1247
1383
|
},
|
|
1248
1384
|
{
|
|
1249
1385
|
type: "event",
|
|
1250
|
-
name: "
|
|
1386
|
+
name: "Withdrawn",
|
|
1251
1387
|
inputs: [
|
|
1252
1388
|
{ name: "user", type: "address", indexed: true },
|
|
1253
|
-
{ name: "amount", type: "uint256", indexed: false }
|
|
1389
|
+
{ name: "amount", type: "uint256", indexed: false },
|
|
1390
|
+
{ name: "totalDeposited", type: "uint256", indexed: false }
|
|
1254
1391
|
]
|
|
1255
1392
|
},
|
|
1256
1393
|
{
|
|
1257
1394
|
type: "event",
|
|
1258
|
-
name: "
|
|
1395
|
+
name: "Locked",
|
|
1259
1396
|
inputs: [
|
|
1260
1397
|
{ name: "user", type: "address", indexed: true },
|
|
1261
|
-
{ name: "
|
|
1262
|
-
{ name: "
|
|
1398
|
+
{ name: "amount", type: "uint256", indexed: false },
|
|
1399
|
+
{ name: "lockDuration", type: "uint256", indexed: false },
|
|
1400
|
+
{ name: "unlockTime", type: "uint256", indexed: false },
|
|
1401
|
+
{ name: "vEXABalance", type: "uint256", indexed: false }
|
|
1263
1402
|
]
|
|
1264
1403
|
},
|
|
1265
1404
|
{
|
|
1266
1405
|
type: "event",
|
|
1267
|
-
name: "
|
|
1406
|
+
name: "Unlocked",
|
|
1268
1407
|
inputs: [
|
|
1269
1408
|
{ name: "user", type: "address", indexed: true },
|
|
1270
1409
|
{ name: "amount", type: "uint256", indexed: false }
|
|
@@ -1272,20 +1411,29 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1272
1411
|
},
|
|
1273
1412
|
{
|
|
1274
1413
|
type: "event",
|
|
1275
|
-
name: "
|
|
1414
|
+
name: "EmergencyWithdrawal",
|
|
1276
1415
|
inputs: [
|
|
1277
|
-
{ name: "
|
|
1278
|
-
{ name: "
|
|
1279
|
-
{ name: "
|
|
1416
|
+
{ name: "user", type: "address", indexed: true },
|
|
1417
|
+
{ name: "returned", type: "uint256", indexed: false },
|
|
1418
|
+
{ name: "penalty", type: "uint256", indexed: false },
|
|
1419
|
+
{ name: "penaltyBps", type: "uint256", indexed: false }
|
|
1280
1420
|
]
|
|
1281
1421
|
},
|
|
1282
1422
|
{
|
|
1283
1423
|
type: "event",
|
|
1284
|
-
name: "
|
|
1424
|
+
name: "LockExtended",
|
|
1285
1425
|
inputs: [
|
|
1286
|
-
{ name: "
|
|
1287
|
-
{ name: "
|
|
1288
|
-
{ name: "
|
|
1426
|
+
{ name: "user", type: "address", indexed: true },
|
|
1427
|
+
{ name: "newUnlockTime", type: "uint256", indexed: false },
|
|
1428
|
+
{ name: "newVeEXABalance", type: "uint256", indexed: false }
|
|
1429
|
+
]
|
|
1430
|
+
},
|
|
1431
|
+
{
|
|
1432
|
+
type: "event",
|
|
1433
|
+
name: "RewardsClaimed",
|
|
1434
|
+
inputs: [
|
|
1435
|
+
{ name: "user", type: "address", indexed: true },
|
|
1436
|
+
{ name: "amount", type: "uint256", indexed: false }
|
|
1289
1437
|
]
|
|
1290
1438
|
},
|
|
1291
1439
|
{
|
|
@@ -1310,15 +1458,6 @@ var ERC20_APPROVE_ABI2 = [
|
|
|
1310
1458
|
stateMutability: "nonpayable"
|
|
1311
1459
|
}
|
|
1312
1460
|
];
|
|
1313
|
-
var DISCOUNT_TIERS = {
|
|
1314
|
-
none: 0,
|
|
1315
|
-
bronze: 1e3,
|
|
1316
|
-
// 10% discount at 10,000 vEXA
|
|
1317
|
-
silver: 2500,
|
|
1318
|
-
// 25% discount at 50,000 vEXA
|
|
1319
|
-
gold: 5e3
|
|
1320
|
-
// 50% discount at 100,000 vEXA
|
|
1321
|
-
};
|
|
1322
1461
|
var ExagentStaking = class {
|
|
1323
1462
|
address;
|
|
1324
1463
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -1331,108 +1470,119 @@ var ExagentStaking = class {
|
|
|
1331
1470
|
this.address = stakingAddress;
|
|
1332
1471
|
this.publicClient = publicClient;
|
|
1333
1472
|
this.walletClient = walletClient;
|
|
1473
|
+
if (!chain) {
|
|
1474
|
+
throw new Error("Chain parameter is required");
|
|
1475
|
+
}
|
|
1334
1476
|
this.chain = chain;
|
|
1335
1477
|
this.account = account;
|
|
1336
1478
|
}
|
|
1337
|
-
// ============
|
|
1479
|
+
// ============ Phase 1: Deposit / Withdraw ============
|
|
1338
1480
|
/**
|
|
1339
|
-
*
|
|
1340
|
-
* @param amount Amount of EXA to
|
|
1341
|
-
* @param lockDuration Lock duration in seconds (30 days to 2 years)
|
|
1481
|
+
* Deposit EXA tokens for vault access (no lock required)
|
|
1482
|
+
* @param amount Amount of EXA to deposit (in wei)
|
|
1342
1483
|
* @returns Transaction hash
|
|
1343
1484
|
*
|
|
1344
1485
|
* @example
|
|
1345
1486
|
* ```typescript
|
|
1346
|
-
* //
|
|
1347
|
-
* const tx = await staking.
|
|
1348
|
-
* parseEther('1000'),
|
|
1349
|
-
* BigInt(180 * 24 * 60 * 60) // 180 days in seconds
|
|
1350
|
-
* );
|
|
1487
|
+
* // Deposit 1000 EXA to unlock vault access
|
|
1488
|
+
* const tx = await staking.deposit(parseEther('1000'));
|
|
1351
1489
|
* ```
|
|
1352
1490
|
*/
|
|
1353
|
-
async
|
|
1491
|
+
async deposit(amount) {
|
|
1354
1492
|
if (!this.walletClient || !this.account) {
|
|
1355
1493
|
throw new Error("Wallet client required for write operations");
|
|
1356
1494
|
}
|
|
1357
1495
|
const hash = await this.walletClient.writeContract({
|
|
1358
1496
|
address: this.address,
|
|
1359
1497
|
abi: EXAGENT_STAKING_ABI,
|
|
1360
|
-
functionName: "
|
|
1361
|
-
args: [amount
|
|
1498
|
+
functionName: "deposit",
|
|
1499
|
+
args: [amount],
|
|
1362
1500
|
account: this.account,
|
|
1363
1501
|
chain: this.chain
|
|
1364
1502
|
});
|
|
1365
1503
|
return hash;
|
|
1366
1504
|
}
|
|
1367
1505
|
/**
|
|
1368
|
-
*
|
|
1506
|
+
* Withdraw unlocked EXA tokens (instant, no penalty)
|
|
1507
|
+
* @param amount Amount of EXA to withdraw (in wei)
|
|
1369
1508
|
* @returns Transaction hash
|
|
1370
|
-
* @throws Error if lock has not expired
|
|
1371
1509
|
*/
|
|
1372
|
-
async
|
|
1510
|
+
async withdraw(amount) {
|
|
1373
1511
|
if (!this.walletClient || !this.account) {
|
|
1374
1512
|
throw new Error("Wallet client required for write operations");
|
|
1375
1513
|
}
|
|
1376
1514
|
const hash = await this.walletClient.writeContract({
|
|
1377
1515
|
address: this.address,
|
|
1378
1516
|
abi: EXAGENT_STAKING_ABI,
|
|
1379
|
-
functionName: "
|
|
1380
|
-
args: [],
|
|
1517
|
+
functionName: "withdraw",
|
|
1518
|
+
args: [amount],
|
|
1381
1519
|
account: this.account,
|
|
1382
1520
|
chain: this.chain
|
|
1383
1521
|
});
|
|
1384
1522
|
return hash;
|
|
1385
1523
|
}
|
|
1524
|
+
// ============ Phase 2: Lock / Unlock ============
|
|
1386
1525
|
/**
|
|
1387
|
-
*
|
|
1388
|
-
* @param
|
|
1526
|
+
* Lock deposited EXA to receive vEXA voting power and earn rewards
|
|
1527
|
+
* @param amount Amount of deposited EXA to lock (in wei)
|
|
1528
|
+
* @param lockDuration Lock duration in seconds (30 days to 2 years)
|
|
1389
1529
|
* @returns Transaction hash
|
|
1530
|
+
*
|
|
1531
|
+
* @example
|
|
1532
|
+
* ```typescript
|
|
1533
|
+
* // Lock 1000 EXA for 6 months
|
|
1534
|
+
* const tx = await staking.lock(
|
|
1535
|
+
* parseEther('1000'),
|
|
1536
|
+
* ExagentStaking.LOCK_6_MONTHS
|
|
1537
|
+
* );
|
|
1538
|
+
* ```
|
|
1390
1539
|
*/
|
|
1391
|
-
async
|
|
1540
|
+
async lock(amount, lockDuration) {
|
|
1392
1541
|
if (!this.walletClient || !this.account) {
|
|
1393
1542
|
throw new Error("Wallet client required for write operations");
|
|
1394
1543
|
}
|
|
1395
1544
|
const hash = await this.walletClient.writeContract({
|
|
1396
1545
|
address: this.address,
|
|
1397
1546
|
abi: EXAGENT_STAKING_ABI,
|
|
1398
|
-
functionName: "
|
|
1399
|
-
args: [
|
|
1547
|
+
functionName: "lock",
|
|
1548
|
+
args: [amount, lockDuration],
|
|
1400
1549
|
account: this.account,
|
|
1401
1550
|
chain: this.chain
|
|
1402
1551
|
});
|
|
1403
1552
|
return hash;
|
|
1404
1553
|
}
|
|
1405
|
-
// ============ Reward Write Functions ============
|
|
1406
1554
|
/**
|
|
1407
|
-
*
|
|
1555
|
+
* Extend lock duration for additional voting power
|
|
1556
|
+
* @param newLockDuration New lock duration in seconds (must be longer than remaining)
|
|
1408
1557
|
* @returns Transaction hash
|
|
1409
1558
|
*/
|
|
1410
|
-
async
|
|
1559
|
+
async extendLock(newLockDuration) {
|
|
1411
1560
|
if (!this.walletClient || !this.account) {
|
|
1412
1561
|
throw new Error("Wallet client required for write operations");
|
|
1413
1562
|
}
|
|
1414
1563
|
const hash = await this.walletClient.writeContract({
|
|
1415
1564
|
address: this.address,
|
|
1416
1565
|
abi: EXAGENT_STAKING_ABI,
|
|
1417
|
-
functionName: "
|
|
1418
|
-
args: [],
|
|
1566
|
+
functionName: "extendLock",
|
|
1567
|
+
args: [newLockDuration],
|
|
1419
1568
|
account: this.account,
|
|
1420
1569
|
chain: this.chain
|
|
1421
1570
|
});
|
|
1422
1571
|
return hash;
|
|
1423
1572
|
}
|
|
1424
1573
|
/**
|
|
1425
|
-
*
|
|
1574
|
+
* Unlock EXA after lock expires (normal path — no penalty)
|
|
1575
|
+
* Returns locked amount to unlocked deposited balance.
|
|
1426
1576
|
* @returns Transaction hash
|
|
1427
1577
|
*/
|
|
1428
|
-
async
|
|
1578
|
+
async unlock() {
|
|
1429
1579
|
if (!this.walletClient || !this.account) {
|
|
1430
1580
|
throw new Error("Wallet client required for write operations");
|
|
1431
1581
|
}
|
|
1432
1582
|
const hash = await this.walletClient.writeContract({
|
|
1433
1583
|
address: this.address,
|
|
1434
1584
|
abi: EXAGENT_STAKING_ABI,
|
|
1435
|
-
functionName: "
|
|
1585
|
+
functionName: "unlock",
|
|
1436
1586
|
args: [],
|
|
1437
1587
|
account: this.account,
|
|
1438
1588
|
chain: this.chain
|
|
@@ -1440,56 +1590,56 @@ var ExagentStaking = class {
|
|
|
1440
1590
|
return hash;
|
|
1441
1591
|
}
|
|
1442
1592
|
/**
|
|
1443
|
-
*
|
|
1444
|
-
*
|
|
1593
|
+
* Emergency withdrawal — instant exit from lock with graduated penalty
|
|
1594
|
+
* Two-phase penalty: 50%→20% over the first quarter of the lock, then flat 20% until expiry.
|
|
1595
|
+
* Penalty goes to treasury. Remaining returns to unlocked deposit balance.
|
|
1445
1596
|
* @returns Transaction hash
|
|
1446
1597
|
*/
|
|
1447
|
-
async
|
|
1598
|
+
async emergencyWithdraw() {
|
|
1448
1599
|
if (!this.walletClient || !this.account) {
|
|
1449
1600
|
throw new Error("Wallet client required for write operations");
|
|
1450
1601
|
}
|
|
1451
1602
|
const hash = await this.walletClient.writeContract({
|
|
1452
1603
|
address: this.address,
|
|
1453
1604
|
abi: EXAGENT_STAKING_ABI,
|
|
1454
|
-
functionName: "
|
|
1455
|
-
args: [
|
|
1605
|
+
functionName: "emergencyWithdraw",
|
|
1606
|
+
args: [],
|
|
1456
1607
|
account: this.account,
|
|
1457
1608
|
chain: this.chain
|
|
1458
1609
|
});
|
|
1459
1610
|
return hash;
|
|
1460
1611
|
}
|
|
1461
|
-
// ============
|
|
1612
|
+
// ============ Reward Functions ============
|
|
1462
1613
|
/**
|
|
1463
|
-
*
|
|
1464
|
-
* @param agentId The agent ID to delegate to
|
|
1614
|
+
* Claim accumulated EXA rewards
|
|
1465
1615
|
* @returns Transaction hash
|
|
1466
1616
|
*/
|
|
1467
|
-
async
|
|
1617
|
+
async claimRewards() {
|
|
1468
1618
|
if (!this.walletClient || !this.account) {
|
|
1469
1619
|
throw new Error("Wallet client required for write operations");
|
|
1470
1620
|
}
|
|
1471
1621
|
const hash = await this.walletClient.writeContract({
|
|
1472
1622
|
address: this.address,
|
|
1473
1623
|
abi: EXAGENT_STAKING_ABI,
|
|
1474
|
-
functionName: "
|
|
1475
|
-
args: [
|
|
1624
|
+
functionName: "claimRewards",
|
|
1625
|
+
args: [],
|
|
1476
1626
|
account: this.account,
|
|
1477
1627
|
chain: this.chain
|
|
1478
1628
|
});
|
|
1479
1629
|
return hash;
|
|
1480
1630
|
}
|
|
1481
1631
|
/**
|
|
1482
|
-
*
|
|
1632
|
+
* Claim all pending multi-token rewards (ETH, USDC, etc.)
|
|
1483
1633
|
* @returns Transaction hash
|
|
1484
1634
|
*/
|
|
1485
|
-
async
|
|
1635
|
+
async claimRewardsMulti() {
|
|
1486
1636
|
if (!this.walletClient || !this.account) {
|
|
1487
1637
|
throw new Error("Wallet client required for write operations");
|
|
1488
1638
|
}
|
|
1489
1639
|
const hash = await this.walletClient.writeContract({
|
|
1490
1640
|
address: this.address,
|
|
1491
1641
|
abi: EXAGENT_STAKING_ABI,
|
|
1492
|
-
functionName: "
|
|
1642
|
+
functionName: "claimRewardsMulti",
|
|
1493
1643
|
args: [],
|
|
1494
1644
|
account: this.account,
|
|
1495
1645
|
chain: this.chain
|
|
@@ -1497,19 +1647,19 @@ var ExagentStaking = class {
|
|
|
1497
1647
|
return hash;
|
|
1498
1648
|
}
|
|
1499
1649
|
/**
|
|
1500
|
-
*
|
|
1501
|
-
* @param
|
|
1650
|
+
* Claim pending rewards for a specific token
|
|
1651
|
+
* @param token The reward token address to claim
|
|
1502
1652
|
* @returns Transaction hash
|
|
1503
1653
|
*/
|
|
1504
|
-
async
|
|
1654
|
+
async claimRewardsToken(token) {
|
|
1505
1655
|
if (!this.walletClient || !this.account) {
|
|
1506
1656
|
throw new Error("Wallet client required for write operations");
|
|
1507
1657
|
}
|
|
1508
1658
|
const hash = await this.walletClient.writeContract({
|
|
1509
1659
|
address: this.address,
|
|
1510
1660
|
abi: EXAGENT_STAKING_ABI,
|
|
1511
|
-
functionName: "
|
|
1512
|
-
args: [
|
|
1661
|
+
functionName: "claimRewardsToken",
|
|
1662
|
+
args: [token],
|
|
1513
1663
|
account: this.account,
|
|
1514
1664
|
chain: this.chain
|
|
1515
1665
|
});
|
|
@@ -1517,20 +1667,26 @@ var ExagentStaking = class {
|
|
|
1517
1667
|
}
|
|
1518
1668
|
// ============ Read Functions ============
|
|
1519
1669
|
/**
|
|
1520
|
-
* Get comprehensive staking info for a user
|
|
1670
|
+
* Get comprehensive staking info for a user (deposit + lock)
|
|
1521
1671
|
* @param userAddress Address to check (defaults to connected wallet)
|
|
1522
|
-
* @returns
|
|
1672
|
+
* @returns Combined staking info
|
|
1523
1673
|
*/
|
|
1524
|
-
async
|
|
1674
|
+
async getStakingInfo(userAddress) {
|
|
1525
1675
|
const user = userAddress ?? this.account?.address;
|
|
1526
1676
|
if (!user) {
|
|
1527
1677
|
throw new Error("User address required");
|
|
1528
1678
|
}
|
|
1529
|
-
const [
|
|
1679
|
+
const [deposited, lockResult, currentVeEXA, vaultAccess, unlockedBalance] = await Promise.all([
|
|
1680
|
+
this.publicClient.readContract({
|
|
1681
|
+
address: this.address,
|
|
1682
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1683
|
+
functionName: "depositedAmount",
|
|
1684
|
+
args: [user]
|
|
1685
|
+
}),
|
|
1530
1686
|
this.publicClient.readContract({
|
|
1531
1687
|
address: this.address,
|
|
1532
1688
|
abi: EXAGENT_STAKING_ABI,
|
|
1533
|
-
functionName: "
|
|
1689
|
+
functionName: "locks",
|
|
1534
1690
|
args: [user]
|
|
1535
1691
|
}),
|
|
1536
1692
|
this.publicClient.readContract({
|
|
@@ -1538,20 +1694,88 @@ var ExagentStaking = class {
|
|
|
1538
1694
|
abi: EXAGENT_STAKING_ABI,
|
|
1539
1695
|
functionName: "getVeEXABalance",
|
|
1540
1696
|
args: [user]
|
|
1697
|
+
}),
|
|
1698
|
+
this.publicClient.readContract({
|
|
1699
|
+
address: this.address,
|
|
1700
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1701
|
+
functionName: "hasVaultAccess",
|
|
1702
|
+
args: [user]
|
|
1703
|
+
}),
|
|
1704
|
+
this.publicClient.readContract({
|
|
1705
|
+
address: this.address,
|
|
1706
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1707
|
+
functionName: "getUnlockedBalance",
|
|
1708
|
+
args: [user]
|
|
1541
1709
|
})
|
|
1542
1710
|
]);
|
|
1543
|
-
const
|
|
1711
|
+
const lockData = lockResult;
|
|
1712
|
+
const depositedBigint = deposited;
|
|
1713
|
+
const lockedAmount = lockData[0];
|
|
1544
1714
|
const now = BigInt(Math.floor(Date.now() / 1e3));
|
|
1545
|
-
const
|
|
1546
|
-
|
|
1715
|
+
const depositInfo = {
|
|
1716
|
+
deposited: depositedBigint,
|
|
1717
|
+
locked: lockedAmount,
|
|
1718
|
+
unlocked: unlockedBalance,
|
|
1719
|
+
hasVaultAccess: vaultAccess
|
|
1720
|
+
};
|
|
1721
|
+
let lockInfo = null;
|
|
1722
|
+
if (lockedAmount > 0n) {
|
|
1723
|
+
const isUnlocked = lockData[1] <= now;
|
|
1724
|
+
const remainingLockTime = isUnlocked ? 0n : lockData[1] - now;
|
|
1725
|
+
lockInfo = {
|
|
1726
|
+
amount: lockData[0],
|
|
1727
|
+
unlockTime: lockData[1],
|
|
1728
|
+
lockDuration: lockData[2],
|
|
1729
|
+
vEXABalance: lockData[3],
|
|
1730
|
+
currentVeEXA,
|
|
1731
|
+
isUnlocked,
|
|
1732
|
+
remainingLockTime
|
|
1733
|
+
};
|
|
1734
|
+
}
|
|
1735
|
+
return { deposit: depositInfo, lock: lockInfo };
|
|
1736
|
+
}
|
|
1737
|
+
/**
|
|
1738
|
+
* Get deposit info for a user
|
|
1739
|
+
* @param userAddress Address to check (defaults to connected wallet)
|
|
1740
|
+
* @returns Deposit info
|
|
1741
|
+
*/
|
|
1742
|
+
async getDepositInfo(userAddress) {
|
|
1743
|
+
const user = userAddress ?? this.account?.address;
|
|
1744
|
+
if (!user) {
|
|
1745
|
+
throw new Error("User address required");
|
|
1746
|
+
}
|
|
1747
|
+
const [deposited, lockResult, vaultAccess, unlockedBalance] = await Promise.all([
|
|
1748
|
+
this.publicClient.readContract({
|
|
1749
|
+
address: this.address,
|
|
1750
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1751
|
+
functionName: "depositedAmount",
|
|
1752
|
+
args: [user]
|
|
1753
|
+
}),
|
|
1754
|
+
this.publicClient.readContract({
|
|
1755
|
+
address: this.address,
|
|
1756
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1757
|
+
functionName: "locks",
|
|
1758
|
+
args: [user]
|
|
1759
|
+
}),
|
|
1760
|
+
this.publicClient.readContract({
|
|
1761
|
+
address: this.address,
|
|
1762
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1763
|
+
functionName: "hasVaultAccess",
|
|
1764
|
+
args: [user]
|
|
1765
|
+
}),
|
|
1766
|
+
this.publicClient.readContract({
|
|
1767
|
+
address: this.address,
|
|
1768
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1769
|
+
functionName: "getUnlockedBalance",
|
|
1770
|
+
args: [user]
|
|
1771
|
+
})
|
|
1772
|
+
]);
|
|
1773
|
+
const lockData = lockResult;
|
|
1547
1774
|
return {
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
currentVeEXA,
|
|
1553
|
-
isUnlocked,
|
|
1554
|
-
remainingLockTime
|
|
1775
|
+
deposited,
|
|
1776
|
+
locked: lockData[0],
|
|
1777
|
+
unlocked: unlockedBalance,
|
|
1778
|
+
hasVaultAccess: vaultAccess
|
|
1555
1779
|
};
|
|
1556
1780
|
}
|
|
1557
1781
|
/**
|
|
@@ -1572,11 +1796,11 @@ var ExagentStaking = class {
|
|
|
1572
1796
|
});
|
|
1573
1797
|
}
|
|
1574
1798
|
/**
|
|
1575
|
-
* Get
|
|
1799
|
+
* Get effective vEXA (with tier multiplier applied)
|
|
1576
1800
|
* @param userAddress Address to check (defaults to connected wallet)
|
|
1577
|
-
* @returns
|
|
1801
|
+
* @returns Effective vEXA balance
|
|
1578
1802
|
*/
|
|
1579
|
-
async
|
|
1803
|
+
async getEffectiveVeEXA(userAddress) {
|
|
1580
1804
|
const user = userAddress ?? this.account?.address;
|
|
1581
1805
|
if (!user) {
|
|
1582
1806
|
throw new Error("User address required");
|
|
@@ -1584,52 +1808,64 @@ var ExagentStaking = class {
|
|
|
1584
1808
|
return this.publicClient.readContract({
|
|
1585
1809
|
address: this.address,
|
|
1586
1810
|
abi: EXAGENT_STAKING_ABI,
|
|
1587
|
-
functionName: "
|
|
1811
|
+
functionName: "getEffectiveVeEXA",
|
|
1588
1812
|
args: [user]
|
|
1589
1813
|
});
|
|
1590
1814
|
}
|
|
1591
1815
|
/**
|
|
1592
|
-
*
|
|
1593
|
-
* @param
|
|
1594
|
-
* @returns
|
|
1816
|
+
* Check if user has vault access (meets deposit threshold)
|
|
1817
|
+
* @param userAddress Address to check (defaults to connected wallet)
|
|
1818
|
+
* @returns True if user can access vaults
|
|
1595
1819
|
*/
|
|
1596
|
-
async
|
|
1820
|
+
async hasVaultAccess(userAddress) {
|
|
1821
|
+
const user = userAddress ?? this.account?.address;
|
|
1822
|
+
if (!user) {
|
|
1823
|
+
throw new Error("User address required");
|
|
1824
|
+
}
|
|
1825
|
+
return this.publicClient.readContract({
|
|
1826
|
+
address: this.address,
|
|
1827
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1828
|
+
functionName: "hasVaultAccess",
|
|
1829
|
+
args: [user]
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
/**
|
|
1833
|
+
* Get earnings tier for a user (Bronze/Silver/Gold/Platinum/Diamond)
|
|
1834
|
+
* @param userAddress Address to check (defaults to connected wallet)
|
|
1835
|
+
* @returns Tier info with multiplier and name
|
|
1836
|
+
*/
|
|
1837
|
+
async getEarningsTier(userAddress) {
|
|
1838
|
+
const user = userAddress ?? this.account?.address;
|
|
1839
|
+
if (!user) {
|
|
1840
|
+
throw new Error("User address required");
|
|
1841
|
+
}
|
|
1597
1842
|
const result = await this.publicClient.readContract({
|
|
1598
1843
|
address: this.address,
|
|
1599
1844
|
abi: EXAGENT_STAKING_ABI,
|
|
1600
|
-
functionName: "
|
|
1601
|
-
args: [
|
|
1845
|
+
functionName: "getEarningsTier",
|
|
1846
|
+
args: [user]
|
|
1602
1847
|
});
|
|
1603
1848
|
return {
|
|
1604
|
-
|
|
1605
|
-
|
|
1849
|
+
multiplierBps: result[0],
|
|
1850
|
+
tierName: result[1]
|
|
1606
1851
|
};
|
|
1607
1852
|
}
|
|
1608
1853
|
/**
|
|
1609
|
-
* Get
|
|
1854
|
+
* Get current emergency withdrawal penalty for a user
|
|
1610
1855
|
* @param userAddress Address to check (defaults to connected wallet)
|
|
1611
|
-
* @returns
|
|
1856
|
+
* @returns Penalty in basis points (5000 = 50% at lock start, ramps to 2000 over first 25% of lock, then flat 2000)
|
|
1612
1857
|
*/
|
|
1613
|
-
async
|
|
1858
|
+
async getEmergencyWithdrawPenalty(userAddress) {
|
|
1614
1859
|
const user = userAddress ?? this.account?.address;
|
|
1615
1860
|
if (!user) {
|
|
1616
1861
|
throw new Error("User address required");
|
|
1617
1862
|
}
|
|
1618
|
-
|
|
1863
|
+
return this.publicClient.readContract({
|
|
1619
1864
|
address: this.address,
|
|
1620
1865
|
abi: EXAGENT_STAKING_ABI,
|
|
1621
|
-
functionName: "
|
|
1866
|
+
functionName: "getEmergencyWithdrawPenalty",
|
|
1622
1867
|
args: [user]
|
|
1623
1868
|
});
|
|
1624
|
-
let tier = "none";
|
|
1625
|
-
if (discountBps >= 5000n) {
|
|
1626
|
-
tier = "gold";
|
|
1627
|
-
} else if (discountBps >= 2500n) {
|
|
1628
|
-
tier = "silver";
|
|
1629
|
-
} else if (discountBps >= 1000n) {
|
|
1630
|
-
tier = "bronze";
|
|
1631
|
-
}
|
|
1632
|
-
return { tier, discountBps };
|
|
1633
1869
|
}
|
|
1634
1870
|
/**
|
|
1635
1871
|
* Get pending EXA rewards for a user
|
|
@@ -1691,14 +1927,25 @@ var ExagentStaking = class {
|
|
|
1691
1927
|
});
|
|
1692
1928
|
}
|
|
1693
1929
|
/**
|
|
1694
|
-
* Get total
|
|
1695
|
-
* @returns Total
|
|
1930
|
+
* Get total EXA deposited across all users
|
|
1931
|
+
* @returns Total deposited amount in wei
|
|
1696
1932
|
*/
|
|
1697
|
-
async
|
|
1933
|
+
async getTotalDeposited() {
|
|
1698
1934
|
return this.publicClient.readContract({
|
|
1699
1935
|
address: this.address,
|
|
1700
1936
|
abi: EXAGENT_STAKING_ABI,
|
|
1701
|
-
functionName: "
|
|
1937
|
+
functionName: "totalDeposited"
|
|
1938
|
+
});
|
|
1939
|
+
}
|
|
1940
|
+
/**
|
|
1941
|
+
* Get total EXA locked across all users
|
|
1942
|
+
* @returns Total locked amount in wei
|
|
1943
|
+
*/
|
|
1944
|
+
async getTotalLocked() {
|
|
1945
|
+
return this.publicClient.readContract({
|
|
1946
|
+
address: this.address,
|
|
1947
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1948
|
+
functionName: "totalLocked"
|
|
1702
1949
|
});
|
|
1703
1950
|
}
|
|
1704
1951
|
/**
|
|
@@ -1713,8 +1960,8 @@ var ExagentStaking = class {
|
|
|
1713
1960
|
});
|
|
1714
1961
|
}
|
|
1715
1962
|
/**
|
|
1716
|
-
* Calculate vEXA balance for a given
|
|
1717
|
-
* @param amount Amount of EXA to
|
|
1963
|
+
* Calculate vEXA balance for a given lock (preview)
|
|
1964
|
+
* @param amount Amount of EXA to lock
|
|
1718
1965
|
* @param lockDuration Lock duration in seconds
|
|
1719
1966
|
* @returns Expected vEXA balance
|
|
1720
1967
|
*/
|
|
@@ -1739,7 +1986,7 @@ var ExagentStaking = class {
|
|
|
1739
1986
|
}
|
|
1740
1987
|
// ============ Helper Functions ============
|
|
1741
1988
|
/**
|
|
1742
|
-
* Approve EXA token spending for
|
|
1989
|
+
* Approve EXA token spending for deposits
|
|
1743
1990
|
* @param amount Amount to approve
|
|
1744
1991
|
* @returns Transaction hash
|
|
1745
1992
|
*/
|
|
@@ -1776,36 +2023,24 @@ var ExagentStaking = class {
|
|
|
1776
2023
|
};
|
|
1777
2024
|
|
|
1778
2025
|
// src/constants.ts
|
|
1779
|
-
import { base
|
|
2026
|
+
import { base } from "viem/chains";
|
|
2027
|
+
var SDK_VERSION = "0.1.4";
|
|
1780
2028
|
var CHAIN_CONFIG = {
|
|
1781
|
-
mainnet: base
|
|
1782
|
-
testnet: baseSepolia
|
|
2029
|
+
mainnet: base
|
|
1783
2030
|
};
|
|
1784
2031
|
var CONTRACT_ADDRESSES = {
|
|
1785
2032
|
mainnet: {
|
|
1786
|
-
agentRegistry: "
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
router: "0x0000000000000000000000000000000000000000",
|
|
2033
|
+
agentRegistry: "0x2261706C751F8ac5cdDb481B7b56EA2137d4A723",
|
|
2034
|
+
exaToken: "0x13403Fb738C97cF7564F279288468c140AaEd05c",
|
|
2035
|
+
staking: "0xAF1729D1519A72f7d9b87aa23a305b775e2849DA",
|
|
2036
|
+
router: "0x11daD5366D903a3eF5d8f07EFF87ce6b173859a9",
|
|
1791
2037
|
vaultFactory: "0x0000000000000000000000000000000000000000",
|
|
1792
|
-
|
|
2038
|
+
// Phase 2 — pending deploy
|
|
2039
|
+
feeCollector: "0xe66328a964AF93bEF2eDB226D039C35aE6e66De1",
|
|
1793
2040
|
buyback: "0x0000000000000000000000000000000000000000",
|
|
2041
|
+
// Phase 2 — pending deploy
|
|
1794
2042
|
serviceEscrow: "0x0000000000000000000000000000000000000000"
|
|
1795
|
-
|
|
1796
|
-
testnet: {
|
|
1797
|
-
agentRegistry: "0xCF48C341e3FebeCA5ECB7eb2535f61A2Ba855d9C",
|
|
1798
|
-
// V4 UUPS proxy, one-agent-per-wallet
|
|
1799
|
-
exaToken: "0x66c39b0ad96B3f5eE198Fef913c6636353a48A87",
|
|
1800
|
-
staking: "0x439441468e1b1b616E9D36b80969C241F261A011",
|
|
1801
|
-
// V2 with delegation
|
|
1802
|
-
router: "0xc0c27eEE047E414CD716D06C2444CF2073113d5C",
|
|
1803
|
-
// V3 with config epochs
|
|
1804
|
-
vaultFactory: "0x5c099daaE33801a907Bb57011c6749655b55dc75",
|
|
1805
|
-
// V2 with requirements
|
|
1806
|
-
feeCollector: "0xcB57b03a50df054b9C738Df1324C17A4fDe4fe46",
|
|
1807
|
-
buyback: "0x35cdEa810A130A846265682e5c71A68A507aB895",
|
|
1808
|
-
serviceEscrow: "0x74a3496b148DEE735ac388299aF9Ac2F7C4EdCBf"
|
|
2043
|
+
// Phase 2 — pending deploy
|
|
1809
2044
|
}
|
|
1810
2045
|
};
|
|
1811
2046
|
var DEX_ADDRESSES = {
|
|
@@ -1825,21 +2060,44 @@ var ZERO_X_CONFIG = {
|
|
|
1825
2060
|
// Base
|
|
1826
2061
|
};
|
|
1827
2062
|
var EXAGENT_API_CONFIG = {
|
|
1828
|
-
mainnet: "https://api.
|
|
1829
|
-
testnet: "https://api.testnet.exagent.io"
|
|
2063
|
+
mainnet: "https://exagent-api.onrender.com"
|
|
1830
2064
|
};
|
|
1831
2065
|
var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
2066
|
+
var PHASE_1_CONTRACTS = /* @__PURE__ */ new Set([
|
|
2067
|
+
"agentRegistry",
|
|
2068
|
+
"exaToken",
|
|
2069
|
+
"staking",
|
|
2070
|
+
"router",
|
|
2071
|
+
"feeCollector"
|
|
2072
|
+
]);
|
|
1832
2073
|
function validateContractAddresses(network) {
|
|
1833
2074
|
const addresses = CONTRACT_ADDRESSES[network];
|
|
1834
|
-
const
|
|
1835
|
-
if (
|
|
1836
|
-
const missing = zeroEntries.map(([name]) => name).join(", ");
|
|
2075
|
+
const missingPhase1 = Object.entries(addresses).filter(([name, addr]) => PHASE_1_CONTRACTS.has(name) && addr === ZERO_ADDRESS).map(([name]) => name);
|
|
2076
|
+
if (missingPhase1.length > 0) {
|
|
1837
2077
|
throw new Error(
|
|
1838
|
-
`Mainnet contracts not
|
|
2078
|
+
`Mainnet Phase 1 contracts not deployed. Missing: ${missingPhase1.join(", ")}. Update @exagent/sdk to the latest version.`
|
|
1839
2079
|
);
|
|
1840
2080
|
}
|
|
1841
2081
|
}
|
|
1842
2082
|
|
|
2083
|
+
// src/types.ts
|
|
2084
|
+
function buildGlobalAgentId(chainId, registryAddress, agentId) {
|
|
2085
|
+
return `eip155:${chainId}:${registryAddress}:${Number(agentId)}`;
|
|
2086
|
+
}
|
|
2087
|
+
function parseGlobalAgentId(globalId) {
|
|
2088
|
+
const parts = globalId.split(":");
|
|
2089
|
+
if (parts.length !== 4 || parts[0] !== "eip155") {
|
|
2090
|
+
throw new Error(`Invalid ERC-8004 global agent ID: ${globalId}`);
|
|
2091
|
+
}
|
|
2092
|
+
const chainId = parseInt(parts[1], 10);
|
|
2093
|
+
const registryAddress = parts[2];
|
|
2094
|
+
const agentId = parseInt(parts[3], 10);
|
|
2095
|
+
if (isNaN(chainId) || isNaN(agentId)) {
|
|
2096
|
+
throw new Error(`Invalid ERC-8004 global agent ID: ${globalId}`);
|
|
2097
|
+
}
|
|
2098
|
+
return { chainId, registryAddress, agentId };
|
|
2099
|
+
}
|
|
2100
|
+
|
|
1843
2101
|
// src/client.ts
|
|
1844
2102
|
var ExagentClient = class {
|
|
1845
2103
|
publicClient;
|
|
@@ -1853,7 +2111,7 @@ var ExagentClient = class {
|
|
|
1853
2111
|
// Cached agent ID
|
|
1854
2112
|
_agentId;
|
|
1855
2113
|
constructor(config) {
|
|
1856
|
-
this.network = config.network ?? "
|
|
2114
|
+
this.network = config.network ?? "mainnet";
|
|
1857
2115
|
this.apiKey = config.apiKey;
|
|
1858
2116
|
validateContractAddresses(this.network);
|
|
1859
2117
|
const chain = CHAIN_CONFIG[this.network];
|
|
@@ -1890,6 +2148,14 @@ var ExagentClient = class {
|
|
|
1890
2148
|
this.account
|
|
1891
2149
|
);
|
|
1892
2150
|
}
|
|
2151
|
+
/** Standard headers for all API requests (includes SDK version for gating) */
|
|
2152
|
+
apiHeaders(contentType) {
|
|
2153
|
+
return {
|
|
2154
|
+
...contentType && { "Content-Type": contentType },
|
|
2155
|
+
"X-Exagent-SDK-Version": SDK_VERSION,
|
|
2156
|
+
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2157
|
+
};
|
|
2158
|
+
}
|
|
1893
2159
|
// ============ Agent Registration ============
|
|
1894
2160
|
/**
|
|
1895
2161
|
* Register as a new agent on Exagent
|
|
@@ -1977,127 +2243,15 @@ var ExagentClient = class {
|
|
|
1977
2243
|
}
|
|
1978
2244
|
// ============ Trading ============
|
|
1979
2245
|
/**
|
|
1980
|
-
*
|
|
1981
|
-
* Uses 0x API for aggregation across Aerodrome, Uniswap, etc.
|
|
1982
|
-
*/
|
|
1983
|
-
async getRoute(intent) {
|
|
1984
|
-
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
1985
|
-
const response = await fetch(`${apiUrl}/v1/routes/quote`, {
|
|
1986
|
-
method: "POST",
|
|
1987
|
-
headers: {
|
|
1988
|
-
"Content-Type": "application/json",
|
|
1989
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
1990
|
-
},
|
|
1991
|
-
body: JSON.stringify({
|
|
1992
|
-
tokenIn: intent.tokenIn,
|
|
1993
|
-
tokenOut: intent.tokenOut,
|
|
1994
|
-
amountIn: intent.amountIn.toString(),
|
|
1995
|
-
slippageBps: intent.maxSlippageBps ?? 50,
|
|
1996
|
-
taker: this.account.address
|
|
1997
|
-
})
|
|
1998
|
-
});
|
|
1999
|
-
if (!response.ok) {
|
|
2000
|
-
const error = await response.json().catch(() => ({ error: response.statusText }));
|
|
2001
|
-
throw new Error(`Failed to get route: ${error.error}`);
|
|
2002
|
-
}
|
|
2003
|
-
return response.json();
|
|
2004
|
-
}
|
|
2005
|
-
/**
|
|
2006
|
-
* Get price quote without transaction data (faster)
|
|
2007
|
-
*/
|
|
2008
|
-
async getPrice(tokenIn, tokenOut, amountIn) {
|
|
2009
|
-
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2010
|
-
const response = await fetch(`${apiUrl}/v1/routes/price`, {
|
|
2011
|
-
method: "POST",
|
|
2012
|
-
headers: {
|
|
2013
|
-
"Content-Type": "application/json",
|
|
2014
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2015
|
-
},
|
|
2016
|
-
body: JSON.stringify({
|
|
2017
|
-
tokenIn,
|
|
2018
|
-
tokenOut,
|
|
2019
|
-
amountIn: amountIn.toString()
|
|
2020
|
-
})
|
|
2021
|
-
});
|
|
2022
|
-
if (!response.ok) {
|
|
2023
|
-
const error = await response.json().catch(() => ({ error: response.statusText }));
|
|
2024
|
-
throw new Error(`Failed to get price: ${error.error}`);
|
|
2025
|
-
}
|
|
2026
|
-
return response.json();
|
|
2027
|
-
}
|
|
2028
|
-
/**
|
|
2029
|
-
* Execute a trade using a pre-fetched route
|
|
2030
|
-
* @param route Route quote from getRoute()
|
|
2031
|
-
* @param options Trade execution options
|
|
2032
|
-
* @returns Transaction hash
|
|
2033
|
-
*/
|
|
2034
|
-
async executeTrade(route, options) {
|
|
2035
|
-
if (route.validUntil && Date.now() > route.validUntil) {
|
|
2036
|
-
throw new Error("Quote expired, please fetch a new route");
|
|
2037
|
-
}
|
|
2038
|
-
if (route.issues?.allowance) {
|
|
2039
|
-
throw new Error(
|
|
2040
|
-
`Insufficient allowance for ${route.issues.allowance.spender}. Need ${route.issues.allowance.expected}, have ${route.issues.allowance.actual}`
|
|
2041
|
-
);
|
|
2042
|
-
}
|
|
2043
|
-
if (options?.validateSlippage !== false) {
|
|
2044
|
-
const freshPrice = await this.getPrice(
|
|
2045
|
-
route.tokenIn,
|
|
2046
|
-
route.tokenOut,
|
|
2047
|
-
BigInt(route.amountIn)
|
|
2048
|
-
);
|
|
2049
|
-
const quotedOutput = BigInt(route.amountOut);
|
|
2050
|
-
const freshOutput = BigInt(freshPrice.amountOut);
|
|
2051
|
-
if (freshOutput < quotedOutput * 99n / 100n) {
|
|
2052
|
-
console.warn("Price has moved significantly since quote was fetched");
|
|
2053
|
-
}
|
|
2054
|
-
}
|
|
2055
|
-
const hash = await this.walletClient.sendTransaction({
|
|
2056
|
-
account: this.account,
|
|
2057
|
-
chain: CHAIN_CONFIG[this.network],
|
|
2058
|
-
to: route.transaction.to,
|
|
2059
|
-
data: route.transaction.data,
|
|
2060
|
-
value: BigInt(route.transaction.value)
|
|
2061
|
-
});
|
|
2062
|
-
return hash;
|
|
2063
|
-
}
|
|
2064
|
-
/**
|
|
2065
|
-
* Get and execute a trade in one call
|
|
2066
|
-
* Convenience method that fetches route and executes
|
|
2067
|
-
*/
|
|
2068
|
-
async swap(intent) {
|
|
2069
|
-
const route = await this.getRoute(intent);
|
|
2070
|
-
const hash = await this.executeTrade(route);
|
|
2071
|
-
return { hash, route };
|
|
2072
|
-
}
|
|
2073
|
-
/**
|
|
2074
|
-
* Broadcast a trade intent to the network
|
|
2075
|
-
* Other agents can see this and potentially provide better execution
|
|
2076
|
-
*/
|
|
2077
|
-
async broadcastIntent(intent) {
|
|
2078
|
-
const agentId = await this.getAgentId();
|
|
2079
|
-
if (!agentId) throw new Error("Agent not registered");
|
|
2080
|
-
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2081
|
-
await fetch(`${apiUrl}/v1/intents`, {
|
|
2082
|
-
method: "POST",
|
|
2083
|
-
headers: {
|
|
2084
|
-
"Content-Type": "application/json",
|
|
2085
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2086
|
-
},
|
|
2087
|
-
body: JSON.stringify({
|
|
2088
|
-
agentId: agentId.toString(),
|
|
2089
|
-
intent,
|
|
2090
|
-
signature: await this.signIntent(intent)
|
|
2091
|
-
})
|
|
2092
|
-
});
|
|
2093
|
-
}
|
|
2094
|
-
// ============ Router Trading (Attributed) ============
|
|
2095
|
-
/**
|
|
2096
|
-
* Execute a trade through ExagentRouter for full attribution
|
|
2246
|
+
* Execute a trade through ExagentRouter
|
|
2097
2247
|
*
|
|
2098
|
-
*
|
|
2099
|
-
*
|
|
2100
|
-
*
|
|
2248
|
+
* All trades MUST go through the ExagentRouter. This ensures:
|
|
2249
|
+
* - Trade attribution for leaderboard ranking
|
|
2250
|
+
* - Protocol fee collection (0.2%)
|
|
2251
|
+
* - On-chain performance tracking
|
|
2252
|
+
* - Token whitelist enforcement per risk universe
|
|
2253
|
+
*
|
|
2254
|
+
* There is no way to trade outside the router. This is by design.
|
|
2101
2255
|
*
|
|
2102
2256
|
* @param intent Trade parameters
|
|
2103
2257
|
* @returns Trade result with transaction hash
|
|
@@ -2150,10 +2304,7 @@ var ExagentClient = class {
|
|
|
2150
2304
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2151
2305
|
const response = await fetch(`${apiUrl}/v1/router/trade`, {
|
|
2152
2306
|
method: "POST",
|
|
2153
|
-
headers:
|
|
2154
|
-
"Content-Type": "application/json",
|
|
2155
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2156
|
-
},
|
|
2307
|
+
headers: this.apiHeaders("application/json"),
|
|
2157
2308
|
body: JSON.stringify({
|
|
2158
2309
|
agentId: id.toString(),
|
|
2159
2310
|
tokenIn: intent.tokenIn,
|
|
@@ -2202,10 +2353,7 @@ var ExagentClient = class {
|
|
|
2202
2353
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2203
2354
|
const response = await fetch(`${apiUrl}/v1/services/request`, {
|
|
2204
2355
|
method: "POST",
|
|
2205
|
-
headers:
|
|
2206
|
-
"Content-Type": "application/json",
|
|
2207
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2208
|
-
},
|
|
2356
|
+
headers: this.apiHeaders("application/json"),
|
|
2209
2357
|
body: JSON.stringify({
|
|
2210
2358
|
requesterId: agentId.toString(),
|
|
2211
2359
|
...request
|
|
@@ -2223,7 +2371,9 @@ var ExagentClient = class {
|
|
|
2223
2371
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2224
2372
|
const params = new URLSearchParams();
|
|
2225
2373
|
if (serviceType) params.set("type", serviceType);
|
|
2226
|
-
const response = await fetch(`${apiUrl}/v1/services?${params}
|
|
2374
|
+
const response = await fetch(`${apiUrl}/v1/services?${params}`, {
|
|
2375
|
+
headers: this.apiHeaders()
|
|
2376
|
+
});
|
|
2227
2377
|
return response.json();
|
|
2228
2378
|
}
|
|
2229
2379
|
// ============ Leaderboards ============
|
|
@@ -2236,7 +2386,9 @@ var ExagentClient = class {
|
|
|
2236
2386
|
if (options?.category) params.set("category", options.category);
|
|
2237
2387
|
if (options?.limit) params.set("limit", options.limit.toString());
|
|
2238
2388
|
if (options?.offset) params.set("offset", options.offset.toString());
|
|
2239
|
-
const response = await fetch(`${apiUrl}/v1/rankings/leaderboard?${params}
|
|
2389
|
+
const response = await fetch(`${apiUrl}/v1/rankings/leaderboard?${params}`, {
|
|
2390
|
+
headers: this.apiHeaders()
|
|
2391
|
+
});
|
|
2240
2392
|
return response.json();
|
|
2241
2393
|
}
|
|
2242
2394
|
// ============ Vault Functions (Phase 4: Copy Trading) ============
|
|
@@ -2264,9 +2416,7 @@ var ExagentClient = class {
|
|
|
2264
2416
|
if (!id) throw new Error("Agent not registered");
|
|
2265
2417
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2266
2418
|
const response = await fetch(`${apiUrl}/v1/vaults?agentId=${id}`, {
|
|
2267
|
-
headers:
|
|
2268
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2269
|
-
}
|
|
2419
|
+
headers: this.apiHeaders()
|
|
2270
2420
|
});
|
|
2271
2421
|
if (!response.ok) {
|
|
2272
2422
|
throw new Error(`Failed to get vaults: ${response.statusText}`);
|
|
@@ -2282,9 +2432,7 @@ var ExagentClient = class {
|
|
|
2282
2432
|
const user = userAddress ?? this.account.address;
|
|
2283
2433
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2284
2434
|
const response = await fetch(`${apiUrl}/v1/vaults?depositor=${user}`, {
|
|
2285
|
-
headers:
|
|
2286
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2287
|
-
}
|
|
2435
|
+
headers: this.apiHeaders()
|
|
2288
2436
|
});
|
|
2289
2437
|
if (!response.ok) {
|
|
2290
2438
|
throw new Error(`Failed to get user vaults: ${response.statusText}`);
|
|
@@ -2304,9 +2452,7 @@ var ExagentClient = class {
|
|
|
2304
2452
|
if (options?.period) params.set("period", options.period);
|
|
2305
2453
|
if (options?.limit) params.set("limit", options.limit.toString());
|
|
2306
2454
|
const response = await fetch(`${apiUrl}/v1/vaults/top?${params}`, {
|
|
2307
|
-
headers:
|
|
2308
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2309
|
-
}
|
|
2455
|
+
headers: this.apiHeaders()
|
|
2310
2456
|
});
|
|
2311
2457
|
if (!response.ok) {
|
|
2312
2458
|
throw new Error(`Failed to get top vaults: ${response.statusText}`);
|
|
@@ -2347,37 +2493,73 @@ var ExagentClient = class {
|
|
|
2347
2493
|
}
|
|
2348
2494
|
// ============ Staking Functions ============
|
|
2349
2495
|
/**
|
|
2350
|
-
*
|
|
2351
|
-
* @param amount Amount of EXA to
|
|
2496
|
+
* Deposit EXA tokens for vault access (no lock required)
|
|
2497
|
+
* @param amount Amount of EXA to deposit (in wei)
|
|
2498
|
+
* @returns Transaction hash
|
|
2499
|
+
*
|
|
2500
|
+
* @example
|
|
2501
|
+
* ```typescript
|
|
2502
|
+
* // Deposit 1000 EXA to unlock vault access
|
|
2503
|
+
* const tx = await exagent.depositExa(parseEther('1000'));
|
|
2504
|
+
* ```
|
|
2505
|
+
*/
|
|
2506
|
+
async depositExa(amount) {
|
|
2507
|
+
await this.staking.approveExa(amount);
|
|
2508
|
+
return this.staking.deposit(amount);
|
|
2509
|
+
}
|
|
2510
|
+
/**
|
|
2511
|
+
* Withdraw unlocked EXA tokens (instant, no penalty)
|
|
2512
|
+
* @param amount Amount of EXA to withdraw (in wei)
|
|
2513
|
+
* @returns Transaction hash
|
|
2514
|
+
*/
|
|
2515
|
+
async withdrawExa(amount) {
|
|
2516
|
+
return this.staking.withdraw(amount);
|
|
2517
|
+
}
|
|
2518
|
+
/**
|
|
2519
|
+
* Lock deposited EXA to receive vEXA voting power and earn rewards
|
|
2520
|
+
* @param amount Amount of deposited EXA to lock (in wei)
|
|
2352
2521
|
* @param lockDuration Lock duration in seconds (30 days to 2 years)
|
|
2353
2522
|
* @returns Transaction hash
|
|
2354
2523
|
*
|
|
2355
2524
|
* @example
|
|
2356
2525
|
* ```typescript
|
|
2357
|
-
* //
|
|
2358
|
-
* const tx = await exagent.
|
|
2526
|
+
* // Lock 1000 EXA for 6 months
|
|
2527
|
+
* const tx = await exagent.lockExa(
|
|
2359
2528
|
* parseEther('1000'),
|
|
2360
2529
|
* ExagentStaking.LOCK_6_MONTHS
|
|
2361
2530
|
* );
|
|
2362
2531
|
* ```
|
|
2363
2532
|
*/
|
|
2364
|
-
async
|
|
2365
|
-
|
|
2366
|
-
return this.staking.stake(amount, lockDuration);
|
|
2533
|
+
async lockExa(amount, lockDuration) {
|
|
2534
|
+
return this.staking.lock(amount, lockDuration);
|
|
2367
2535
|
}
|
|
2368
2536
|
/**
|
|
2369
|
-
*
|
|
2537
|
+
* Unlock EXA after lock expires (no penalty)
|
|
2370
2538
|
* @returns Transaction hash
|
|
2371
2539
|
*/
|
|
2372
|
-
async
|
|
2373
|
-
return this.staking.
|
|
2540
|
+
async unlockExa() {
|
|
2541
|
+
return this.staking.unlock();
|
|
2374
2542
|
}
|
|
2375
2543
|
/**
|
|
2376
|
-
*
|
|
2377
|
-
* @returns
|
|
2544
|
+
* Emergency withdrawal from active lock (graduated 50%→20% penalty)
|
|
2545
|
+
* @returns Transaction hash
|
|
2546
|
+
*/
|
|
2547
|
+
async emergencyWithdrawExa() {
|
|
2548
|
+
return this.staking.emergencyWithdraw();
|
|
2549
|
+
}
|
|
2550
|
+
/**
|
|
2551
|
+
* Get comprehensive staking info (deposit + lock) for the connected wallet
|
|
2552
|
+
* @returns Staking info including deposit status and lock status
|
|
2378
2553
|
*/
|
|
2379
2554
|
async getStakingInfo() {
|
|
2380
|
-
return this.staking.
|
|
2555
|
+
return this.staking.getStakingInfo();
|
|
2556
|
+
}
|
|
2557
|
+
/**
|
|
2558
|
+
* Get deposit info for the connected wallet
|
|
2559
|
+
* @returns Deposit info (deposited, locked, unlocked, vault access)
|
|
2560
|
+
*/
|
|
2561
|
+
async getDepositInfo() {
|
|
2562
|
+
return this.staking.getDepositInfo();
|
|
2381
2563
|
}
|
|
2382
2564
|
/**
|
|
2383
2565
|
* Get current vEXA balance for the connected wallet
|
|
@@ -2387,20 +2569,25 @@ var ExagentClient = class {
|
|
|
2387
2569
|
return this.staking.getVeEXABalance();
|
|
2388
2570
|
}
|
|
2389
2571
|
/**
|
|
2390
|
-
*
|
|
2391
|
-
* @
|
|
2392
|
-
|
|
2572
|
+
* Check if connected wallet has vault access (meets deposit threshold)
|
|
2573
|
+
* @returns True if user can access vaults
|
|
2574
|
+
*/
|
|
2575
|
+
async hasVaultAccess() {
|
|
2576
|
+
return this.staking.hasVaultAccess();
|
|
2577
|
+
}
|
|
2578
|
+
/**
|
|
2579
|
+
* Get earnings tier for the connected wallet
|
|
2580
|
+
* @returns Tier info with multiplier and name
|
|
2393
2581
|
*/
|
|
2394
|
-
async
|
|
2395
|
-
return this.staking.
|
|
2582
|
+
async getEarningsTier() {
|
|
2583
|
+
return this.staking.getEarningsTier();
|
|
2396
2584
|
}
|
|
2397
2585
|
/**
|
|
2398
|
-
* Get
|
|
2399
|
-
* @
|
|
2400
|
-
* @returns Delegation info with total vEXA and delegator count
|
|
2586
|
+
* Get emergency withdrawal penalty for the connected wallet
|
|
2587
|
+
* @returns Penalty in basis points (5000 = 50% at start, 2000 = 20% near expiry)
|
|
2401
2588
|
*/
|
|
2402
|
-
async
|
|
2403
|
-
return this.staking.
|
|
2589
|
+
async getEmergencyWithdrawPenalty() {
|
|
2590
|
+
return this.staking.getEmergencyWithdrawPenalty();
|
|
2404
2591
|
}
|
|
2405
2592
|
/**
|
|
2406
2593
|
* Claim all pending staking rewards (EXA + multi-token)
|
|
@@ -2411,6 +2598,46 @@ var ExagentClient = class {
|
|
|
2411
2598
|
const multiTokenRewards = await this.staking.claimRewardsMulti();
|
|
2412
2599
|
return { exaRewards, multiTokenRewards };
|
|
2413
2600
|
}
|
|
2601
|
+
// ============ ERC-8004 Global Agent Identity ============
|
|
2602
|
+
/**
|
|
2603
|
+
* Get the ERC-8004 global agent identifier for the current agent
|
|
2604
|
+
*
|
|
2605
|
+
* Format: eip155:{chainId}:{registryAddress}:{agentId}
|
|
2606
|
+
*
|
|
2607
|
+
* This creates a universally unique identifier that can be used for
|
|
2608
|
+
* cross-protocol agent discovery and interoperability.
|
|
2609
|
+
*
|
|
2610
|
+
* @returns The global agent ID string
|
|
2611
|
+
* @throws Error if agent is not registered
|
|
2612
|
+
*
|
|
2613
|
+
* @example
|
|
2614
|
+
* ```typescript
|
|
2615
|
+
* const globalId = await exagent.getGlobalAgentId();
|
|
2616
|
+
* // => "eip155:8453:0xABC...DEF:42"
|
|
2617
|
+
* ```
|
|
2618
|
+
*/
|
|
2619
|
+
async getGlobalAgentId() {
|
|
2620
|
+
const agentId = await this.getAgentId();
|
|
2621
|
+
if (!agentId) throw new Error("Agent not registered");
|
|
2622
|
+
const chain = CHAIN_CONFIG[this.network];
|
|
2623
|
+
const addresses = CONTRACT_ADDRESSES[this.network];
|
|
2624
|
+
return buildGlobalAgentId(
|
|
2625
|
+
chain.id,
|
|
2626
|
+
addresses.agentRegistry,
|
|
2627
|
+
agentId
|
|
2628
|
+
);
|
|
2629
|
+
}
|
|
2630
|
+
/**
|
|
2631
|
+
* Build a global agent ID for any agent (static utility)
|
|
2632
|
+
*
|
|
2633
|
+
* @param chainId - EVM chain ID
|
|
2634
|
+
* @param registryAddress - ExagentRegistry contract address
|
|
2635
|
+
* @param agentId - On-chain agent ID
|
|
2636
|
+
* @returns ERC-8004 global agent identifier
|
|
2637
|
+
*/
|
|
2638
|
+
static buildGlobalAgentId(chainId, registryAddress, agentId) {
|
|
2639
|
+
return buildGlobalAgentId(chainId, registryAddress, agentId);
|
|
2640
|
+
}
|
|
2414
2641
|
// ============ Helpers ============
|
|
2415
2642
|
/**
|
|
2416
2643
|
* Get the agent's wallet address
|
|
@@ -2430,10 +2657,7 @@ var ExagentClient = class {
|
|
|
2430
2657
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2431
2658
|
const response = await fetch(`${apiUrl}/v1/metadata/upload`, {
|
|
2432
2659
|
method: "POST",
|
|
2433
|
-
headers:
|
|
2434
|
-
"Content-Type": "application/json",
|
|
2435
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2436
|
-
},
|
|
2660
|
+
headers: this.apiHeaders("application/json"),
|
|
2437
2661
|
body: JSON.stringify(metadata)
|
|
2438
2662
|
});
|
|
2439
2663
|
if (!response.ok) {
|
|
@@ -2442,12 +2666,16 @@ var ExagentClient = class {
|
|
|
2442
2666
|
const result = await response.json();
|
|
2443
2667
|
return result.uri;
|
|
2444
2668
|
}
|
|
2445
|
-
async signIntent(intent) {
|
|
2446
|
-
const message = JSON.stringify(intent);
|
|
2447
|
-
return this.walletClient.signMessage({ account: this.account, message });
|
|
2448
|
-
}
|
|
2449
2669
|
parseAgentIdFromReceipt(receipt) {
|
|
2450
|
-
|
|
2670
|
+
const registryAddress = this.registry.address.toLowerCase();
|
|
2671
|
+
for (const log of receipt.logs) {
|
|
2672
|
+
if (log.address.toLowerCase() !== registryAddress) continue;
|
|
2673
|
+
if (log.topics.length >= 2 && log.topics[1]) {
|
|
2674
|
+
const agentId = BigInt(log.topics[1]);
|
|
2675
|
+
return agentId;
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
throw new Error("AgentRegistered event not found in transaction receipt");
|
|
2451
2679
|
}
|
|
2452
2680
|
};
|
|
2453
2681
|
|
|
@@ -2457,8 +2685,12 @@ var EXAGENT_VAULT_FACTORY_ABI = [
|
|
|
2457
2685
|
{ type: "function", name: "owner", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2458
2686
|
{ type: "function", name: "registry", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2459
2687
|
{ type: "function", name: "router", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2460
|
-
{ type: "function", name: "
|
|
2461
|
-
{ type: "function", name: "
|
|
2688
|
+
{ type: "function", name: "feeCollector", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2689
|
+
{ type: "function", name: "stakingContract", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2690
|
+
{ type: "function", name: "VERIFIED_VEXA_REQUIREMENT", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2691
|
+
{ type: "function", name: "MIN_SEED_AMOUNT", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2692
|
+
{ type: "function", name: "UNVERIFIED_CAP_MULTIPLIER", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2693
|
+
{ type: "function", name: "VERIFIED_CAP_MULTIPLIER", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2462
2694
|
{ type: "function", name: "allowedAssets", inputs: [{ name: "asset", type: "address" }], outputs: [{ type: "bool" }], stateMutability: "view" },
|
|
2463
2695
|
{ type: "function", name: "vaults", inputs: [{ name: "agentId", type: "uint256" }, { name: "asset", type: "address" }], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2464
2696
|
{ type: "function", name: "agentVaultCount", inputs: [{ name: "agentId", type: "uint256" }], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
@@ -2471,14 +2703,9 @@ var EXAGENT_VAULT_FACTORY_ABI = [
|
|
|
2471
2703
|
},
|
|
2472
2704
|
{
|
|
2473
2705
|
type: "function",
|
|
2474
|
-
name: "
|
|
2475
|
-
inputs: [],
|
|
2476
|
-
outputs: [
|
|
2477
|
-
{ name: "veXARequired", type: "uint256" },
|
|
2478
|
-
{ name: "burnFee", type: "uint256" },
|
|
2479
|
-
{ name: "stakingContract", type: "address" },
|
|
2480
|
-
{ name: "exaToken", type: "address" }
|
|
2481
|
-
],
|
|
2706
|
+
name: "canCreateVerifiedVault",
|
|
2707
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
2708
|
+
outputs: [{ name: "isVerified", type: "bool" }, { name: "reason", type: "string" }],
|
|
2482
2709
|
stateMutability: "view"
|
|
2483
2710
|
},
|
|
2484
2711
|
// Write functions
|
|
@@ -2488,6 +2715,7 @@ var EXAGENT_VAULT_FACTORY_ABI = [
|
|
|
2488
2715
|
inputs: [
|
|
2489
2716
|
{ name: "agentId", type: "uint256" },
|
|
2490
2717
|
{ name: "asset", type: "address" },
|
|
2718
|
+
{ name: "seedAmount", type: "uint256" },
|
|
2491
2719
|
{ name: "name", type: "string" },
|
|
2492
2720
|
{ name: "symbol", type: "string" },
|
|
2493
2721
|
{ name: "feeRecipient", type: "address" }
|
|
@@ -2529,50 +2757,51 @@ var ExagentVaultFactory = class {
|
|
|
2529
2757
|
this.address = factoryAddress;
|
|
2530
2758
|
this.publicClient = publicClient;
|
|
2531
2759
|
this.walletClient = walletClient;
|
|
2760
|
+
if (!chain) {
|
|
2761
|
+
throw new Error("Chain parameter is required");
|
|
2762
|
+
}
|
|
2532
2763
|
this.chain = chain;
|
|
2533
2764
|
this.account = account;
|
|
2534
2765
|
}
|
|
2535
2766
|
// ============ Read Functions ============
|
|
2536
2767
|
/**
|
|
2537
|
-
* Get vault creation requirements
|
|
2768
|
+
* Get vault creation requirements (mainnet: seed-based, no burn fee)
|
|
2538
2769
|
*/
|
|
2539
2770
|
async getRequirements() {
|
|
2540
|
-
|
|
2541
|
-
|
|
2771
|
+
const [veXARequired, minSeedAmount, unverifiedCapMultiplier, verifiedCapMultiplier, stakingContract] = await Promise.all([
|
|
2772
|
+
this.publicClient.readContract({
|
|
2542
2773
|
address: this.address,
|
|
2543
2774
|
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2544
|
-
functionName: "
|
|
2545
|
-
})
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
};
|
|
2575
|
-
}
|
|
2775
|
+
functionName: "VERIFIED_VEXA_REQUIREMENT"
|
|
2776
|
+
}),
|
|
2777
|
+
this.publicClient.readContract({
|
|
2778
|
+
address: this.address,
|
|
2779
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2780
|
+
functionName: "MIN_SEED_AMOUNT"
|
|
2781
|
+
}),
|
|
2782
|
+
this.publicClient.readContract({
|
|
2783
|
+
address: this.address,
|
|
2784
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2785
|
+
functionName: "UNVERIFIED_CAP_MULTIPLIER"
|
|
2786
|
+
}),
|
|
2787
|
+
this.publicClient.readContract({
|
|
2788
|
+
address: this.address,
|
|
2789
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2790
|
+
functionName: "VERIFIED_CAP_MULTIPLIER"
|
|
2791
|
+
}),
|
|
2792
|
+
this.publicClient.readContract({
|
|
2793
|
+
address: this.address,
|
|
2794
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2795
|
+
functionName: "stakingContract"
|
|
2796
|
+
})
|
|
2797
|
+
]);
|
|
2798
|
+
return {
|
|
2799
|
+
veXARequired,
|
|
2800
|
+
minSeedAmount,
|
|
2801
|
+
unverifiedCapMultiplier,
|
|
2802
|
+
verifiedCapMultiplier,
|
|
2803
|
+
stakingContract
|
|
2804
|
+
};
|
|
2576
2805
|
}
|
|
2577
2806
|
/**
|
|
2578
2807
|
* Check if an address can create a vault
|
|
@@ -2590,6 +2819,22 @@ var ExagentVaultFactory = class {
|
|
|
2590
2819
|
reason: result[1]
|
|
2591
2820
|
};
|
|
2592
2821
|
}
|
|
2822
|
+
/**
|
|
2823
|
+
* Check if an agent can create a verified vault (higher deposit cap)
|
|
2824
|
+
* @param agentId Agent ID to check
|
|
2825
|
+
*/
|
|
2826
|
+
async canCreateVerifiedVault(agentId) {
|
|
2827
|
+
const result = await this.publicClient.readContract({
|
|
2828
|
+
address: this.address,
|
|
2829
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2830
|
+
functionName: "canCreateVerifiedVault",
|
|
2831
|
+
args: [agentId]
|
|
2832
|
+
});
|
|
2833
|
+
return {
|
|
2834
|
+
isVerified: result[0],
|
|
2835
|
+
reason: result[1]
|
|
2836
|
+
};
|
|
2837
|
+
}
|
|
2593
2838
|
/**
|
|
2594
2839
|
* Check if an asset is whitelisted for vault creation
|
|
2595
2840
|
* @param asset Asset address to check
|
|
@@ -2639,8 +2884,8 @@ var ExagentVaultFactory = class {
|
|
|
2639
2884
|
}
|
|
2640
2885
|
// ============ Write Functions ============
|
|
2641
2886
|
/**
|
|
2642
|
-
* Create a new vault for an agent
|
|
2643
|
-
* @param options Vault creation options
|
|
2887
|
+
* Create a new vault for an agent (mainnet: requires seed amount)
|
|
2888
|
+
* @param options Vault creation options including seedAmount
|
|
2644
2889
|
* @returns Transaction hash
|
|
2645
2890
|
*/
|
|
2646
2891
|
async createVault(options) {
|
|
@@ -2652,7 +2897,7 @@ var ExagentVaultFactory = class {
|
|
|
2652
2897
|
address: this.address,
|
|
2653
2898
|
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2654
2899
|
functionName: "createVault",
|
|
2655
|
-
args: [options.agentId, options.asset, options.name, options.symbol, feeRecipient],
|
|
2900
|
+
args: [options.agentId, options.asset, options.seedAmount, options.name, options.symbol, feeRecipient],
|
|
2656
2901
|
account: this.account,
|
|
2657
2902
|
chain: this.chain
|
|
2658
2903
|
});
|
|
@@ -2663,7 +2908,7 @@ var ExagentVaultFactory = class {
|
|
|
2663
2908
|
* Check all requirements and create a vault if possible
|
|
2664
2909
|
* Returns detailed status about each requirement
|
|
2665
2910
|
*/
|
|
2666
|
-
async checkAndCreateVault(agentId, asset, name, symbol, feeRecipient) {
|
|
2911
|
+
async checkAndCreateVault(agentId, asset, seedAmount, name, symbol, feeRecipient) {
|
|
2667
2912
|
const [canCreateResult, assetAllowed, hasExisting] = await Promise.all([
|
|
2668
2913
|
this.canCreateVault(this.account?.address ?? "0x0000000000000000000000000000000000000000"),
|
|
2669
2914
|
this.isAssetAllowed(asset),
|
|
@@ -2702,6 +2947,7 @@ var ExagentVaultFactory = class {
|
|
|
2702
2947
|
const txHash = await this.createVault({
|
|
2703
2948
|
agentId,
|
|
2704
2949
|
asset,
|
|
2950
|
+
seedAmount,
|
|
2705
2951
|
name,
|
|
2706
2952
|
symbol,
|
|
2707
2953
|
feeRecipient
|
|
@@ -2731,27 +2977,10 @@ var ExagentVaultFactory = class {
|
|
|
2731
2977
|
}
|
|
2732
2978
|
}
|
|
2733
2979
|
};
|
|
2734
|
-
|
|
2735
|
-
// src/index.ts
|
|
2736
|
-
var TESTNET_ADDRESSES = {
|
|
2737
|
-
registry: "0xCF48C341e3FebeCA5ECB7eb2535f61A2Ba855d9C",
|
|
2738
|
-
// V4 UUPS proxy
|
|
2739
|
-
token: "0x66c39b0ad96B3f5eE198Fef913c6636353a48A87",
|
|
2740
|
-
staking: "0x439441468e1b1b616E9D36b80969C241F261A011",
|
|
2741
|
-
router: "0xc0c27eEE047E414CD716D06C2444CF2073113d5C",
|
|
2742
|
-
// V3 with config epochs
|
|
2743
|
-
vaultFactory: "0x5c099daaE33801a907Bb57011c6749655b55dc75",
|
|
2744
|
-
feeCollector: "0xcB57b03a50df054b9C738Df1324C17A4fDe4fe46",
|
|
2745
|
-
buyback: "0x35cdEa810A130A846265682e5c71A68A507aB895",
|
|
2746
|
-
serviceEscrow: "0x74a3496b148DEE735ac388299aF9Ac2F7C4EdCBf",
|
|
2747
|
-
usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
|
|
2748
|
-
// Circle's Base Sepolia USDC (only vault asset)
|
|
2749
|
-
};
|
|
2750
2980
|
export {
|
|
2751
2981
|
CHAIN_CONFIG,
|
|
2752
2982
|
CONTRACT_ADDRESSES,
|
|
2753
2983
|
DEX_ADDRESSES,
|
|
2754
|
-
DISCOUNT_TIERS,
|
|
2755
2984
|
EXAGENT_API_CONFIG,
|
|
2756
2985
|
EXAGENT_STAKING_ABI,
|
|
2757
2986
|
EXAGENT_VAULT_FACTORY_ABI,
|
|
@@ -2760,6 +2989,8 @@ export {
|
|
|
2760
2989
|
ExagentStaking,
|
|
2761
2990
|
ExagentVault,
|
|
2762
2991
|
ExagentVaultFactory,
|
|
2763
|
-
|
|
2764
|
-
ZERO_X_CONFIG
|
|
2992
|
+
SDK_VERSION,
|
|
2993
|
+
ZERO_X_CONFIG,
|
|
2994
|
+
buildGlobalAgentId,
|
|
2995
|
+
parseGlobalAgentId
|
|
2765
2996
|
};
|