@exagent/sdk 0.1.3 → 0.1.4
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 +481 -273
- package/dist/index.d.ts +481 -273
- package/dist/index.js +696 -422
- package/dist/index.mjs +692 -427
- 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([
|
|
1530
1680
|
this.publicClient.readContract({
|
|
1531
1681
|
address: this.address,
|
|
1532
1682
|
abi: EXAGENT_STAKING_ABI,
|
|
1533
|
-
functionName: "
|
|
1683
|
+
functionName: "depositedAmount",
|
|
1684
|
+
args: [user]
|
|
1685
|
+
}),
|
|
1686
|
+
this.publicClient.readContract({
|
|
1687
|
+
address: this.address,
|
|
1688
|
+
abi: EXAGENT_STAKING_ABI,
|
|
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,28 @@ var ExagentStaking = class {
|
|
|
1572
1796
|
});
|
|
1573
1797
|
}
|
|
1574
1798
|
/**
|
|
1575
|
-
* Get
|
|
1799
|
+
* Get effective vEXA (with tier multiplier applied)
|
|
1800
|
+
* @param userAddress Address to check (defaults to connected wallet)
|
|
1801
|
+
* @returns Effective vEXA balance
|
|
1802
|
+
*/
|
|
1803
|
+
async getEffectiveVeEXA(userAddress) {
|
|
1804
|
+
const user = userAddress ?? this.account?.address;
|
|
1805
|
+
if (!user) {
|
|
1806
|
+
throw new Error("User address required");
|
|
1807
|
+
}
|
|
1808
|
+
return this.publicClient.readContract({
|
|
1809
|
+
address: this.address,
|
|
1810
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1811
|
+
functionName: "getEffectiveVeEXA",
|
|
1812
|
+
args: [user]
|
|
1813
|
+
});
|
|
1814
|
+
}
|
|
1815
|
+
/**
|
|
1816
|
+
* Check if user has vault access (meets deposit threshold)
|
|
1576
1817
|
* @param userAddress Address to check (defaults to connected wallet)
|
|
1577
|
-
* @returns
|
|
1818
|
+
* @returns True if user can access vaults
|
|
1578
1819
|
*/
|
|
1579
|
-
async
|
|
1820
|
+
async hasVaultAccess(userAddress) {
|
|
1580
1821
|
const user = userAddress ?? this.account?.address;
|
|
1581
1822
|
if (!user) {
|
|
1582
1823
|
throw new Error("User address required");
|
|
@@ -1584,52 +1825,47 @@ var ExagentStaking = class {
|
|
|
1584
1825
|
return this.publicClient.readContract({
|
|
1585
1826
|
address: this.address,
|
|
1586
1827
|
abi: EXAGENT_STAKING_ABI,
|
|
1587
|
-
functionName: "
|
|
1828
|
+
functionName: "hasVaultAccess",
|
|
1588
1829
|
args: [user]
|
|
1589
1830
|
});
|
|
1590
1831
|
}
|
|
1591
1832
|
/**
|
|
1592
|
-
* Get
|
|
1593
|
-
* @param
|
|
1594
|
-
* @returns
|
|
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
|
|
1595
1836
|
*/
|
|
1596
|
-
async
|
|
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
|
*/
|
|
@@ -1777,25 +2024,28 @@ var ExagentStaking = class {
|
|
|
1777
2024
|
|
|
1778
2025
|
// src/constants.ts
|
|
1779
2026
|
import { base, baseSepolia } from "viem/chains";
|
|
2027
|
+
var SDK_VERSION = "0.1.4";
|
|
1780
2028
|
var CHAIN_CONFIG = {
|
|
1781
2029
|
mainnet: base,
|
|
1782
2030
|
testnet: baseSepolia
|
|
1783
2031
|
};
|
|
1784
2032
|
var CONTRACT_ADDRESSES = {
|
|
1785
2033
|
mainnet: {
|
|
1786
|
-
agentRegistry: "
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
router: "0x0000000000000000000000000000000000000000",
|
|
2034
|
+
agentRegistry: "0x2261706C751F8ac5cdDb481B7b56EA2137d4A723",
|
|
2035
|
+
exaToken: "0x13403Fb738C97cF7564F279288468c140AaEd05c",
|
|
2036
|
+
staking: "0xAF1729D1519A72f7d9b87aa23a305b775e2849DA",
|
|
2037
|
+
router: "0x11daD5366D903a3eF5d8f07EFF87ce6b173859a9",
|
|
1791
2038
|
vaultFactory: "0x0000000000000000000000000000000000000000",
|
|
1792
|
-
|
|
2039
|
+
// Phase 2 — pending deploy
|
|
2040
|
+
feeCollector: "0xe66328a964AF93bEF2eDB226D039C35aE6e66De1",
|
|
1793
2041
|
buyback: "0x0000000000000000000000000000000000000000",
|
|
2042
|
+
// Phase 2 — pending deploy
|
|
1794
2043
|
serviceEscrow: "0x0000000000000000000000000000000000000000"
|
|
2044
|
+
// Phase 2 — pending deploy
|
|
1795
2045
|
},
|
|
1796
2046
|
testnet: {
|
|
1797
2047
|
agentRegistry: "0xCF48C341e3FebeCA5ECB7eb2535f61A2Ba855d9C",
|
|
1798
|
-
//
|
|
2048
|
+
// one-agent-per-wallet
|
|
1799
2049
|
exaToken: "0x66c39b0ad96B3f5eE198Fef913c6636353a48A87",
|
|
1800
2050
|
staking: "0x439441468e1b1b616E9D36b80969C241F261A011",
|
|
1801
2051
|
// V2 with delegation
|
|
@@ -1825,21 +2075,47 @@ var ZERO_X_CONFIG = {
|
|
|
1825
2075
|
// Base
|
|
1826
2076
|
};
|
|
1827
2077
|
var EXAGENT_API_CONFIG = {
|
|
1828
|
-
mainnet: "https://api.
|
|
1829
|
-
testnet: "https://api.
|
|
2078
|
+
mainnet: "https://exagent-api.onrender.com",
|
|
2079
|
+
testnet: "https://exagent-api.onrender.com"
|
|
1830
2080
|
};
|
|
1831
2081
|
var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
2082
|
+
var PHASE_1_CONTRACTS = /* @__PURE__ */ new Set([
|
|
2083
|
+
"agentRegistry",
|
|
2084
|
+
"exaToken",
|
|
2085
|
+
"staking",
|
|
2086
|
+
"router",
|
|
2087
|
+
"feeCollector"
|
|
2088
|
+
]);
|
|
1832
2089
|
function validateContractAddresses(network) {
|
|
1833
2090
|
const addresses = CONTRACT_ADDRESSES[network];
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
2091
|
+
if (network === "mainnet") {
|
|
2092
|
+
const missingPhase1 = Object.entries(addresses).filter(([name, addr]) => PHASE_1_CONTRACTS.has(name) && addr === ZERO_ADDRESS).map(([name]) => name);
|
|
2093
|
+
if (missingPhase1.length > 0) {
|
|
2094
|
+
throw new Error(
|
|
2095
|
+
`Mainnet Phase 1 contracts not deployed. Missing: ${missingPhase1.join(", ")}. Update @exagent/sdk to the latest version.`
|
|
2096
|
+
);
|
|
2097
|
+
}
|
|
1840
2098
|
}
|
|
1841
2099
|
}
|
|
1842
2100
|
|
|
2101
|
+
// src/types.ts
|
|
2102
|
+
function buildGlobalAgentId(chainId, registryAddress, agentId) {
|
|
2103
|
+
return `eip155:${chainId}:${registryAddress}:${Number(agentId)}`;
|
|
2104
|
+
}
|
|
2105
|
+
function parseGlobalAgentId(globalId) {
|
|
2106
|
+
const parts = globalId.split(":");
|
|
2107
|
+
if (parts.length !== 4 || parts[0] !== "eip155") {
|
|
2108
|
+
throw new Error(`Invalid ERC-8004 global agent ID: ${globalId}`);
|
|
2109
|
+
}
|
|
2110
|
+
const chainId = parseInt(parts[1], 10);
|
|
2111
|
+
const registryAddress = parts[2];
|
|
2112
|
+
const agentId = parseInt(parts[3], 10);
|
|
2113
|
+
if (isNaN(chainId) || isNaN(agentId)) {
|
|
2114
|
+
throw new Error(`Invalid ERC-8004 global agent ID: ${globalId}`);
|
|
2115
|
+
}
|
|
2116
|
+
return { chainId, registryAddress, agentId };
|
|
2117
|
+
}
|
|
2118
|
+
|
|
1843
2119
|
// src/client.ts
|
|
1844
2120
|
var ExagentClient = class {
|
|
1845
2121
|
publicClient;
|
|
@@ -1890,6 +2166,14 @@ var ExagentClient = class {
|
|
|
1890
2166
|
this.account
|
|
1891
2167
|
);
|
|
1892
2168
|
}
|
|
2169
|
+
/** Standard headers for all API requests (includes SDK version for gating) */
|
|
2170
|
+
apiHeaders(contentType) {
|
|
2171
|
+
return {
|
|
2172
|
+
...contentType && { "Content-Type": contentType },
|
|
2173
|
+
"X-Exagent-SDK-Version": SDK_VERSION,
|
|
2174
|
+
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2175
|
+
};
|
|
2176
|
+
}
|
|
1893
2177
|
// ============ Agent Registration ============
|
|
1894
2178
|
/**
|
|
1895
2179
|
* Register as a new agent on Exagent
|
|
@@ -1977,127 +2261,15 @@ var ExagentClient = class {
|
|
|
1977
2261
|
}
|
|
1978
2262
|
// ============ Trading ============
|
|
1979
2263
|
/**
|
|
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
|
|
2264
|
+
* Execute a trade through ExagentRouter
|
|
2097
2265
|
*
|
|
2098
|
-
*
|
|
2099
|
-
*
|
|
2100
|
-
*
|
|
2266
|
+
* All trades MUST go through the ExagentRouter. This ensures:
|
|
2267
|
+
* - Trade attribution for leaderboard ranking
|
|
2268
|
+
* - Protocol fee collection (0.2%)
|
|
2269
|
+
* - On-chain performance tracking
|
|
2270
|
+
* - Token whitelist enforcement per risk universe
|
|
2271
|
+
*
|
|
2272
|
+
* There is no way to trade outside the router. This is by design.
|
|
2101
2273
|
*
|
|
2102
2274
|
* @param intent Trade parameters
|
|
2103
2275
|
* @returns Trade result with transaction hash
|
|
@@ -2150,10 +2322,7 @@ var ExagentClient = class {
|
|
|
2150
2322
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2151
2323
|
const response = await fetch(`${apiUrl}/v1/router/trade`, {
|
|
2152
2324
|
method: "POST",
|
|
2153
|
-
headers:
|
|
2154
|
-
"Content-Type": "application/json",
|
|
2155
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2156
|
-
},
|
|
2325
|
+
headers: this.apiHeaders("application/json"),
|
|
2157
2326
|
body: JSON.stringify({
|
|
2158
2327
|
agentId: id.toString(),
|
|
2159
2328
|
tokenIn: intent.tokenIn,
|
|
@@ -2202,10 +2371,7 @@ var ExagentClient = class {
|
|
|
2202
2371
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2203
2372
|
const response = await fetch(`${apiUrl}/v1/services/request`, {
|
|
2204
2373
|
method: "POST",
|
|
2205
|
-
headers:
|
|
2206
|
-
"Content-Type": "application/json",
|
|
2207
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2208
|
-
},
|
|
2374
|
+
headers: this.apiHeaders("application/json"),
|
|
2209
2375
|
body: JSON.stringify({
|
|
2210
2376
|
requesterId: agentId.toString(),
|
|
2211
2377
|
...request
|
|
@@ -2223,7 +2389,9 @@ var ExagentClient = class {
|
|
|
2223
2389
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2224
2390
|
const params = new URLSearchParams();
|
|
2225
2391
|
if (serviceType) params.set("type", serviceType);
|
|
2226
|
-
const response = await fetch(`${apiUrl}/v1/services?${params}
|
|
2392
|
+
const response = await fetch(`${apiUrl}/v1/services?${params}`, {
|
|
2393
|
+
headers: this.apiHeaders()
|
|
2394
|
+
});
|
|
2227
2395
|
return response.json();
|
|
2228
2396
|
}
|
|
2229
2397
|
// ============ Leaderboards ============
|
|
@@ -2236,7 +2404,9 @@ var ExagentClient = class {
|
|
|
2236
2404
|
if (options?.category) params.set("category", options.category);
|
|
2237
2405
|
if (options?.limit) params.set("limit", options.limit.toString());
|
|
2238
2406
|
if (options?.offset) params.set("offset", options.offset.toString());
|
|
2239
|
-
const response = await fetch(`${apiUrl}/v1/rankings/leaderboard?${params}
|
|
2407
|
+
const response = await fetch(`${apiUrl}/v1/rankings/leaderboard?${params}`, {
|
|
2408
|
+
headers: this.apiHeaders()
|
|
2409
|
+
});
|
|
2240
2410
|
return response.json();
|
|
2241
2411
|
}
|
|
2242
2412
|
// ============ Vault Functions (Phase 4: Copy Trading) ============
|
|
@@ -2264,9 +2434,7 @@ var ExagentClient = class {
|
|
|
2264
2434
|
if (!id) throw new Error("Agent not registered");
|
|
2265
2435
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2266
2436
|
const response = await fetch(`${apiUrl}/v1/vaults?agentId=${id}`, {
|
|
2267
|
-
headers:
|
|
2268
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2269
|
-
}
|
|
2437
|
+
headers: this.apiHeaders()
|
|
2270
2438
|
});
|
|
2271
2439
|
if (!response.ok) {
|
|
2272
2440
|
throw new Error(`Failed to get vaults: ${response.statusText}`);
|
|
@@ -2282,9 +2450,7 @@ var ExagentClient = class {
|
|
|
2282
2450
|
const user = userAddress ?? this.account.address;
|
|
2283
2451
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2284
2452
|
const response = await fetch(`${apiUrl}/v1/vaults?depositor=${user}`, {
|
|
2285
|
-
headers:
|
|
2286
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2287
|
-
}
|
|
2453
|
+
headers: this.apiHeaders()
|
|
2288
2454
|
});
|
|
2289
2455
|
if (!response.ok) {
|
|
2290
2456
|
throw new Error(`Failed to get user vaults: ${response.statusText}`);
|
|
@@ -2304,9 +2470,7 @@ var ExagentClient = class {
|
|
|
2304
2470
|
if (options?.period) params.set("period", options.period);
|
|
2305
2471
|
if (options?.limit) params.set("limit", options.limit.toString());
|
|
2306
2472
|
const response = await fetch(`${apiUrl}/v1/vaults/top?${params}`, {
|
|
2307
|
-
headers:
|
|
2308
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2309
|
-
}
|
|
2473
|
+
headers: this.apiHeaders()
|
|
2310
2474
|
});
|
|
2311
2475
|
if (!response.ok) {
|
|
2312
2476
|
throw new Error(`Failed to get top vaults: ${response.statusText}`);
|
|
@@ -2347,37 +2511,73 @@ var ExagentClient = class {
|
|
|
2347
2511
|
}
|
|
2348
2512
|
// ============ Staking Functions ============
|
|
2349
2513
|
/**
|
|
2350
|
-
*
|
|
2351
|
-
* @param amount Amount of EXA to
|
|
2514
|
+
* Deposit EXA tokens for vault access (no lock required)
|
|
2515
|
+
* @param amount Amount of EXA to deposit (in wei)
|
|
2516
|
+
* @returns Transaction hash
|
|
2517
|
+
*
|
|
2518
|
+
* @example
|
|
2519
|
+
* ```typescript
|
|
2520
|
+
* // Deposit 1000 EXA to unlock vault access
|
|
2521
|
+
* const tx = await exagent.depositExa(parseEther('1000'));
|
|
2522
|
+
* ```
|
|
2523
|
+
*/
|
|
2524
|
+
async depositExa(amount) {
|
|
2525
|
+
await this.staking.approveExa(amount);
|
|
2526
|
+
return this.staking.deposit(amount);
|
|
2527
|
+
}
|
|
2528
|
+
/**
|
|
2529
|
+
* Withdraw unlocked EXA tokens (instant, no penalty)
|
|
2530
|
+
* @param amount Amount of EXA to withdraw (in wei)
|
|
2531
|
+
* @returns Transaction hash
|
|
2532
|
+
*/
|
|
2533
|
+
async withdrawExa(amount) {
|
|
2534
|
+
return this.staking.withdraw(amount);
|
|
2535
|
+
}
|
|
2536
|
+
/**
|
|
2537
|
+
* Lock deposited EXA to receive vEXA voting power and earn rewards
|
|
2538
|
+
* @param amount Amount of deposited EXA to lock (in wei)
|
|
2352
2539
|
* @param lockDuration Lock duration in seconds (30 days to 2 years)
|
|
2353
2540
|
* @returns Transaction hash
|
|
2354
2541
|
*
|
|
2355
2542
|
* @example
|
|
2356
2543
|
* ```typescript
|
|
2357
|
-
* //
|
|
2358
|
-
* const tx = await exagent.
|
|
2544
|
+
* // Lock 1000 EXA for 6 months
|
|
2545
|
+
* const tx = await exagent.lockExa(
|
|
2359
2546
|
* parseEther('1000'),
|
|
2360
2547
|
* ExagentStaking.LOCK_6_MONTHS
|
|
2361
2548
|
* );
|
|
2362
2549
|
* ```
|
|
2363
2550
|
*/
|
|
2364
|
-
async
|
|
2365
|
-
|
|
2366
|
-
|
|
2551
|
+
async lockExa(amount, lockDuration) {
|
|
2552
|
+
return this.staking.lock(amount, lockDuration);
|
|
2553
|
+
}
|
|
2554
|
+
/**
|
|
2555
|
+
* Unlock EXA after lock expires (no penalty)
|
|
2556
|
+
* @returns Transaction hash
|
|
2557
|
+
*/
|
|
2558
|
+
async unlockExa() {
|
|
2559
|
+
return this.staking.unlock();
|
|
2367
2560
|
}
|
|
2368
2561
|
/**
|
|
2369
|
-
*
|
|
2562
|
+
* Emergency withdrawal from active lock (graduated 50%→20% penalty)
|
|
2370
2563
|
* @returns Transaction hash
|
|
2371
2564
|
*/
|
|
2372
|
-
async
|
|
2373
|
-
return this.staking.
|
|
2565
|
+
async emergencyWithdrawExa() {
|
|
2566
|
+
return this.staking.emergencyWithdraw();
|
|
2374
2567
|
}
|
|
2375
2568
|
/**
|
|
2376
|
-
* Get staking info for the connected wallet
|
|
2377
|
-
* @returns Staking info including
|
|
2569
|
+
* Get comprehensive staking info (deposit + lock) for the connected wallet
|
|
2570
|
+
* @returns Staking info including deposit status and lock status
|
|
2378
2571
|
*/
|
|
2379
2572
|
async getStakingInfo() {
|
|
2380
|
-
return this.staking.
|
|
2573
|
+
return this.staking.getStakingInfo();
|
|
2574
|
+
}
|
|
2575
|
+
/**
|
|
2576
|
+
* Get deposit info for the connected wallet
|
|
2577
|
+
* @returns Deposit info (deposited, locked, unlocked, vault access)
|
|
2578
|
+
*/
|
|
2579
|
+
async getDepositInfo() {
|
|
2580
|
+
return this.staking.getDepositInfo();
|
|
2381
2581
|
}
|
|
2382
2582
|
/**
|
|
2383
2583
|
* Get current vEXA balance for the connected wallet
|
|
@@ -2387,20 +2587,25 @@ var ExagentClient = class {
|
|
|
2387
2587
|
return this.staking.getVeEXABalance();
|
|
2388
2588
|
}
|
|
2389
2589
|
/**
|
|
2390
|
-
*
|
|
2391
|
-
* @
|
|
2392
|
-
* @returns Transaction hash
|
|
2590
|
+
* Check if connected wallet has vault access (meets deposit threshold)
|
|
2591
|
+
* @returns True if user can access vaults
|
|
2393
2592
|
*/
|
|
2394
|
-
async
|
|
2395
|
-
return this.staking.
|
|
2593
|
+
async hasVaultAccess() {
|
|
2594
|
+
return this.staking.hasVaultAccess();
|
|
2396
2595
|
}
|
|
2397
2596
|
/**
|
|
2398
|
-
* Get
|
|
2399
|
-
* @
|
|
2400
|
-
* @returns Delegation info with total vEXA and delegator count
|
|
2597
|
+
* Get earnings tier for the connected wallet
|
|
2598
|
+
* @returns Tier info with multiplier and name
|
|
2401
2599
|
*/
|
|
2402
|
-
async
|
|
2403
|
-
return this.staking.
|
|
2600
|
+
async getEarningsTier() {
|
|
2601
|
+
return this.staking.getEarningsTier();
|
|
2602
|
+
}
|
|
2603
|
+
/**
|
|
2604
|
+
* Get emergency withdrawal penalty for the connected wallet
|
|
2605
|
+
* @returns Penalty in basis points (5000 = 50% at start, 2000 = 20% near expiry)
|
|
2606
|
+
*/
|
|
2607
|
+
async getEmergencyWithdrawPenalty() {
|
|
2608
|
+
return this.staking.getEmergencyWithdrawPenalty();
|
|
2404
2609
|
}
|
|
2405
2610
|
/**
|
|
2406
2611
|
* Claim all pending staking rewards (EXA + multi-token)
|
|
@@ -2411,6 +2616,46 @@ var ExagentClient = class {
|
|
|
2411
2616
|
const multiTokenRewards = await this.staking.claimRewardsMulti();
|
|
2412
2617
|
return { exaRewards, multiTokenRewards };
|
|
2413
2618
|
}
|
|
2619
|
+
// ============ ERC-8004 Global Agent Identity ============
|
|
2620
|
+
/**
|
|
2621
|
+
* Get the ERC-8004 global agent identifier for the current agent
|
|
2622
|
+
*
|
|
2623
|
+
* Format: eip155:{chainId}:{registryAddress}:{agentId}
|
|
2624
|
+
*
|
|
2625
|
+
* This creates a universally unique identifier that can be used for
|
|
2626
|
+
* cross-protocol agent discovery and interoperability.
|
|
2627
|
+
*
|
|
2628
|
+
* @returns The global agent ID string
|
|
2629
|
+
* @throws Error if agent is not registered
|
|
2630
|
+
*
|
|
2631
|
+
* @example
|
|
2632
|
+
* ```typescript
|
|
2633
|
+
* const globalId = await exagent.getGlobalAgentId();
|
|
2634
|
+
* // => "eip155:8453:0xABC...DEF:42"
|
|
2635
|
+
* ```
|
|
2636
|
+
*/
|
|
2637
|
+
async getGlobalAgentId() {
|
|
2638
|
+
const agentId = await this.getAgentId();
|
|
2639
|
+
if (!agentId) throw new Error("Agent not registered");
|
|
2640
|
+
const chain = CHAIN_CONFIG[this.network];
|
|
2641
|
+
const addresses = CONTRACT_ADDRESSES[this.network];
|
|
2642
|
+
return buildGlobalAgentId(
|
|
2643
|
+
chain.id,
|
|
2644
|
+
addresses.agentRegistry,
|
|
2645
|
+
agentId
|
|
2646
|
+
);
|
|
2647
|
+
}
|
|
2648
|
+
/**
|
|
2649
|
+
* Build a global agent ID for any agent (static utility)
|
|
2650
|
+
*
|
|
2651
|
+
* @param chainId - EVM chain ID
|
|
2652
|
+
* @param registryAddress - ExagentRegistry contract address
|
|
2653
|
+
* @param agentId - On-chain agent ID
|
|
2654
|
+
* @returns ERC-8004 global agent identifier
|
|
2655
|
+
*/
|
|
2656
|
+
static buildGlobalAgentId(chainId, registryAddress, agentId) {
|
|
2657
|
+
return buildGlobalAgentId(chainId, registryAddress, agentId);
|
|
2658
|
+
}
|
|
2414
2659
|
// ============ Helpers ============
|
|
2415
2660
|
/**
|
|
2416
2661
|
* Get the agent's wallet address
|
|
@@ -2430,10 +2675,7 @@ var ExagentClient = class {
|
|
|
2430
2675
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2431
2676
|
const response = await fetch(`${apiUrl}/v1/metadata/upload`, {
|
|
2432
2677
|
method: "POST",
|
|
2433
|
-
headers:
|
|
2434
|
-
"Content-Type": "application/json",
|
|
2435
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2436
|
-
},
|
|
2678
|
+
headers: this.apiHeaders("application/json"),
|
|
2437
2679
|
body: JSON.stringify(metadata)
|
|
2438
2680
|
});
|
|
2439
2681
|
if (!response.ok) {
|
|
@@ -2442,12 +2684,16 @@ var ExagentClient = class {
|
|
|
2442
2684
|
const result = await response.json();
|
|
2443
2685
|
return result.uri;
|
|
2444
2686
|
}
|
|
2445
|
-
async signIntent(intent) {
|
|
2446
|
-
const message = JSON.stringify(intent);
|
|
2447
|
-
return this.walletClient.signMessage({ account: this.account, message });
|
|
2448
|
-
}
|
|
2449
2687
|
parseAgentIdFromReceipt(receipt) {
|
|
2450
|
-
|
|
2688
|
+
const registryAddress = this.registry.address.toLowerCase();
|
|
2689
|
+
for (const log of receipt.logs) {
|
|
2690
|
+
if (log.address.toLowerCase() !== registryAddress) continue;
|
|
2691
|
+
if (log.topics.length >= 2 && log.topics[1]) {
|
|
2692
|
+
const agentId = BigInt(log.topics[1]);
|
|
2693
|
+
return agentId;
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
throw new Error("AgentRegistered event not found in transaction receipt");
|
|
2451
2697
|
}
|
|
2452
2698
|
};
|
|
2453
2699
|
|
|
@@ -2457,8 +2703,12 @@ var EXAGENT_VAULT_FACTORY_ABI = [
|
|
|
2457
2703
|
{ type: "function", name: "owner", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2458
2704
|
{ type: "function", name: "registry", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2459
2705
|
{ type: "function", name: "router", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2460
|
-
{ type: "function", name: "
|
|
2461
|
-
{ type: "function", name: "
|
|
2706
|
+
{ type: "function", name: "feeCollector", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2707
|
+
{ type: "function", name: "stakingContract", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2708
|
+
{ type: "function", name: "VERIFIED_VEXA_REQUIREMENT", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2709
|
+
{ type: "function", name: "MIN_SEED_AMOUNT", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2710
|
+
{ type: "function", name: "UNVERIFIED_CAP_MULTIPLIER", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2711
|
+
{ type: "function", name: "VERIFIED_CAP_MULTIPLIER", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2462
2712
|
{ type: "function", name: "allowedAssets", inputs: [{ name: "asset", type: "address" }], outputs: [{ type: "bool" }], stateMutability: "view" },
|
|
2463
2713
|
{ type: "function", name: "vaults", inputs: [{ name: "agentId", type: "uint256" }, { name: "asset", type: "address" }], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2464
2714
|
{ type: "function", name: "agentVaultCount", inputs: [{ name: "agentId", type: "uint256" }], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
@@ -2471,14 +2721,9 @@ var EXAGENT_VAULT_FACTORY_ABI = [
|
|
|
2471
2721
|
},
|
|
2472
2722
|
{
|
|
2473
2723
|
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
|
-
],
|
|
2724
|
+
name: "canCreateVerifiedVault",
|
|
2725
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
2726
|
+
outputs: [{ name: "isVerified", type: "bool" }, { name: "reason", type: "string" }],
|
|
2482
2727
|
stateMutability: "view"
|
|
2483
2728
|
},
|
|
2484
2729
|
// Write functions
|
|
@@ -2488,6 +2733,7 @@ var EXAGENT_VAULT_FACTORY_ABI = [
|
|
|
2488
2733
|
inputs: [
|
|
2489
2734
|
{ name: "agentId", type: "uint256" },
|
|
2490
2735
|
{ name: "asset", type: "address" },
|
|
2736
|
+
{ name: "seedAmount", type: "uint256" },
|
|
2491
2737
|
{ name: "name", type: "string" },
|
|
2492
2738
|
{ name: "symbol", type: "string" },
|
|
2493
2739
|
{ name: "feeRecipient", type: "address" }
|
|
@@ -2529,50 +2775,51 @@ var ExagentVaultFactory = class {
|
|
|
2529
2775
|
this.address = factoryAddress;
|
|
2530
2776
|
this.publicClient = publicClient;
|
|
2531
2777
|
this.walletClient = walletClient;
|
|
2778
|
+
if (!chain) {
|
|
2779
|
+
throw new Error("Chain parameter is required");
|
|
2780
|
+
}
|
|
2532
2781
|
this.chain = chain;
|
|
2533
2782
|
this.account = account;
|
|
2534
2783
|
}
|
|
2535
2784
|
// ============ Read Functions ============
|
|
2536
2785
|
/**
|
|
2537
|
-
* Get vault creation requirements
|
|
2786
|
+
* Get vault creation requirements (mainnet: seed-based, no burn fee)
|
|
2538
2787
|
*/
|
|
2539
2788
|
async getRequirements() {
|
|
2540
|
-
|
|
2541
|
-
|
|
2789
|
+
const [veXARequired, minSeedAmount, unverifiedCapMultiplier, verifiedCapMultiplier, stakingContract] = await Promise.all([
|
|
2790
|
+
this.publicClient.readContract({
|
|
2542
2791
|
address: this.address,
|
|
2543
2792
|
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
|
-
}
|
|
2793
|
+
functionName: "VERIFIED_VEXA_REQUIREMENT"
|
|
2794
|
+
}),
|
|
2795
|
+
this.publicClient.readContract({
|
|
2796
|
+
address: this.address,
|
|
2797
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2798
|
+
functionName: "MIN_SEED_AMOUNT"
|
|
2799
|
+
}),
|
|
2800
|
+
this.publicClient.readContract({
|
|
2801
|
+
address: this.address,
|
|
2802
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2803
|
+
functionName: "UNVERIFIED_CAP_MULTIPLIER"
|
|
2804
|
+
}),
|
|
2805
|
+
this.publicClient.readContract({
|
|
2806
|
+
address: this.address,
|
|
2807
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2808
|
+
functionName: "VERIFIED_CAP_MULTIPLIER"
|
|
2809
|
+
}),
|
|
2810
|
+
this.publicClient.readContract({
|
|
2811
|
+
address: this.address,
|
|
2812
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2813
|
+
functionName: "stakingContract"
|
|
2814
|
+
})
|
|
2815
|
+
]);
|
|
2816
|
+
return {
|
|
2817
|
+
veXARequired,
|
|
2818
|
+
minSeedAmount,
|
|
2819
|
+
unverifiedCapMultiplier,
|
|
2820
|
+
verifiedCapMultiplier,
|
|
2821
|
+
stakingContract
|
|
2822
|
+
};
|
|
2576
2823
|
}
|
|
2577
2824
|
/**
|
|
2578
2825
|
* Check if an address can create a vault
|
|
@@ -2590,6 +2837,22 @@ var ExagentVaultFactory = class {
|
|
|
2590
2837
|
reason: result[1]
|
|
2591
2838
|
};
|
|
2592
2839
|
}
|
|
2840
|
+
/**
|
|
2841
|
+
* Check if an agent can create a verified vault (higher deposit cap)
|
|
2842
|
+
* @param agentId Agent ID to check
|
|
2843
|
+
*/
|
|
2844
|
+
async canCreateVerifiedVault(agentId) {
|
|
2845
|
+
const result = await this.publicClient.readContract({
|
|
2846
|
+
address: this.address,
|
|
2847
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2848
|
+
functionName: "canCreateVerifiedVault",
|
|
2849
|
+
args: [agentId]
|
|
2850
|
+
});
|
|
2851
|
+
return {
|
|
2852
|
+
isVerified: result[0],
|
|
2853
|
+
reason: result[1]
|
|
2854
|
+
};
|
|
2855
|
+
}
|
|
2593
2856
|
/**
|
|
2594
2857
|
* Check if an asset is whitelisted for vault creation
|
|
2595
2858
|
* @param asset Asset address to check
|
|
@@ -2639,8 +2902,8 @@ var ExagentVaultFactory = class {
|
|
|
2639
2902
|
}
|
|
2640
2903
|
// ============ Write Functions ============
|
|
2641
2904
|
/**
|
|
2642
|
-
* Create a new vault for an agent
|
|
2643
|
-
* @param options Vault creation options
|
|
2905
|
+
* Create a new vault for an agent (mainnet: requires seed amount)
|
|
2906
|
+
* @param options Vault creation options including seedAmount
|
|
2644
2907
|
* @returns Transaction hash
|
|
2645
2908
|
*/
|
|
2646
2909
|
async createVault(options) {
|
|
@@ -2652,7 +2915,7 @@ var ExagentVaultFactory = class {
|
|
|
2652
2915
|
address: this.address,
|
|
2653
2916
|
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2654
2917
|
functionName: "createVault",
|
|
2655
|
-
args: [options.agentId, options.asset, options.name, options.symbol, feeRecipient],
|
|
2918
|
+
args: [options.agentId, options.asset, options.seedAmount, options.name, options.symbol, feeRecipient],
|
|
2656
2919
|
account: this.account,
|
|
2657
2920
|
chain: this.chain
|
|
2658
2921
|
});
|
|
@@ -2663,7 +2926,7 @@ var ExagentVaultFactory = class {
|
|
|
2663
2926
|
* Check all requirements and create a vault if possible
|
|
2664
2927
|
* Returns detailed status about each requirement
|
|
2665
2928
|
*/
|
|
2666
|
-
async checkAndCreateVault(agentId, asset, name, symbol, feeRecipient) {
|
|
2929
|
+
async checkAndCreateVault(agentId, asset, seedAmount, name, symbol, feeRecipient) {
|
|
2667
2930
|
const [canCreateResult, assetAllowed, hasExisting] = await Promise.all([
|
|
2668
2931
|
this.canCreateVault(this.account?.address ?? "0x0000000000000000000000000000000000000000"),
|
|
2669
2932
|
this.isAssetAllowed(asset),
|
|
@@ -2702,6 +2965,7 @@ var ExagentVaultFactory = class {
|
|
|
2702
2965
|
const txHash = await this.createVault({
|
|
2703
2966
|
agentId,
|
|
2704
2967
|
asset,
|
|
2968
|
+
seedAmount,
|
|
2705
2969
|
name,
|
|
2706
2970
|
symbol,
|
|
2707
2971
|
feeRecipient
|
|
@@ -2735,7 +2999,6 @@ var ExagentVaultFactory = class {
|
|
|
2735
2999
|
// src/index.ts
|
|
2736
3000
|
var TESTNET_ADDRESSES = {
|
|
2737
3001
|
registry: "0xCF48C341e3FebeCA5ECB7eb2535f61A2Ba855d9C",
|
|
2738
|
-
// V4 UUPS proxy
|
|
2739
3002
|
token: "0x66c39b0ad96B3f5eE198Fef913c6636353a48A87",
|
|
2740
3003
|
staking: "0x439441468e1b1b616E9D36b80969C241F261A011",
|
|
2741
3004
|
router: "0xc0c27eEE047E414CD716D06C2444CF2073113d5C",
|
|
@@ -2751,7 +3014,6 @@ export {
|
|
|
2751
3014
|
CHAIN_CONFIG,
|
|
2752
3015
|
CONTRACT_ADDRESSES,
|
|
2753
3016
|
DEX_ADDRESSES,
|
|
2754
|
-
DISCOUNT_TIERS,
|
|
2755
3017
|
EXAGENT_API_CONFIG,
|
|
2756
3018
|
EXAGENT_STAKING_ABI,
|
|
2757
3019
|
EXAGENT_VAULT_FACTORY_ABI,
|
|
@@ -2760,6 +3022,9 @@ export {
|
|
|
2760
3022
|
ExagentStaking,
|
|
2761
3023
|
ExagentVault,
|
|
2762
3024
|
ExagentVaultFactory,
|
|
3025
|
+
SDK_VERSION,
|
|
2763
3026
|
TESTNET_ADDRESSES,
|
|
2764
|
-
ZERO_X_CONFIG
|
|
3027
|
+
ZERO_X_CONFIG,
|
|
3028
|
+
buildGlobalAgentId,
|
|
3029
|
+
parseGlobalAgentId
|
|
2765
3030
|
};
|