@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.js
CHANGED
|
@@ -23,7 +23,6 @@ __export(index_exports, {
|
|
|
23
23
|
CHAIN_CONFIG: () => CHAIN_CONFIG,
|
|
24
24
|
CONTRACT_ADDRESSES: () => CONTRACT_ADDRESSES,
|
|
25
25
|
DEX_ADDRESSES: () => DEX_ADDRESSES,
|
|
26
|
-
DISCOUNT_TIERS: () => DISCOUNT_TIERS,
|
|
27
26
|
EXAGENT_API_CONFIG: () => EXAGENT_API_CONFIG,
|
|
28
27
|
EXAGENT_STAKING_ABI: () => EXAGENT_STAKING_ABI,
|
|
29
28
|
EXAGENT_VAULT_FACTORY_ABI: () => EXAGENT_VAULT_FACTORY_ABI,
|
|
@@ -32,8 +31,10 @@ __export(index_exports, {
|
|
|
32
31
|
ExagentStaking: () => ExagentStaking,
|
|
33
32
|
ExagentVault: () => ExagentVault,
|
|
34
33
|
ExagentVaultFactory: () => ExagentVaultFactory,
|
|
35
|
-
|
|
36
|
-
ZERO_X_CONFIG: () => ZERO_X_CONFIG
|
|
34
|
+
SDK_VERSION: () => SDK_VERSION,
|
|
35
|
+
ZERO_X_CONFIG: () => ZERO_X_CONFIG,
|
|
36
|
+
buildGlobalAgentId: () => buildGlobalAgentId,
|
|
37
|
+
parseGlobalAgentId: () => parseGlobalAgentId
|
|
37
38
|
});
|
|
38
39
|
module.exports = __toCommonJS(index_exports);
|
|
39
40
|
|
|
@@ -49,7 +50,10 @@ var EXAGENT_REGISTRY_ABI = [
|
|
|
49
50
|
name: "registerAgent",
|
|
50
51
|
inputs: [
|
|
51
52
|
{ name: "name", type: "string" },
|
|
52
|
-
{ name: "metadataURI", type: "string" }
|
|
53
|
+
{ name: "metadataURI", type: "string" },
|
|
54
|
+
{ name: "riskUniverse", type: "uint8" },
|
|
55
|
+
{ name: "maxPositionSizeBps", type: "uint256" },
|
|
56
|
+
{ name: "maxDailyLossBps", type: "uint256" }
|
|
53
57
|
],
|
|
54
58
|
outputs: [{ name: "agentId", type: "uint256" }],
|
|
55
59
|
stateMutability: "nonpayable"
|
|
@@ -279,6 +283,62 @@ var EXAGENT_REGISTRY_ABI = [
|
|
|
279
283
|
outputs: [{ name: "", type: "bytes32" }],
|
|
280
284
|
stateMutability: "view"
|
|
281
285
|
},
|
|
286
|
+
// Mainnet: Agent retirement
|
|
287
|
+
{
|
|
288
|
+
type: "function",
|
|
289
|
+
name: "retireAgent",
|
|
290
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
291
|
+
outputs: [],
|
|
292
|
+
stateMutability: "nonpayable"
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
type: "function",
|
|
296
|
+
name: "retired",
|
|
297
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
298
|
+
outputs: [{ type: "bool" }],
|
|
299
|
+
stateMutability: "view"
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
type: "function",
|
|
303
|
+
name: "isRetired",
|
|
304
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
305
|
+
outputs: [{ type: "bool" }],
|
|
306
|
+
stateMutability: "view"
|
|
307
|
+
},
|
|
308
|
+
// Mainnet: Risk universe token whitelists
|
|
309
|
+
{
|
|
310
|
+
type: "function",
|
|
311
|
+
name: "isTradeAllowed",
|
|
312
|
+
inputs: [
|
|
313
|
+
{ name: "agentId", type: "uint256" },
|
|
314
|
+
{ name: "token", type: "address" },
|
|
315
|
+
{ name: "aggregator", type: "address" }
|
|
316
|
+
],
|
|
317
|
+
outputs: [{ type: "bool" }],
|
|
318
|
+
stateMutability: "view"
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
type: "function",
|
|
322
|
+
name: "getRiskUniverse",
|
|
323
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
324
|
+
outputs: [{ type: "uint8" }],
|
|
325
|
+
stateMutability: "view"
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
type: "function",
|
|
329
|
+
name: "tradeCount",
|
|
330
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
331
|
+
outputs: [{ type: "uint256" }],
|
|
332
|
+
stateMutability: "view"
|
|
333
|
+
},
|
|
334
|
+
// Events
|
|
335
|
+
{
|
|
336
|
+
type: "event",
|
|
337
|
+
name: "AgentRetired",
|
|
338
|
+
inputs: [
|
|
339
|
+
{ name: "agentId", type: "uint256", indexed: true }
|
|
340
|
+
]
|
|
341
|
+
},
|
|
282
342
|
{
|
|
283
343
|
type: "event",
|
|
284
344
|
name: "ConfigUpdated",
|
|
@@ -289,7 +349,16 @@ var EXAGENT_REGISTRY_ABI = [
|
|
|
289
349
|
{ name: "epochId", type: "uint256", indexed: false },
|
|
290
350
|
{ name: "blockNumber", type: "uint256", indexed: false }
|
|
291
351
|
]
|
|
292
|
-
}
|
|
352
|
+
},
|
|
353
|
+
// Custom errors
|
|
354
|
+
{ type: "error", name: "OwnerAlreadyHasAgent", inputs: [{ name: "existingAgentId", type: "uint256" }] },
|
|
355
|
+
{ type: "error", name: "InvalidMetadataURI", inputs: [] },
|
|
356
|
+
{ type: "error", name: "InvalidName", inputs: [] },
|
|
357
|
+
{ type: "error", name: "InvalidRiskUniverse", inputs: [] },
|
|
358
|
+
{ type: "error", name: "InvalidTradingConfig", inputs: [] },
|
|
359
|
+
{ type: "error", name: "NameAlreadyTaken", inputs: [] },
|
|
360
|
+
{ type: "error", name: "AgentNotOwner", inputs: [] },
|
|
361
|
+
{ type: "error", name: "AgentIsRetired", inputs: [] }
|
|
293
362
|
];
|
|
294
363
|
var ExagentRegistry = class {
|
|
295
364
|
address;
|
|
@@ -310,9 +379,12 @@ var ExagentRegistry = class {
|
|
|
310
379
|
* Register a new agent
|
|
311
380
|
* @param name Unique agent name (3-32 chars, alphanumeric + spaces/hyphens/underscores)
|
|
312
381
|
* @param metadataURI IPFS URI for agent metadata
|
|
382
|
+
* @param riskUniverse Risk tier: 0=Core, 1=Established, 2=Derivatives, 3=Emerging, 4=Frontier
|
|
383
|
+
* @param maxPositionSizeBps Maximum position size in basis points (1-10000)
|
|
384
|
+
* @param maxDailyLossBps Maximum daily loss in basis points (1-10000)
|
|
313
385
|
* @returns Transaction hash
|
|
314
386
|
*/
|
|
315
|
-
async register(name, metadataURI) {
|
|
387
|
+
async register(name, metadataURI, riskUniverse = 1, maxPositionSizeBps = 1000n, maxDailyLossBps = 500n) {
|
|
316
388
|
if (!this.walletClient || !this.account) throw new Error("Wallet client and account required for write operations");
|
|
317
389
|
const hash = await this.walletClient.writeContract({
|
|
318
390
|
account: this.account,
|
|
@@ -320,7 +392,7 @@ var ExagentRegistry = class {
|
|
|
320
392
|
address: this.address,
|
|
321
393
|
abi: EXAGENT_REGISTRY_ABI,
|
|
322
394
|
functionName: "registerAgent",
|
|
323
|
-
args: [name, metadataURI]
|
|
395
|
+
args: [name, metadataURI, riskUniverse, maxPositionSizeBps, maxDailyLossBps]
|
|
324
396
|
});
|
|
325
397
|
return hash;
|
|
326
398
|
}
|
|
@@ -655,8 +727,84 @@ var ExagentRegistry = class {
|
|
|
655
727
|
* @returns keccak256 hash of the config
|
|
656
728
|
*/
|
|
657
729
|
static calculateConfigHash(provider, model) {
|
|
658
|
-
|
|
659
|
-
|
|
730
|
+
return (0, import_viem.keccak256)((0, import_viem.encodePacked)(["string", "string"], [provider, model]));
|
|
731
|
+
}
|
|
732
|
+
// ============ Agent Retirement ============
|
|
733
|
+
/**
|
|
734
|
+
* Retire an agent — marks it as retired, unlinks all wallets, allows new agent registration
|
|
735
|
+
* @param agentId The agent's ID
|
|
736
|
+
* @returns Transaction hash
|
|
737
|
+
*/
|
|
738
|
+
async retireAgent(agentId) {
|
|
739
|
+
if (!this.walletClient || !this.account) throw new Error("Wallet client and account required for write operations");
|
|
740
|
+
const hash = await this.walletClient.writeContract({
|
|
741
|
+
account: this.account,
|
|
742
|
+
chain: this.chain,
|
|
743
|
+
address: this.address,
|
|
744
|
+
abi: EXAGENT_REGISTRY_ABI,
|
|
745
|
+
functionName: "retireAgent",
|
|
746
|
+
args: [agentId]
|
|
747
|
+
});
|
|
748
|
+
return hash;
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Check if an agent is retired
|
|
752
|
+
* @param agentId The agent's ID
|
|
753
|
+
* @returns True if agent is retired
|
|
754
|
+
*/
|
|
755
|
+
async isRetired(agentId) {
|
|
756
|
+
const result = await this.publicClient.readContract({
|
|
757
|
+
address: this.address,
|
|
758
|
+
abi: EXAGENT_REGISTRY_ABI,
|
|
759
|
+
functionName: "isRetired",
|
|
760
|
+
args: [agentId]
|
|
761
|
+
});
|
|
762
|
+
return result;
|
|
763
|
+
}
|
|
764
|
+
// ============ Risk Universe Token Eligibility ============
|
|
765
|
+
/**
|
|
766
|
+
* Check if a token trade is allowed for an agent's risk universe
|
|
767
|
+
* @param agentId The agent's ID
|
|
768
|
+
* @param token The token address to check
|
|
769
|
+
* @param aggregator The aggregator being used (for trusted aggregator bypass)
|
|
770
|
+
* @returns True if the trade is allowed
|
|
771
|
+
*/
|
|
772
|
+
async isTradeAllowed(agentId, token, aggregator) {
|
|
773
|
+
const result = await this.publicClient.readContract({
|
|
774
|
+
address: this.address,
|
|
775
|
+
abi: EXAGENT_REGISTRY_ABI,
|
|
776
|
+
functionName: "isTradeAllowed",
|
|
777
|
+
args: [agentId, token, aggregator]
|
|
778
|
+
});
|
|
779
|
+
return result;
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* Get the risk universe for an agent
|
|
783
|
+
* @param agentId The agent's ID
|
|
784
|
+
* @returns Risk universe (0=Core, 1=Established, 2=Derivatives, 3=Emerging, 4=Frontier)
|
|
785
|
+
*/
|
|
786
|
+
async getRiskUniverse(agentId) {
|
|
787
|
+
const result = await this.publicClient.readContract({
|
|
788
|
+
address: this.address,
|
|
789
|
+
abi: EXAGENT_REGISTRY_ABI,
|
|
790
|
+
functionName: "getRiskUniverse",
|
|
791
|
+
args: [agentId]
|
|
792
|
+
});
|
|
793
|
+
return Number(result);
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Get trade count for an agent
|
|
797
|
+
* @param agentId The agent's ID
|
|
798
|
+
* @returns Number of recorded trades
|
|
799
|
+
*/
|
|
800
|
+
async getTradeCount(agentId) {
|
|
801
|
+
const result = await this.publicClient.readContract({
|
|
802
|
+
address: this.address,
|
|
803
|
+
abi: EXAGENT_REGISTRY_ABI,
|
|
804
|
+
functionName: "tradeCount",
|
|
805
|
+
args: [agentId]
|
|
806
|
+
});
|
|
807
|
+
return result;
|
|
660
808
|
}
|
|
661
809
|
};
|
|
662
810
|
|
|
@@ -747,6 +895,9 @@ var ExagentVault = class {
|
|
|
747
895
|
this.address = vaultAddress;
|
|
748
896
|
this.publicClient = publicClient;
|
|
749
897
|
this.walletClient = walletClient;
|
|
898
|
+
if (!chain) {
|
|
899
|
+
throw new Error("Chain parameter is required");
|
|
900
|
+
}
|
|
750
901
|
this.chain = chain;
|
|
751
902
|
this.account = account;
|
|
752
903
|
}
|
|
@@ -1093,17 +1244,34 @@ var ExagentVault = class {
|
|
|
1093
1244
|
var EXAGENT_STAKING_ABI = [
|
|
1094
1245
|
// ============ State Variables ============
|
|
1095
1246
|
{ type: "function", name: "exaToken", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
1096
|
-
{ type: "function", name: "
|
|
1247
|
+
{ type: "function", name: "totalDeposited", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1248
|
+
{ type: "function", name: "totalLocked", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1097
1249
|
{ type: "function", name: "totalVeEXA", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1098
|
-
{ type: "function", name: "
|
|
1250
|
+
{ type: "function", name: "totalEffectiveVeEXA", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1099
1251
|
// ============ Constants ============
|
|
1100
1252
|
{ type: "function", name: "MIN_LOCK_DURATION", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1101
1253
|
{ type: "function", name: "MAX_LOCK_DURATION", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1254
|
+
{ type: "function", name: "VAULT_ACCESS_THRESHOLD", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1102
1255
|
{ type: "function", name: "PRECISION", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
1103
|
-
// ============
|
|
1256
|
+
// ============ Phase 1: Deposit / Withdraw ============
|
|
1257
|
+
{
|
|
1258
|
+
type: "function",
|
|
1259
|
+
name: "deposit",
|
|
1260
|
+
inputs: [{ name: "amount", type: "uint256" }],
|
|
1261
|
+
outputs: [],
|
|
1262
|
+
stateMutability: "nonpayable"
|
|
1263
|
+
},
|
|
1264
|
+
{
|
|
1265
|
+
type: "function",
|
|
1266
|
+
name: "withdraw",
|
|
1267
|
+
inputs: [{ name: "amount", type: "uint256" }],
|
|
1268
|
+
outputs: [],
|
|
1269
|
+
stateMutability: "nonpayable"
|
|
1270
|
+
},
|
|
1271
|
+
// ============ Phase 2: Lock / Unlock ============
|
|
1104
1272
|
{
|
|
1105
1273
|
type: "function",
|
|
1106
|
-
name: "
|
|
1274
|
+
name: "lock",
|
|
1107
1275
|
inputs: [
|
|
1108
1276
|
{ name: "amount", type: "uint256" },
|
|
1109
1277
|
{ name: "lockDuration", type: "uint256" }
|
|
@@ -1111,7 +1279,6 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1111
1279
|
outputs: [],
|
|
1112
1280
|
stateMutability: "nonpayable"
|
|
1113
1281
|
},
|
|
1114
|
-
{ type: "function", name: "unstake", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1115
1282
|
{
|
|
1116
1283
|
type: "function",
|
|
1117
1284
|
name: "extendLock",
|
|
@@ -1119,6 +1286,8 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1119
1286
|
outputs: [],
|
|
1120
1287
|
stateMutability: "nonpayable"
|
|
1121
1288
|
},
|
|
1289
|
+
{ type: "function", name: "unlock", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1290
|
+
{ type: "function", name: "emergencyWithdraw", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1122
1291
|
// ============ Reward Functions ============
|
|
1123
1292
|
{ type: "function", name: "claimRewards", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1124
1293
|
{ type: "function", name: "claimRewardsMulti", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
@@ -1129,26 +1298,17 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1129
1298
|
outputs: [],
|
|
1130
1299
|
stateMutability: "nonpayable"
|
|
1131
1300
|
},
|
|
1132
|
-
// ============
|
|
1133
|
-
{
|
|
1134
|
-
type: "function",
|
|
1135
|
-
name: "delegate",
|
|
1136
|
-
inputs: [{ name: "agentId", type: "uint256" }],
|
|
1137
|
-
outputs: [],
|
|
1138
|
-
stateMutability: "nonpayable"
|
|
1139
|
-
},
|
|
1140
|
-
{ type: "function", name: "undelegate", inputs: [], outputs: [], stateMutability: "nonpayable" },
|
|
1301
|
+
// ============ View Functions ============
|
|
1141
1302
|
{
|
|
1142
1303
|
type: "function",
|
|
1143
|
-
name: "
|
|
1144
|
-
inputs: [{ name: "
|
|
1145
|
-
outputs: [],
|
|
1146
|
-
stateMutability: "
|
|
1304
|
+
name: "depositedAmount",
|
|
1305
|
+
inputs: [{ name: "user", type: "address" }],
|
|
1306
|
+
outputs: [{ type: "uint256" }],
|
|
1307
|
+
stateMutability: "view"
|
|
1147
1308
|
},
|
|
1148
|
-
// ============ View Functions ============
|
|
1149
1309
|
{
|
|
1150
1310
|
type: "function",
|
|
1151
|
-
name: "
|
|
1311
|
+
name: "locks",
|
|
1152
1312
|
inputs: [{ name: "user", type: "address" }],
|
|
1153
1313
|
outputs: [
|
|
1154
1314
|
{ name: "amount", type: "uint256" },
|
|
@@ -1165,6 +1325,13 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1165
1325
|
outputs: [{ type: "uint256" }],
|
|
1166
1326
|
stateMutability: "view"
|
|
1167
1327
|
},
|
|
1328
|
+
{
|
|
1329
|
+
type: "function",
|
|
1330
|
+
name: "getEffectiveVeEXA",
|
|
1331
|
+
inputs: [{ name: "user", type: "address" }],
|
|
1332
|
+
outputs: [{ type: "uint256" }],
|
|
1333
|
+
stateMutability: "view"
|
|
1334
|
+
},
|
|
1168
1335
|
{
|
|
1169
1336
|
type: "function",
|
|
1170
1337
|
name: "calculateVeEXA",
|
|
@@ -1194,61 +1361,40 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1194
1361
|
},
|
|
1195
1362
|
{
|
|
1196
1363
|
type: "function",
|
|
1197
|
-
name: "
|
|
1364
|
+
name: "getEarningsTier",
|
|
1198
1365
|
inputs: [{ name: "user", type: "address" }],
|
|
1199
|
-
outputs: [{ type: "uint256" }],
|
|
1200
|
-
stateMutability: "view"
|
|
1201
|
-
},
|
|
1202
|
-
{
|
|
1203
|
-
type: "function",
|
|
1204
|
-
name: "getAgentDelegation",
|
|
1205
|
-
inputs: [{ name: "agentId", type: "uint256" }],
|
|
1206
1366
|
outputs: [
|
|
1207
|
-
{ name: "
|
|
1208
|
-
{ name: "
|
|
1367
|
+
{ name: "multiplierBps", type: "uint256" },
|
|
1368
|
+
{ name: "tierName", type: "string" }
|
|
1209
1369
|
],
|
|
1210
1370
|
stateMutability: "view"
|
|
1211
1371
|
},
|
|
1212
1372
|
{
|
|
1213
1373
|
type: "function",
|
|
1214
|
-
name: "
|
|
1374
|
+
name: "getEmergencyWithdrawPenalty",
|
|
1215
1375
|
inputs: [{ name: "user", type: "address" }],
|
|
1216
|
-
outputs: [{ name: "
|
|
1217
|
-
stateMutability: "view"
|
|
1218
|
-
},
|
|
1219
|
-
{
|
|
1220
|
-
type: "function",
|
|
1221
|
-
name: "getRewardTokens",
|
|
1222
|
-
inputs: [],
|
|
1223
|
-
outputs: [{ type: "address[]" }],
|
|
1376
|
+
outputs: [{ name: "penaltyBps", type: "uint256" }],
|
|
1224
1377
|
stateMutability: "view"
|
|
1225
1378
|
},
|
|
1226
1379
|
{
|
|
1227
1380
|
type: "function",
|
|
1228
|
-
name: "
|
|
1381
|
+
name: "hasVaultAccess",
|
|
1229
1382
|
inputs: [{ name: "user", type: "address" }],
|
|
1230
|
-
outputs: [{ type: "
|
|
1383
|
+
outputs: [{ type: "bool" }],
|
|
1231
1384
|
stateMutability: "view"
|
|
1232
1385
|
},
|
|
1233
1386
|
{
|
|
1234
1387
|
type: "function",
|
|
1235
|
-
name: "
|
|
1388
|
+
name: "getUnlockedBalance",
|
|
1236
1389
|
inputs: [{ name: "user", type: "address" }],
|
|
1237
1390
|
outputs: [{ type: "uint256" }],
|
|
1238
1391
|
stateMutability: "view"
|
|
1239
1392
|
},
|
|
1240
1393
|
{
|
|
1241
1394
|
type: "function",
|
|
1242
|
-
name: "
|
|
1243
|
-
inputs: [
|
|
1244
|
-
outputs: [{ type: "
|
|
1245
|
-
stateMutability: "view"
|
|
1246
|
-
},
|
|
1247
|
-
{
|
|
1248
|
-
type: "function",
|
|
1249
|
-
name: "agentDelegatorCount",
|
|
1250
|
-
inputs: [{ name: "agentId", type: "uint256" }],
|
|
1251
|
-
outputs: [{ type: "uint256" }],
|
|
1395
|
+
name: "getRewardTokens",
|
|
1396
|
+
inputs: [],
|
|
1397
|
+
outputs: [{ type: "address[]" }],
|
|
1252
1398
|
stateMutability: "view"
|
|
1253
1399
|
},
|
|
1254
1400
|
{
|
|
@@ -1261,35 +1407,36 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1261
1407
|
// ============ Events ============
|
|
1262
1408
|
{
|
|
1263
1409
|
type: "event",
|
|
1264
|
-
name: "
|
|
1410
|
+
name: "Deposited",
|
|
1265
1411
|
inputs: [
|
|
1266
1412
|
{ name: "user", type: "address", indexed: true },
|
|
1267
1413
|
{ name: "amount", type: "uint256", indexed: false },
|
|
1268
|
-
{ name: "
|
|
1269
|
-
{ name: "unlockTime", type: "uint256", indexed: false },
|
|
1270
|
-
{ name: "vEXABalance", type: "uint256", indexed: false }
|
|
1414
|
+
{ name: "totalDeposited", type: "uint256", indexed: false }
|
|
1271
1415
|
]
|
|
1272
1416
|
},
|
|
1273
1417
|
{
|
|
1274
1418
|
type: "event",
|
|
1275
|
-
name: "
|
|
1419
|
+
name: "Withdrawn",
|
|
1276
1420
|
inputs: [
|
|
1277
1421
|
{ name: "user", type: "address", indexed: true },
|
|
1278
|
-
{ name: "amount", type: "uint256", indexed: false }
|
|
1422
|
+
{ name: "amount", type: "uint256", indexed: false },
|
|
1423
|
+
{ name: "totalDeposited", type: "uint256", indexed: false }
|
|
1279
1424
|
]
|
|
1280
1425
|
},
|
|
1281
1426
|
{
|
|
1282
1427
|
type: "event",
|
|
1283
|
-
name: "
|
|
1428
|
+
name: "Locked",
|
|
1284
1429
|
inputs: [
|
|
1285
1430
|
{ name: "user", type: "address", indexed: true },
|
|
1286
|
-
{ name: "
|
|
1287
|
-
{ name: "
|
|
1431
|
+
{ name: "amount", type: "uint256", indexed: false },
|
|
1432
|
+
{ name: "lockDuration", type: "uint256", indexed: false },
|
|
1433
|
+
{ name: "unlockTime", type: "uint256", indexed: false },
|
|
1434
|
+
{ name: "vEXABalance", type: "uint256", indexed: false }
|
|
1288
1435
|
]
|
|
1289
1436
|
},
|
|
1290
1437
|
{
|
|
1291
1438
|
type: "event",
|
|
1292
|
-
name: "
|
|
1439
|
+
name: "Unlocked",
|
|
1293
1440
|
inputs: [
|
|
1294
1441
|
{ name: "user", type: "address", indexed: true },
|
|
1295
1442
|
{ name: "amount", type: "uint256", indexed: false }
|
|
@@ -1297,20 +1444,29 @@ var EXAGENT_STAKING_ABI = [
|
|
|
1297
1444
|
},
|
|
1298
1445
|
{
|
|
1299
1446
|
type: "event",
|
|
1300
|
-
name: "
|
|
1447
|
+
name: "EmergencyWithdrawal",
|
|
1301
1448
|
inputs: [
|
|
1302
|
-
{ name: "
|
|
1303
|
-
{ name: "
|
|
1304
|
-
{ name: "
|
|
1449
|
+
{ name: "user", type: "address", indexed: true },
|
|
1450
|
+
{ name: "returned", type: "uint256", indexed: false },
|
|
1451
|
+
{ name: "penalty", type: "uint256", indexed: false },
|
|
1452
|
+
{ name: "penaltyBps", type: "uint256", indexed: false }
|
|
1305
1453
|
]
|
|
1306
1454
|
},
|
|
1307
1455
|
{
|
|
1308
1456
|
type: "event",
|
|
1309
|
-
name: "
|
|
1457
|
+
name: "LockExtended",
|
|
1310
1458
|
inputs: [
|
|
1311
|
-
{ name: "
|
|
1312
|
-
{ name: "
|
|
1313
|
-
{ name: "
|
|
1459
|
+
{ name: "user", type: "address", indexed: true },
|
|
1460
|
+
{ name: "newUnlockTime", type: "uint256", indexed: false },
|
|
1461
|
+
{ name: "newVeEXABalance", type: "uint256", indexed: false }
|
|
1462
|
+
]
|
|
1463
|
+
},
|
|
1464
|
+
{
|
|
1465
|
+
type: "event",
|
|
1466
|
+
name: "RewardsClaimed",
|
|
1467
|
+
inputs: [
|
|
1468
|
+
{ name: "user", type: "address", indexed: true },
|
|
1469
|
+
{ name: "amount", type: "uint256", indexed: false }
|
|
1314
1470
|
]
|
|
1315
1471
|
},
|
|
1316
1472
|
{
|
|
@@ -1335,15 +1491,6 @@ var ERC20_APPROVE_ABI2 = [
|
|
|
1335
1491
|
stateMutability: "nonpayable"
|
|
1336
1492
|
}
|
|
1337
1493
|
];
|
|
1338
|
-
var DISCOUNT_TIERS = {
|
|
1339
|
-
none: 0,
|
|
1340
|
-
bronze: 1e3,
|
|
1341
|
-
// 10% discount at 10,000 vEXA
|
|
1342
|
-
silver: 2500,
|
|
1343
|
-
// 25% discount at 50,000 vEXA
|
|
1344
|
-
gold: 5e3
|
|
1345
|
-
// 50% discount at 100,000 vEXA
|
|
1346
|
-
};
|
|
1347
1494
|
var ExagentStaking = class {
|
|
1348
1495
|
address;
|
|
1349
1496
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -1356,108 +1503,119 @@ var ExagentStaking = class {
|
|
|
1356
1503
|
this.address = stakingAddress;
|
|
1357
1504
|
this.publicClient = publicClient;
|
|
1358
1505
|
this.walletClient = walletClient;
|
|
1506
|
+
if (!chain) {
|
|
1507
|
+
throw new Error("Chain parameter is required");
|
|
1508
|
+
}
|
|
1359
1509
|
this.chain = chain;
|
|
1360
1510
|
this.account = account;
|
|
1361
1511
|
}
|
|
1362
|
-
// ============
|
|
1512
|
+
// ============ Phase 1: Deposit / Withdraw ============
|
|
1363
1513
|
/**
|
|
1364
|
-
*
|
|
1365
|
-
* @param amount Amount of EXA to
|
|
1366
|
-
* @param lockDuration Lock duration in seconds (30 days to 2 years)
|
|
1514
|
+
* Deposit EXA tokens for vault access (no lock required)
|
|
1515
|
+
* @param amount Amount of EXA to deposit (in wei)
|
|
1367
1516
|
* @returns Transaction hash
|
|
1368
1517
|
*
|
|
1369
1518
|
* @example
|
|
1370
1519
|
* ```typescript
|
|
1371
|
-
* //
|
|
1372
|
-
* const tx = await staking.
|
|
1373
|
-
* parseEther('1000'),
|
|
1374
|
-
* BigInt(180 * 24 * 60 * 60) // 180 days in seconds
|
|
1375
|
-
* );
|
|
1520
|
+
* // Deposit 1000 EXA to unlock vault access
|
|
1521
|
+
* const tx = await staking.deposit(parseEther('1000'));
|
|
1376
1522
|
* ```
|
|
1377
1523
|
*/
|
|
1378
|
-
async
|
|
1524
|
+
async deposit(amount) {
|
|
1379
1525
|
if (!this.walletClient || !this.account) {
|
|
1380
1526
|
throw new Error("Wallet client required for write operations");
|
|
1381
1527
|
}
|
|
1382
1528
|
const hash = await this.walletClient.writeContract({
|
|
1383
1529
|
address: this.address,
|
|
1384
1530
|
abi: EXAGENT_STAKING_ABI,
|
|
1385
|
-
functionName: "
|
|
1386
|
-
args: [amount
|
|
1531
|
+
functionName: "deposit",
|
|
1532
|
+
args: [amount],
|
|
1387
1533
|
account: this.account,
|
|
1388
1534
|
chain: this.chain
|
|
1389
1535
|
});
|
|
1390
1536
|
return hash;
|
|
1391
1537
|
}
|
|
1392
1538
|
/**
|
|
1393
|
-
*
|
|
1539
|
+
* Withdraw unlocked EXA tokens (instant, no penalty)
|
|
1540
|
+
* @param amount Amount of EXA to withdraw (in wei)
|
|
1394
1541
|
* @returns Transaction hash
|
|
1395
|
-
* @throws Error if lock has not expired
|
|
1396
1542
|
*/
|
|
1397
|
-
async
|
|
1543
|
+
async withdraw(amount) {
|
|
1398
1544
|
if (!this.walletClient || !this.account) {
|
|
1399
1545
|
throw new Error("Wallet client required for write operations");
|
|
1400
1546
|
}
|
|
1401
1547
|
const hash = await this.walletClient.writeContract({
|
|
1402
1548
|
address: this.address,
|
|
1403
1549
|
abi: EXAGENT_STAKING_ABI,
|
|
1404
|
-
functionName: "
|
|
1405
|
-
args: [],
|
|
1550
|
+
functionName: "withdraw",
|
|
1551
|
+
args: [amount],
|
|
1406
1552
|
account: this.account,
|
|
1407
1553
|
chain: this.chain
|
|
1408
1554
|
});
|
|
1409
1555
|
return hash;
|
|
1410
1556
|
}
|
|
1557
|
+
// ============ Phase 2: Lock / Unlock ============
|
|
1411
1558
|
/**
|
|
1412
|
-
*
|
|
1413
|
-
* @param
|
|
1559
|
+
* Lock deposited EXA to receive vEXA voting power and earn rewards
|
|
1560
|
+
* @param amount Amount of deposited EXA to lock (in wei)
|
|
1561
|
+
* @param lockDuration Lock duration in seconds (30 days to 2 years)
|
|
1414
1562
|
* @returns Transaction hash
|
|
1563
|
+
*
|
|
1564
|
+
* @example
|
|
1565
|
+
* ```typescript
|
|
1566
|
+
* // Lock 1000 EXA for 6 months
|
|
1567
|
+
* const tx = await staking.lock(
|
|
1568
|
+
* parseEther('1000'),
|
|
1569
|
+
* ExagentStaking.LOCK_6_MONTHS
|
|
1570
|
+
* );
|
|
1571
|
+
* ```
|
|
1415
1572
|
*/
|
|
1416
|
-
async
|
|
1573
|
+
async lock(amount, lockDuration) {
|
|
1417
1574
|
if (!this.walletClient || !this.account) {
|
|
1418
1575
|
throw new Error("Wallet client required for write operations");
|
|
1419
1576
|
}
|
|
1420
1577
|
const hash = await this.walletClient.writeContract({
|
|
1421
1578
|
address: this.address,
|
|
1422
1579
|
abi: EXAGENT_STAKING_ABI,
|
|
1423
|
-
functionName: "
|
|
1424
|
-
args: [
|
|
1580
|
+
functionName: "lock",
|
|
1581
|
+
args: [amount, lockDuration],
|
|
1425
1582
|
account: this.account,
|
|
1426
1583
|
chain: this.chain
|
|
1427
1584
|
});
|
|
1428
1585
|
return hash;
|
|
1429
1586
|
}
|
|
1430
|
-
// ============ Reward Write Functions ============
|
|
1431
1587
|
/**
|
|
1432
|
-
*
|
|
1588
|
+
* Extend lock duration for additional voting power
|
|
1589
|
+
* @param newLockDuration New lock duration in seconds (must be longer than remaining)
|
|
1433
1590
|
* @returns Transaction hash
|
|
1434
1591
|
*/
|
|
1435
|
-
async
|
|
1592
|
+
async extendLock(newLockDuration) {
|
|
1436
1593
|
if (!this.walletClient || !this.account) {
|
|
1437
1594
|
throw new Error("Wallet client required for write operations");
|
|
1438
1595
|
}
|
|
1439
1596
|
const hash = await this.walletClient.writeContract({
|
|
1440
1597
|
address: this.address,
|
|
1441
1598
|
abi: EXAGENT_STAKING_ABI,
|
|
1442
|
-
functionName: "
|
|
1443
|
-
args: [],
|
|
1599
|
+
functionName: "extendLock",
|
|
1600
|
+
args: [newLockDuration],
|
|
1444
1601
|
account: this.account,
|
|
1445
1602
|
chain: this.chain
|
|
1446
1603
|
});
|
|
1447
1604
|
return hash;
|
|
1448
1605
|
}
|
|
1449
1606
|
/**
|
|
1450
|
-
*
|
|
1607
|
+
* Unlock EXA after lock expires (normal path — no penalty)
|
|
1608
|
+
* Returns locked amount to unlocked deposited balance.
|
|
1451
1609
|
* @returns Transaction hash
|
|
1452
1610
|
*/
|
|
1453
|
-
async
|
|
1611
|
+
async unlock() {
|
|
1454
1612
|
if (!this.walletClient || !this.account) {
|
|
1455
1613
|
throw new Error("Wallet client required for write operations");
|
|
1456
1614
|
}
|
|
1457
1615
|
const hash = await this.walletClient.writeContract({
|
|
1458
1616
|
address: this.address,
|
|
1459
1617
|
abi: EXAGENT_STAKING_ABI,
|
|
1460
|
-
functionName: "
|
|
1618
|
+
functionName: "unlock",
|
|
1461
1619
|
args: [],
|
|
1462
1620
|
account: this.account,
|
|
1463
1621
|
chain: this.chain
|
|
@@ -1465,56 +1623,56 @@ var ExagentStaking = class {
|
|
|
1465
1623
|
return hash;
|
|
1466
1624
|
}
|
|
1467
1625
|
/**
|
|
1468
|
-
*
|
|
1469
|
-
*
|
|
1626
|
+
* Emergency withdrawal — instant exit from lock with graduated penalty
|
|
1627
|
+
* Two-phase penalty: 50%→20% over the first quarter of the lock, then flat 20% until expiry.
|
|
1628
|
+
* Penalty goes to treasury. Remaining returns to unlocked deposit balance.
|
|
1470
1629
|
* @returns Transaction hash
|
|
1471
1630
|
*/
|
|
1472
|
-
async
|
|
1631
|
+
async emergencyWithdraw() {
|
|
1473
1632
|
if (!this.walletClient || !this.account) {
|
|
1474
1633
|
throw new Error("Wallet client required for write operations");
|
|
1475
1634
|
}
|
|
1476
1635
|
const hash = await this.walletClient.writeContract({
|
|
1477
1636
|
address: this.address,
|
|
1478
1637
|
abi: EXAGENT_STAKING_ABI,
|
|
1479
|
-
functionName: "
|
|
1480
|
-
args: [
|
|
1638
|
+
functionName: "emergencyWithdraw",
|
|
1639
|
+
args: [],
|
|
1481
1640
|
account: this.account,
|
|
1482
1641
|
chain: this.chain
|
|
1483
1642
|
});
|
|
1484
1643
|
return hash;
|
|
1485
1644
|
}
|
|
1486
|
-
// ============
|
|
1645
|
+
// ============ Reward Functions ============
|
|
1487
1646
|
/**
|
|
1488
|
-
*
|
|
1489
|
-
* @param agentId The agent ID to delegate to
|
|
1647
|
+
* Claim accumulated EXA rewards
|
|
1490
1648
|
* @returns Transaction hash
|
|
1491
1649
|
*/
|
|
1492
|
-
async
|
|
1650
|
+
async claimRewards() {
|
|
1493
1651
|
if (!this.walletClient || !this.account) {
|
|
1494
1652
|
throw new Error("Wallet client required for write operations");
|
|
1495
1653
|
}
|
|
1496
1654
|
const hash = await this.walletClient.writeContract({
|
|
1497
1655
|
address: this.address,
|
|
1498
1656
|
abi: EXAGENT_STAKING_ABI,
|
|
1499
|
-
functionName: "
|
|
1500
|
-
args: [
|
|
1657
|
+
functionName: "claimRewards",
|
|
1658
|
+
args: [],
|
|
1501
1659
|
account: this.account,
|
|
1502
1660
|
chain: this.chain
|
|
1503
1661
|
});
|
|
1504
1662
|
return hash;
|
|
1505
1663
|
}
|
|
1506
1664
|
/**
|
|
1507
|
-
*
|
|
1665
|
+
* Claim all pending multi-token rewards (ETH, USDC, etc.)
|
|
1508
1666
|
* @returns Transaction hash
|
|
1509
1667
|
*/
|
|
1510
|
-
async
|
|
1668
|
+
async claimRewardsMulti() {
|
|
1511
1669
|
if (!this.walletClient || !this.account) {
|
|
1512
1670
|
throw new Error("Wallet client required for write operations");
|
|
1513
1671
|
}
|
|
1514
1672
|
const hash = await this.walletClient.writeContract({
|
|
1515
1673
|
address: this.address,
|
|
1516
1674
|
abi: EXAGENT_STAKING_ABI,
|
|
1517
|
-
functionName: "
|
|
1675
|
+
functionName: "claimRewardsMulti",
|
|
1518
1676
|
args: [],
|
|
1519
1677
|
account: this.account,
|
|
1520
1678
|
chain: this.chain
|
|
@@ -1522,19 +1680,19 @@ var ExagentStaking = class {
|
|
|
1522
1680
|
return hash;
|
|
1523
1681
|
}
|
|
1524
1682
|
/**
|
|
1525
|
-
*
|
|
1526
|
-
* @param
|
|
1683
|
+
* Claim pending rewards for a specific token
|
|
1684
|
+
* @param token The reward token address to claim
|
|
1527
1685
|
* @returns Transaction hash
|
|
1528
1686
|
*/
|
|
1529
|
-
async
|
|
1687
|
+
async claimRewardsToken(token) {
|
|
1530
1688
|
if (!this.walletClient || !this.account) {
|
|
1531
1689
|
throw new Error("Wallet client required for write operations");
|
|
1532
1690
|
}
|
|
1533
1691
|
const hash = await this.walletClient.writeContract({
|
|
1534
1692
|
address: this.address,
|
|
1535
1693
|
abi: EXAGENT_STAKING_ABI,
|
|
1536
|
-
functionName: "
|
|
1537
|
-
args: [
|
|
1694
|
+
functionName: "claimRewardsToken",
|
|
1695
|
+
args: [token],
|
|
1538
1696
|
account: this.account,
|
|
1539
1697
|
chain: this.chain
|
|
1540
1698
|
});
|
|
@@ -1542,20 +1700,26 @@ var ExagentStaking = class {
|
|
|
1542
1700
|
}
|
|
1543
1701
|
// ============ Read Functions ============
|
|
1544
1702
|
/**
|
|
1545
|
-
* Get comprehensive staking info for a user
|
|
1703
|
+
* Get comprehensive staking info for a user (deposit + lock)
|
|
1546
1704
|
* @param userAddress Address to check (defaults to connected wallet)
|
|
1547
|
-
* @returns
|
|
1705
|
+
* @returns Combined staking info
|
|
1548
1706
|
*/
|
|
1549
|
-
async
|
|
1707
|
+
async getStakingInfo(userAddress) {
|
|
1550
1708
|
const user = userAddress ?? this.account?.address;
|
|
1551
1709
|
if (!user) {
|
|
1552
1710
|
throw new Error("User address required");
|
|
1553
1711
|
}
|
|
1554
|
-
const [
|
|
1712
|
+
const [deposited, lockResult, currentVeEXA, vaultAccess, unlockedBalance] = await Promise.all([
|
|
1713
|
+
this.publicClient.readContract({
|
|
1714
|
+
address: this.address,
|
|
1715
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1716
|
+
functionName: "depositedAmount",
|
|
1717
|
+
args: [user]
|
|
1718
|
+
}),
|
|
1555
1719
|
this.publicClient.readContract({
|
|
1556
1720
|
address: this.address,
|
|
1557
1721
|
abi: EXAGENT_STAKING_ABI,
|
|
1558
|
-
functionName: "
|
|
1722
|
+
functionName: "locks",
|
|
1559
1723
|
args: [user]
|
|
1560
1724
|
}),
|
|
1561
1725
|
this.publicClient.readContract({
|
|
@@ -1563,20 +1727,88 @@ var ExagentStaking = class {
|
|
|
1563
1727
|
abi: EXAGENT_STAKING_ABI,
|
|
1564
1728
|
functionName: "getVeEXABalance",
|
|
1565
1729
|
args: [user]
|
|
1730
|
+
}),
|
|
1731
|
+
this.publicClient.readContract({
|
|
1732
|
+
address: this.address,
|
|
1733
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1734
|
+
functionName: "hasVaultAccess",
|
|
1735
|
+
args: [user]
|
|
1736
|
+
}),
|
|
1737
|
+
this.publicClient.readContract({
|
|
1738
|
+
address: this.address,
|
|
1739
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1740
|
+
functionName: "getUnlockedBalance",
|
|
1741
|
+
args: [user]
|
|
1566
1742
|
})
|
|
1567
1743
|
]);
|
|
1568
|
-
const
|
|
1744
|
+
const lockData = lockResult;
|
|
1745
|
+
const depositedBigint = deposited;
|
|
1746
|
+
const lockedAmount = lockData[0];
|
|
1569
1747
|
const now = BigInt(Math.floor(Date.now() / 1e3));
|
|
1570
|
-
const
|
|
1571
|
-
|
|
1748
|
+
const depositInfo = {
|
|
1749
|
+
deposited: depositedBigint,
|
|
1750
|
+
locked: lockedAmount,
|
|
1751
|
+
unlocked: unlockedBalance,
|
|
1752
|
+
hasVaultAccess: vaultAccess
|
|
1753
|
+
};
|
|
1754
|
+
let lockInfo = null;
|
|
1755
|
+
if (lockedAmount > 0n) {
|
|
1756
|
+
const isUnlocked = lockData[1] <= now;
|
|
1757
|
+
const remainingLockTime = isUnlocked ? 0n : lockData[1] - now;
|
|
1758
|
+
lockInfo = {
|
|
1759
|
+
amount: lockData[0],
|
|
1760
|
+
unlockTime: lockData[1],
|
|
1761
|
+
lockDuration: lockData[2],
|
|
1762
|
+
vEXABalance: lockData[3],
|
|
1763
|
+
currentVeEXA,
|
|
1764
|
+
isUnlocked,
|
|
1765
|
+
remainingLockTime
|
|
1766
|
+
};
|
|
1767
|
+
}
|
|
1768
|
+
return { deposit: depositInfo, lock: lockInfo };
|
|
1769
|
+
}
|
|
1770
|
+
/**
|
|
1771
|
+
* Get deposit info for a user
|
|
1772
|
+
* @param userAddress Address to check (defaults to connected wallet)
|
|
1773
|
+
* @returns Deposit info
|
|
1774
|
+
*/
|
|
1775
|
+
async getDepositInfo(userAddress) {
|
|
1776
|
+
const user = userAddress ?? this.account?.address;
|
|
1777
|
+
if (!user) {
|
|
1778
|
+
throw new Error("User address required");
|
|
1779
|
+
}
|
|
1780
|
+
const [deposited, lockResult, vaultAccess, unlockedBalance] = await Promise.all([
|
|
1781
|
+
this.publicClient.readContract({
|
|
1782
|
+
address: this.address,
|
|
1783
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1784
|
+
functionName: "depositedAmount",
|
|
1785
|
+
args: [user]
|
|
1786
|
+
}),
|
|
1787
|
+
this.publicClient.readContract({
|
|
1788
|
+
address: this.address,
|
|
1789
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1790
|
+
functionName: "locks",
|
|
1791
|
+
args: [user]
|
|
1792
|
+
}),
|
|
1793
|
+
this.publicClient.readContract({
|
|
1794
|
+
address: this.address,
|
|
1795
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1796
|
+
functionName: "hasVaultAccess",
|
|
1797
|
+
args: [user]
|
|
1798
|
+
}),
|
|
1799
|
+
this.publicClient.readContract({
|
|
1800
|
+
address: this.address,
|
|
1801
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1802
|
+
functionName: "getUnlockedBalance",
|
|
1803
|
+
args: [user]
|
|
1804
|
+
})
|
|
1805
|
+
]);
|
|
1806
|
+
const lockData = lockResult;
|
|
1572
1807
|
return {
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
currentVeEXA,
|
|
1578
|
-
isUnlocked,
|
|
1579
|
-
remainingLockTime
|
|
1808
|
+
deposited,
|
|
1809
|
+
locked: lockData[0],
|
|
1810
|
+
unlocked: unlockedBalance,
|
|
1811
|
+
hasVaultAccess: vaultAccess
|
|
1580
1812
|
};
|
|
1581
1813
|
}
|
|
1582
1814
|
/**
|
|
@@ -1597,11 +1829,28 @@ var ExagentStaking = class {
|
|
|
1597
1829
|
});
|
|
1598
1830
|
}
|
|
1599
1831
|
/**
|
|
1600
|
-
* Get
|
|
1832
|
+
* Get effective vEXA (with tier multiplier applied)
|
|
1833
|
+
* @param userAddress Address to check (defaults to connected wallet)
|
|
1834
|
+
* @returns Effective vEXA balance
|
|
1835
|
+
*/
|
|
1836
|
+
async getEffectiveVeEXA(userAddress) {
|
|
1837
|
+
const user = userAddress ?? this.account?.address;
|
|
1838
|
+
if (!user) {
|
|
1839
|
+
throw new Error("User address required");
|
|
1840
|
+
}
|
|
1841
|
+
return this.publicClient.readContract({
|
|
1842
|
+
address: this.address,
|
|
1843
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1844
|
+
functionName: "getEffectiveVeEXA",
|
|
1845
|
+
args: [user]
|
|
1846
|
+
});
|
|
1847
|
+
}
|
|
1848
|
+
/**
|
|
1849
|
+
* Check if user has vault access (meets deposit threshold)
|
|
1601
1850
|
* @param userAddress Address to check (defaults to connected wallet)
|
|
1602
|
-
* @returns
|
|
1851
|
+
* @returns True if user can access vaults
|
|
1603
1852
|
*/
|
|
1604
|
-
async
|
|
1853
|
+
async hasVaultAccess(userAddress) {
|
|
1605
1854
|
const user = userAddress ?? this.account?.address;
|
|
1606
1855
|
if (!user) {
|
|
1607
1856
|
throw new Error("User address required");
|
|
@@ -1609,52 +1858,47 @@ var ExagentStaking = class {
|
|
|
1609
1858
|
return this.publicClient.readContract({
|
|
1610
1859
|
address: this.address,
|
|
1611
1860
|
abi: EXAGENT_STAKING_ABI,
|
|
1612
|
-
functionName: "
|
|
1861
|
+
functionName: "hasVaultAccess",
|
|
1613
1862
|
args: [user]
|
|
1614
1863
|
});
|
|
1615
1864
|
}
|
|
1616
1865
|
/**
|
|
1617
|
-
* Get
|
|
1618
|
-
* @param
|
|
1619
|
-
* @returns
|
|
1866
|
+
* Get earnings tier for a user (Bronze/Silver/Gold/Platinum/Diamond)
|
|
1867
|
+
* @param userAddress Address to check (defaults to connected wallet)
|
|
1868
|
+
* @returns Tier info with multiplier and name
|
|
1620
1869
|
*/
|
|
1621
|
-
async
|
|
1870
|
+
async getEarningsTier(userAddress) {
|
|
1871
|
+
const user = userAddress ?? this.account?.address;
|
|
1872
|
+
if (!user) {
|
|
1873
|
+
throw new Error("User address required");
|
|
1874
|
+
}
|
|
1622
1875
|
const result = await this.publicClient.readContract({
|
|
1623
1876
|
address: this.address,
|
|
1624
1877
|
abi: EXAGENT_STAKING_ABI,
|
|
1625
|
-
functionName: "
|
|
1626
|
-
args: [
|
|
1878
|
+
functionName: "getEarningsTier",
|
|
1879
|
+
args: [user]
|
|
1627
1880
|
});
|
|
1628
1881
|
return {
|
|
1629
|
-
|
|
1630
|
-
|
|
1882
|
+
multiplierBps: result[0],
|
|
1883
|
+
tierName: result[1]
|
|
1631
1884
|
};
|
|
1632
1885
|
}
|
|
1633
1886
|
/**
|
|
1634
|
-
* Get
|
|
1887
|
+
* Get current emergency withdrawal penalty for a user
|
|
1635
1888
|
* @param userAddress Address to check (defaults to connected wallet)
|
|
1636
|
-
* @returns
|
|
1889
|
+
* @returns Penalty in basis points (5000 = 50% at lock start, ramps to 2000 over first 25% of lock, then flat 2000)
|
|
1637
1890
|
*/
|
|
1638
|
-
async
|
|
1891
|
+
async getEmergencyWithdrawPenalty(userAddress) {
|
|
1639
1892
|
const user = userAddress ?? this.account?.address;
|
|
1640
1893
|
if (!user) {
|
|
1641
1894
|
throw new Error("User address required");
|
|
1642
1895
|
}
|
|
1643
|
-
|
|
1896
|
+
return this.publicClient.readContract({
|
|
1644
1897
|
address: this.address,
|
|
1645
1898
|
abi: EXAGENT_STAKING_ABI,
|
|
1646
|
-
functionName: "
|
|
1899
|
+
functionName: "getEmergencyWithdrawPenalty",
|
|
1647
1900
|
args: [user]
|
|
1648
1901
|
});
|
|
1649
|
-
let tier = "none";
|
|
1650
|
-
if (discountBps >= 5000n) {
|
|
1651
|
-
tier = "gold";
|
|
1652
|
-
} else if (discountBps >= 2500n) {
|
|
1653
|
-
tier = "silver";
|
|
1654
|
-
} else if (discountBps >= 1000n) {
|
|
1655
|
-
tier = "bronze";
|
|
1656
|
-
}
|
|
1657
|
-
return { tier, discountBps };
|
|
1658
1902
|
}
|
|
1659
1903
|
/**
|
|
1660
1904
|
* Get pending EXA rewards for a user
|
|
@@ -1716,14 +1960,25 @@ var ExagentStaking = class {
|
|
|
1716
1960
|
});
|
|
1717
1961
|
}
|
|
1718
1962
|
/**
|
|
1719
|
-
* Get total
|
|
1720
|
-
* @returns Total
|
|
1963
|
+
* Get total EXA deposited across all users
|
|
1964
|
+
* @returns Total deposited amount in wei
|
|
1721
1965
|
*/
|
|
1722
|
-
async
|
|
1966
|
+
async getTotalDeposited() {
|
|
1723
1967
|
return this.publicClient.readContract({
|
|
1724
1968
|
address: this.address,
|
|
1725
1969
|
abi: EXAGENT_STAKING_ABI,
|
|
1726
|
-
functionName: "
|
|
1970
|
+
functionName: "totalDeposited"
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
1973
|
+
/**
|
|
1974
|
+
* Get total EXA locked across all users
|
|
1975
|
+
* @returns Total locked amount in wei
|
|
1976
|
+
*/
|
|
1977
|
+
async getTotalLocked() {
|
|
1978
|
+
return this.publicClient.readContract({
|
|
1979
|
+
address: this.address,
|
|
1980
|
+
abi: EXAGENT_STAKING_ABI,
|
|
1981
|
+
functionName: "totalLocked"
|
|
1727
1982
|
});
|
|
1728
1983
|
}
|
|
1729
1984
|
/**
|
|
@@ -1738,8 +1993,8 @@ var ExagentStaking = class {
|
|
|
1738
1993
|
});
|
|
1739
1994
|
}
|
|
1740
1995
|
/**
|
|
1741
|
-
* Calculate vEXA balance for a given
|
|
1742
|
-
* @param amount Amount of EXA to
|
|
1996
|
+
* Calculate vEXA balance for a given lock (preview)
|
|
1997
|
+
* @param amount Amount of EXA to lock
|
|
1743
1998
|
* @param lockDuration Lock duration in seconds
|
|
1744
1999
|
* @returns Expected vEXA balance
|
|
1745
2000
|
*/
|
|
@@ -1764,7 +2019,7 @@ var ExagentStaking = class {
|
|
|
1764
2019
|
}
|
|
1765
2020
|
// ============ Helper Functions ============
|
|
1766
2021
|
/**
|
|
1767
|
-
* Approve EXA token spending for
|
|
2022
|
+
* Approve EXA token spending for deposits
|
|
1768
2023
|
* @param amount Amount to approve
|
|
1769
2024
|
* @returns Transaction hash
|
|
1770
2025
|
*/
|
|
@@ -1802,35 +2057,23 @@ var ExagentStaking = class {
|
|
|
1802
2057
|
|
|
1803
2058
|
// src/constants.ts
|
|
1804
2059
|
var import_chains = require("viem/chains");
|
|
2060
|
+
var SDK_VERSION = "0.1.4";
|
|
1805
2061
|
var CHAIN_CONFIG = {
|
|
1806
|
-
mainnet: import_chains.base
|
|
1807
|
-
testnet: import_chains.baseSepolia
|
|
2062
|
+
mainnet: import_chains.base
|
|
1808
2063
|
};
|
|
1809
2064
|
var CONTRACT_ADDRESSES = {
|
|
1810
2065
|
mainnet: {
|
|
1811
|
-
agentRegistry: "
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
router: "0x0000000000000000000000000000000000000000",
|
|
2066
|
+
agentRegistry: "0x2261706C751F8ac5cdDb481B7b56EA2137d4A723",
|
|
2067
|
+
exaToken: "0x13403Fb738C97cF7564F279288468c140AaEd05c",
|
|
2068
|
+
staking: "0xAF1729D1519A72f7d9b87aa23a305b775e2849DA",
|
|
2069
|
+
router: "0x11daD5366D903a3eF5d8f07EFF87ce6b173859a9",
|
|
1816
2070
|
vaultFactory: "0x0000000000000000000000000000000000000000",
|
|
1817
|
-
|
|
2071
|
+
// Phase 2 — pending deploy
|
|
2072
|
+
feeCollector: "0xe66328a964AF93bEF2eDB226D039C35aE6e66De1",
|
|
1818
2073
|
buyback: "0x0000000000000000000000000000000000000000",
|
|
2074
|
+
// Phase 2 — pending deploy
|
|
1819
2075
|
serviceEscrow: "0x0000000000000000000000000000000000000000"
|
|
1820
|
-
|
|
1821
|
-
testnet: {
|
|
1822
|
-
agentRegistry: "0xCF48C341e3FebeCA5ECB7eb2535f61A2Ba855d9C",
|
|
1823
|
-
// V4 UUPS proxy, one-agent-per-wallet
|
|
1824
|
-
exaToken: "0x66c39b0ad96B3f5eE198Fef913c6636353a48A87",
|
|
1825
|
-
staking: "0x439441468e1b1b616E9D36b80969C241F261A011",
|
|
1826
|
-
// V2 with delegation
|
|
1827
|
-
router: "0xc0c27eEE047E414CD716D06C2444CF2073113d5C",
|
|
1828
|
-
// V3 with config epochs
|
|
1829
|
-
vaultFactory: "0x5c099daaE33801a907Bb57011c6749655b55dc75",
|
|
1830
|
-
// V2 with requirements
|
|
1831
|
-
feeCollector: "0xcB57b03a50df054b9C738Df1324C17A4fDe4fe46",
|
|
1832
|
-
buyback: "0x35cdEa810A130A846265682e5c71A68A507aB895",
|
|
1833
|
-
serviceEscrow: "0x74a3496b148DEE735ac388299aF9Ac2F7C4EdCBf"
|
|
2076
|
+
// Phase 2 — pending deploy
|
|
1834
2077
|
}
|
|
1835
2078
|
};
|
|
1836
2079
|
var DEX_ADDRESSES = {
|
|
@@ -1850,21 +2093,44 @@ var ZERO_X_CONFIG = {
|
|
|
1850
2093
|
// Base
|
|
1851
2094
|
};
|
|
1852
2095
|
var EXAGENT_API_CONFIG = {
|
|
1853
|
-
mainnet: "https://api.
|
|
1854
|
-
testnet: "https://api.testnet.exagent.io"
|
|
2096
|
+
mainnet: "https://exagent-api.onrender.com"
|
|
1855
2097
|
};
|
|
1856
2098
|
var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
2099
|
+
var PHASE_1_CONTRACTS = /* @__PURE__ */ new Set([
|
|
2100
|
+
"agentRegistry",
|
|
2101
|
+
"exaToken",
|
|
2102
|
+
"staking",
|
|
2103
|
+
"router",
|
|
2104
|
+
"feeCollector"
|
|
2105
|
+
]);
|
|
1857
2106
|
function validateContractAddresses(network) {
|
|
1858
2107
|
const addresses = CONTRACT_ADDRESSES[network];
|
|
1859
|
-
const
|
|
1860
|
-
if (
|
|
1861
|
-
const missing = zeroEntries.map(([name]) => name).join(", ");
|
|
2108
|
+
const missingPhase1 = Object.entries(addresses).filter(([name, addr]) => PHASE_1_CONTRACTS.has(name) && addr === ZERO_ADDRESS).map(([name]) => name);
|
|
2109
|
+
if (missingPhase1.length > 0) {
|
|
1862
2110
|
throw new Error(
|
|
1863
|
-
`Mainnet contracts not
|
|
2111
|
+
`Mainnet Phase 1 contracts not deployed. Missing: ${missingPhase1.join(", ")}. Update @exagent/sdk to the latest version.`
|
|
1864
2112
|
);
|
|
1865
2113
|
}
|
|
1866
2114
|
}
|
|
1867
2115
|
|
|
2116
|
+
// src/types.ts
|
|
2117
|
+
function buildGlobalAgentId(chainId, registryAddress, agentId) {
|
|
2118
|
+
return `eip155:${chainId}:${registryAddress}:${Number(agentId)}`;
|
|
2119
|
+
}
|
|
2120
|
+
function parseGlobalAgentId(globalId) {
|
|
2121
|
+
const parts = globalId.split(":");
|
|
2122
|
+
if (parts.length !== 4 || parts[0] !== "eip155") {
|
|
2123
|
+
throw new Error(`Invalid ERC-8004 global agent ID: ${globalId}`);
|
|
2124
|
+
}
|
|
2125
|
+
const chainId = parseInt(parts[1], 10);
|
|
2126
|
+
const registryAddress = parts[2];
|
|
2127
|
+
const agentId = parseInt(parts[3], 10);
|
|
2128
|
+
if (isNaN(chainId) || isNaN(agentId)) {
|
|
2129
|
+
throw new Error(`Invalid ERC-8004 global agent ID: ${globalId}`);
|
|
2130
|
+
}
|
|
2131
|
+
return { chainId, registryAddress, agentId };
|
|
2132
|
+
}
|
|
2133
|
+
|
|
1868
2134
|
// src/client.ts
|
|
1869
2135
|
var ExagentClient = class {
|
|
1870
2136
|
publicClient;
|
|
@@ -1878,7 +2144,7 @@ var ExagentClient = class {
|
|
|
1878
2144
|
// Cached agent ID
|
|
1879
2145
|
_agentId;
|
|
1880
2146
|
constructor(config) {
|
|
1881
|
-
this.network = config.network ?? "
|
|
2147
|
+
this.network = config.network ?? "mainnet";
|
|
1882
2148
|
this.apiKey = config.apiKey;
|
|
1883
2149
|
validateContractAddresses(this.network);
|
|
1884
2150
|
const chain = CHAIN_CONFIG[this.network];
|
|
@@ -1915,6 +2181,14 @@ var ExagentClient = class {
|
|
|
1915
2181
|
this.account
|
|
1916
2182
|
);
|
|
1917
2183
|
}
|
|
2184
|
+
/** Standard headers for all API requests (includes SDK version for gating) */
|
|
2185
|
+
apiHeaders(contentType) {
|
|
2186
|
+
return {
|
|
2187
|
+
...contentType && { "Content-Type": contentType },
|
|
2188
|
+
"X-Exagent-SDK-Version": SDK_VERSION,
|
|
2189
|
+
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2190
|
+
};
|
|
2191
|
+
}
|
|
1918
2192
|
// ============ Agent Registration ============
|
|
1919
2193
|
/**
|
|
1920
2194
|
* Register as a new agent on Exagent
|
|
@@ -2002,127 +2276,15 @@ var ExagentClient = class {
|
|
|
2002
2276
|
}
|
|
2003
2277
|
// ============ Trading ============
|
|
2004
2278
|
/**
|
|
2005
|
-
*
|
|
2006
|
-
*
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
headers: {
|
|
2013
|
-
"Content-Type": "application/json",
|
|
2014
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2015
|
-
},
|
|
2016
|
-
body: JSON.stringify({
|
|
2017
|
-
tokenIn: intent.tokenIn,
|
|
2018
|
-
tokenOut: intent.tokenOut,
|
|
2019
|
-
amountIn: intent.amountIn.toString(),
|
|
2020
|
-
slippageBps: intent.maxSlippageBps ?? 50,
|
|
2021
|
-
taker: this.account.address
|
|
2022
|
-
})
|
|
2023
|
-
});
|
|
2024
|
-
if (!response.ok) {
|
|
2025
|
-
const error = await response.json().catch(() => ({ error: response.statusText }));
|
|
2026
|
-
throw new Error(`Failed to get route: ${error.error}`);
|
|
2027
|
-
}
|
|
2028
|
-
return response.json();
|
|
2029
|
-
}
|
|
2030
|
-
/**
|
|
2031
|
-
* Get price quote without transaction data (faster)
|
|
2032
|
-
*/
|
|
2033
|
-
async getPrice(tokenIn, tokenOut, amountIn) {
|
|
2034
|
-
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2035
|
-
const response = await fetch(`${apiUrl}/v1/routes/price`, {
|
|
2036
|
-
method: "POST",
|
|
2037
|
-
headers: {
|
|
2038
|
-
"Content-Type": "application/json",
|
|
2039
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2040
|
-
},
|
|
2041
|
-
body: JSON.stringify({
|
|
2042
|
-
tokenIn,
|
|
2043
|
-
tokenOut,
|
|
2044
|
-
amountIn: amountIn.toString()
|
|
2045
|
-
})
|
|
2046
|
-
});
|
|
2047
|
-
if (!response.ok) {
|
|
2048
|
-
const error = await response.json().catch(() => ({ error: response.statusText }));
|
|
2049
|
-
throw new Error(`Failed to get price: ${error.error}`);
|
|
2050
|
-
}
|
|
2051
|
-
return response.json();
|
|
2052
|
-
}
|
|
2053
|
-
/**
|
|
2054
|
-
* Execute a trade using a pre-fetched route
|
|
2055
|
-
* @param route Route quote from getRoute()
|
|
2056
|
-
* @param options Trade execution options
|
|
2057
|
-
* @returns Transaction hash
|
|
2058
|
-
*/
|
|
2059
|
-
async executeTrade(route, options) {
|
|
2060
|
-
if (route.validUntil && Date.now() > route.validUntil) {
|
|
2061
|
-
throw new Error("Quote expired, please fetch a new route");
|
|
2062
|
-
}
|
|
2063
|
-
if (route.issues?.allowance) {
|
|
2064
|
-
throw new Error(
|
|
2065
|
-
`Insufficient allowance for ${route.issues.allowance.spender}. Need ${route.issues.allowance.expected}, have ${route.issues.allowance.actual}`
|
|
2066
|
-
);
|
|
2067
|
-
}
|
|
2068
|
-
if (options?.validateSlippage !== false) {
|
|
2069
|
-
const freshPrice = await this.getPrice(
|
|
2070
|
-
route.tokenIn,
|
|
2071
|
-
route.tokenOut,
|
|
2072
|
-
BigInt(route.amountIn)
|
|
2073
|
-
);
|
|
2074
|
-
const quotedOutput = BigInt(route.amountOut);
|
|
2075
|
-
const freshOutput = BigInt(freshPrice.amountOut);
|
|
2076
|
-
if (freshOutput < quotedOutput * 99n / 100n) {
|
|
2077
|
-
console.warn("Price has moved significantly since quote was fetched");
|
|
2078
|
-
}
|
|
2079
|
-
}
|
|
2080
|
-
const hash = await this.walletClient.sendTransaction({
|
|
2081
|
-
account: this.account,
|
|
2082
|
-
chain: CHAIN_CONFIG[this.network],
|
|
2083
|
-
to: route.transaction.to,
|
|
2084
|
-
data: route.transaction.data,
|
|
2085
|
-
value: BigInt(route.transaction.value)
|
|
2086
|
-
});
|
|
2087
|
-
return hash;
|
|
2088
|
-
}
|
|
2089
|
-
/**
|
|
2090
|
-
* Get and execute a trade in one call
|
|
2091
|
-
* Convenience method that fetches route and executes
|
|
2092
|
-
*/
|
|
2093
|
-
async swap(intent) {
|
|
2094
|
-
const route = await this.getRoute(intent);
|
|
2095
|
-
const hash = await this.executeTrade(route);
|
|
2096
|
-
return { hash, route };
|
|
2097
|
-
}
|
|
2098
|
-
/**
|
|
2099
|
-
* Broadcast a trade intent to the network
|
|
2100
|
-
* Other agents can see this and potentially provide better execution
|
|
2101
|
-
*/
|
|
2102
|
-
async broadcastIntent(intent) {
|
|
2103
|
-
const agentId = await this.getAgentId();
|
|
2104
|
-
if (!agentId) throw new Error("Agent not registered");
|
|
2105
|
-
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2106
|
-
await fetch(`${apiUrl}/v1/intents`, {
|
|
2107
|
-
method: "POST",
|
|
2108
|
-
headers: {
|
|
2109
|
-
"Content-Type": "application/json",
|
|
2110
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2111
|
-
},
|
|
2112
|
-
body: JSON.stringify({
|
|
2113
|
-
agentId: agentId.toString(),
|
|
2114
|
-
intent,
|
|
2115
|
-
signature: await this.signIntent(intent)
|
|
2116
|
-
})
|
|
2117
|
-
});
|
|
2118
|
-
}
|
|
2119
|
-
// ============ Router Trading (Attributed) ============
|
|
2120
|
-
/**
|
|
2121
|
-
* Execute a trade through ExagentRouter for full attribution
|
|
2279
|
+
* Execute a trade through ExagentRouter
|
|
2280
|
+
*
|
|
2281
|
+
* All trades MUST go through the ExagentRouter. This ensures:
|
|
2282
|
+
* - Trade attribution for leaderboard ranking
|
|
2283
|
+
* - Protocol fee collection (0.2%)
|
|
2284
|
+
* - On-chain performance tracking
|
|
2285
|
+
* - Token whitelist enforcement per risk universe
|
|
2122
2286
|
*
|
|
2123
|
-
*
|
|
2124
|
-
* the ExagentRouter emit TradeExecuted events that are captured by the indexer
|
|
2125
|
-
* for accurate performance tracking and rankings.
|
|
2287
|
+
* There is no way to trade outside the router. This is by design.
|
|
2126
2288
|
*
|
|
2127
2289
|
* @param intent Trade parameters
|
|
2128
2290
|
* @returns Trade result with transaction hash
|
|
@@ -2175,10 +2337,7 @@ var ExagentClient = class {
|
|
|
2175
2337
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2176
2338
|
const response = await fetch(`${apiUrl}/v1/router/trade`, {
|
|
2177
2339
|
method: "POST",
|
|
2178
|
-
headers:
|
|
2179
|
-
"Content-Type": "application/json",
|
|
2180
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2181
|
-
},
|
|
2340
|
+
headers: this.apiHeaders("application/json"),
|
|
2182
2341
|
body: JSON.stringify({
|
|
2183
2342
|
agentId: id.toString(),
|
|
2184
2343
|
tokenIn: intent.tokenIn,
|
|
@@ -2227,10 +2386,7 @@ var ExagentClient = class {
|
|
|
2227
2386
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2228
2387
|
const response = await fetch(`${apiUrl}/v1/services/request`, {
|
|
2229
2388
|
method: "POST",
|
|
2230
|
-
headers:
|
|
2231
|
-
"Content-Type": "application/json",
|
|
2232
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2233
|
-
},
|
|
2389
|
+
headers: this.apiHeaders("application/json"),
|
|
2234
2390
|
body: JSON.stringify({
|
|
2235
2391
|
requesterId: agentId.toString(),
|
|
2236
2392
|
...request
|
|
@@ -2248,7 +2404,9 @@ var ExagentClient = class {
|
|
|
2248
2404
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2249
2405
|
const params = new URLSearchParams();
|
|
2250
2406
|
if (serviceType) params.set("type", serviceType);
|
|
2251
|
-
const response = await fetch(`${apiUrl}/v1/services?${params}
|
|
2407
|
+
const response = await fetch(`${apiUrl}/v1/services?${params}`, {
|
|
2408
|
+
headers: this.apiHeaders()
|
|
2409
|
+
});
|
|
2252
2410
|
return response.json();
|
|
2253
2411
|
}
|
|
2254
2412
|
// ============ Leaderboards ============
|
|
@@ -2261,7 +2419,9 @@ var ExagentClient = class {
|
|
|
2261
2419
|
if (options?.category) params.set("category", options.category);
|
|
2262
2420
|
if (options?.limit) params.set("limit", options.limit.toString());
|
|
2263
2421
|
if (options?.offset) params.set("offset", options.offset.toString());
|
|
2264
|
-
const response = await fetch(`${apiUrl}/v1/rankings/leaderboard?${params}
|
|
2422
|
+
const response = await fetch(`${apiUrl}/v1/rankings/leaderboard?${params}`, {
|
|
2423
|
+
headers: this.apiHeaders()
|
|
2424
|
+
});
|
|
2265
2425
|
return response.json();
|
|
2266
2426
|
}
|
|
2267
2427
|
// ============ Vault Functions (Phase 4: Copy Trading) ============
|
|
@@ -2289,9 +2449,7 @@ var ExagentClient = class {
|
|
|
2289
2449
|
if (!id) throw new Error("Agent not registered");
|
|
2290
2450
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2291
2451
|
const response = await fetch(`${apiUrl}/v1/vaults?agentId=${id}`, {
|
|
2292
|
-
headers:
|
|
2293
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2294
|
-
}
|
|
2452
|
+
headers: this.apiHeaders()
|
|
2295
2453
|
});
|
|
2296
2454
|
if (!response.ok) {
|
|
2297
2455
|
throw new Error(`Failed to get vaults: ${response.statusText}`);
|
|
@@ -2307,9 +2465,7 @@ var ExagentClient = class {
|
|
|
2307
2465
|
const user = userAddress ?? this.account.address;
|
|
2308
2466
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2309
2467
|
const response = await fetch(`${apiUrl}/v1/vaults?depositor=${user}`, {
|
|
2310
|
-
headers:
|
|
2311
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2312
|
-
}
|
|
2468
|
+
headers: this.apiHeaders()
|
|
2313
2469
|
});
|
|
2314
2470
|
if (!response.ok) {
|
|
2315
2471
|
throw new Error(`Failed to get user vaults: ${response.statusText}`);
|
|
@@ -2329,9 +2485,7 @@ var ExagentClient = class {
|
|
|
2329
2485
|
if (options?.period) params.set("period", options.period);
|
|
2330
2486
|
if (options?.limit) params.set("limit", options.limit.toString());
|
|
2331
2487
|
const response = await fetch(`${apiUrl}/v1/vaults/top?${params}`, {
|
|
2332
|
-
headers:
|
|
2333
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2334
|
-
}
|
|
2488
|
+
headers: this.apiHeaders()
|
|
2335
2489
|
});
|
|
2336
2490
|
if (!response.ok) {
|
|
2337
2491
|
throw new Error(`Failed to get top vaults: ${response.statusText}`);
|
|
@@ -2372,37 +2526,73 @@ var ExagentClient = class {
|
|
|
2372
2526
|
}
|
|
2373
2527
|
// ============ Staking Functions ============
|
|
2374
2528
|
/**
|
|
2375
|
-
*
|
|
2376
|
-
* @param amount Amount of EXA to
|
|
2529
|
+
* Deposit EXA tokens for vault access (no lock required)
|
|
2530
|
+
* @param amount Amount of EXA to deposit (in wei)
|
|
2531
|
+
* @returns Transaction hash
|
|
2532
|
+
*
|
|
2533
|
+
* @example
|
|
2534
|
+
* ```typescript
|
|
2535
|
+
* // Deposit 1000 EXA to unlock vault access
|
|
2536
|
+
* const tx = await exagent.depositExa(parseEther('1000'));
|
|
2537
|
+
* ```
|
|
2538
|
+
*/
|
|
2539
|
+
async depositExa(amount) {
|
|
2540
|
+
await this.staking.approveExa(amount);
|
|
2541
|
+
return this.staking.deposit(amount);
|
|
2542
|
+
}
|
|
2543
|
+
/**
|
|
2544
|
+
* Withdraw unlocked EXA tokens (instant, no penalty)
|
|
2545
|
+
* @param amount Amount of EXA to withdraw (in wei)
|
|
2546
|
+
* @returns Transaction hash
|
|
2547
|
+
*/
|
|
2548
|
+
async withdrawExa(amount) {
|
|
2549
|
+
return this.staking.withdraw(amount);
|
|
2550
|
+
}
|
|
2551
|
+
/**
|
|
2552
|
+
* Lock deposited EXA to receive vEXA voting power and earn rewards
|
|
2553
|
+
* @param amount Amount of deposited EXA to lock (in wei)
|
|
2377
2554
|
* @param lockDuration Lock duration in seconds (30 days to 2 years)
|
|
2378
2555
|
* @returns Transaction hash
|
|
2379
2556
|
*
|
|
2380
2557
|
* @example
|
|
2381
2558
|
* ```typescript
|
|
2382
|
-
* //
|
|
2383
|
-
* const tx = await exagent.
|
|
2559
|
+
* // Lock 1000 EXA for 6 months
|
|
2560
|
+
* const tx = await exagent.lockExa(
|
|
2384
2561
|
* parseEther('1000'),
|
|
2385
2562
|
* ExagentStaking.LOCK_6_MONTHS
|
|
2386
2563
|
* );
|
|
2387
2564
|
* ```
|
|
2388
2565
|
*/
|
|
2389
|
-
async
|
|
2390
|
-
|
|
2391
|
-
return this.staking.stake(amount, lockDuration);
|
|
2566
|
+
async lockExa(amount, lockDuration) {
|
|
2567
|
+
return this.staking.lock(amount, lockDuration);
|
|
2392
2568
|
}
|
|
2393
2569
|
/**
|
|
2394
|
-
*
|
|
2570
|
+
* Unlock EXA after lock expires (no penalty)
|
|
2395
2571
|
* @returns Transaction hash
|
|
2396
2572
|
*/
|
|
2397
|
-
async
|
|
2398
|
-
return this.staking.
|
|
2573
|
+
async unlockExa() {
|
|
2574
|
+
return this.staking.unlock();
|
|
2399
2575
|
}
|
|
2400
2576
|
/**
|
|
2401
|
-
*
|
|
2402
|
-
* @returns
|
|
2577
|
+
* Emergency withdrawal from active lock (graduated 50%→20% penalty)
|
|
2578
|
+
* @returns Transaction hash
|
|
2579
|
+
*/
|
|
2580
|
+
async emergencyWithdrawExa() {
|
|
2581
|
+
return this.staking.emergencyWithdraw();
|
|
2582
|
+
}
|
|
2583
|
+
/**
|
|
2584
|
+
* Get comprehensive staking info (deposit + lock) for the connected wallet
|
|
2585
|
+
* @returns Staking info including deposit status and lock status
|
|
2403
2586
|
*/
|
|
2404
2587
|
async getStakingInfo() {
|
|
2405
|
-
return this.staking.
|
|
2588
|
+
return this.staking.getStakingInfo();
|
|
2589
|
+
}
|
|
2590
|
+
/**
|
|
2591
|
+
* Get deposit info for the connected wallet
|
|
2592
|
+
* @returns Deposit info (deposited, locked, unlocked, vault access)
|
|
2593
|
+
*/
|
|
2594
|
+
async getDepositInfo() {
|
|
2595
|
+
return this.staking.getDepositInfo();
|
|
2406
2596
|
}
|
|
2407
2597
|
/**
|
|
2408
2598
|
* Get current vEXA balance for the connected wallet
|
|
@@ -2412,20 +2602,25 @@ var ExagentClient = class {
|
|
|
2412
2602
|
return this.staking.getVeEXABalance();
|
|
2413
2603
|
}
|
|
2414
2604
|
/**
|
|
2415
|
-
*
|
|
2416
|
-
* @
|
|
2417
|
-
|
|
2605
|
+
* Check if connected wallet has vault access (meets deposit threshold)
|
|
2606
|
+
* @returns True if user can access vaults
|
|
2607
|
+
*/
|
|
2608
|
+
async hasVaultAccess() {
|
|
2609
|
+
return this.staking.hasVaultAccess();
|
|
2610
|
+
}
|
|
2611
|
+
/**
|
|
2612
|
+
* Get earnings tier for the connected wallet
|
|
2613
|
+
* @returns Tier info with multiplier and name
|
|
2418
2614
|
*/
|
|
2419
|
-
async
|
|
2420
|
-
return this.staking.
|
|
2615
|
+
async getEarningsTier() {
|
|
2616
|
+
return this.staking.getEarningsTier();
|
|
2421
2617
|
}
|
|
2422
2618
|
/**
|
|
2423
|
-
* Get
|
|
2424
|
-
* @
|
|
2425
|
-
* @returns Delegation info with total vEXA and delegator count
|
|
2619
|
+
* Get emergency withdrawal penalty for the connected wallet
|
|
2620
|
+
* @returns Penalty in basis points (5000 = 50% at start, 2000 = 20% near expiry)
|
|
2426
2621
|
*/
|
|
2427
|
-
async
|
|
2428
|
-
return this.staking.
|
|
2622
|
+
async getEmergencyWithdrawPenalty() {
|
|
2623
|
+
return this.staking.getEmergencyWithdrawPenalty();
|
|
2429
2624
|
}
|
|
2430
2625
|
/**
|
|
2431
2626
|
* Claim all pending staking rewards (EXA + multi-token)
|
|
@@ -2436,6 +2631,46 @@ var ExagentClient = class {
|
|
|
2436
2631
|
const multiTokenRewards = await this.staking.claimRewardsMulti();
|
|
2437
2632
|
return { exaRewards, multiTokenRewards };
|
|
2438
2633
|
}
|
|
2634
|
+
// ============ ERC-8004 Global Agent Identity ============
|
|
2635
|
+
/**
|
|
2636
|
+
* Get the ERC-8004 global agent identifier for the current agent
|
|
2637
|
+
*
|
|
2638
|
+
* Format: eip155:{chainId}:{registryAddress}:{agentId}
|
|
2639
|
+
*
|
|
2640
|
+
* This creates a universally unique identifier that can be used for
|
|
2641
|
+
* cross-protocol agent discovery and interoperability.
|
|
2642
|
+
*
|
|
2643
|
+
* @returns The global agent ID string
|
|
2644
|
+
* @throws Error if agent is not registered
|
|
2645
|
+
*
|
|
2646
|
+
* @example
|
|
2647
|
+
* ```typescript
|
|
2648
|
+
* const globalId = await exagent.getGlobalAgentId();
|
|
2649
|
+
* // => "eip155:8453:0xABC...DEF:42"
|
|
2650
|
+
* ```
|
|
2651
|
+
*/
|
|
2652
|
+
async getGlobalAgentId() {
|
|
2653
|
+
const agentId = await this.getAgentId();
|
|
2654
|
+
if (!agentId) throw new Error("Agent not registered");
|
|
2655
|
+
const chain = CHAIN_CONFIG[this.network];
|
|
2656
|
+
const addresses = CONTRACT_ADDRESSES[this.network];
|
|
2657
|
+
return buildGlobalAgentId(
|
|
2658
|
+
chain.id,
|
|
2659
|
+
addresses.agentRegistry,
|
|
2660
|
+
agentId
|
|
2661
|
+
);
|
|
2662
|
+
}
|
|
2663
|
+
/**
|
|
2664
|
+
* Build a global agent ID for any agent (static utility)
|
|
2665
|
+
*
|
|
2666
|
+
* @param chainId - EVM chain ID
|
|
2667
|
+
* @param registryAddress - ExagentRegistry contract address
|
|
2668
|
+
* @param agentId - On-chain agent ID
|
|
2669
|
+
* @returns ERC-8004 global agent identifier
|
|
2670
|
+
*/
|
|
2671
|
+
static buildGlobalAgentId(chainId, registryAddress, agentId) {
|
|
2672
|
+
return buildGlobalAgentId(chainId, registryAddress, agentId);
|
|
2673
|
+
}
|
|
2439
2674
|
// ============ Helpers ============
|
|
2440
2675
|
/**
|
|
2441
2676
|
* Get the agent's wallet address
|
|
@@ -2455,10 +2690,7 @@ var ExagentClient = class {
|
|
|
2455
2690
|
const apiUrl = EXAGENT_API_CONFIG[this.network];
|
|
2456
2691
|
const response = await fetch(`${apiUrl}/v1/metadata/upload`, {
|
|
2457
2692
|
method: "POST",
|
|
2458
|
-
headers:
|
|
2459
|
-
"Content-Type": "application/json",
|
|
2460
|
-
...this.apiKey && { "X-API-Key": this.apiKey }
|
|
2461
|
-
},
|
|
2693
|
+
headers: this.apiHeaders("application/json"),
|
|
2462
2694
|
body: JSON.stringify(metadata)
|
|
2463
2695
|
});
|
|
2464
2696
|
if (!response.ok) {
|
|
@@ -2467,12 +2699,16 @@ var ExagentClient = class {
|
|
|
2467
2699
|
const result = await response.json();
|
|
2468
2700
|
return result.uri;
|
|
2469
2701
|
}
|
|
2470
|
-
async signIntent(intent) {
|
|
2471
|
-
const message = JSON.stringify(intent);
|
|
2472
|
-
return this.walletClient.signMessage({ account: this.account, message });
|
|
2473
|
-
}
|
|
2474
2702
|
parseAgentIdFromReceipt(receipt) {
|
|
2475
|
-
|
|
2703
|
+
const registryAddress = this.registry.address.toLowerCase();
|
|
2704
|
+
for (const log of receipt.logs) {
|
|
2705
|
+
if (log.address.toLowerCase() !== registryAddress) continue;
|
|
2706
|
+
if (log.topics.length >= 2 && log.topics[1]) {
|
|
2707
|
+
const agentId = BigInt(log.topics[1]);
|
|
2708
|
+
return agentId;
|
|
2709
|
+
}
|
|
2710
|
+
}
|
|
2711
|
+
throw new Error("AgentRegistered event not found in transaction receipt");
|
|
2476
2712
|
}
|
|
2477
2713
|
};
|
|
2478
2714
|
|
|
@@ -2482,8 +2718,12 @@ var EXAGENT_VAULT_FACTORY_ABI = [
|
|
|
2482
2718
|
{ type: "function", name: "owner", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2483
2719
|
{ type: "function", name: "registry", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2484
2720
|
{ type: "function", name: "router", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2485
|
-
{ type: "function", name: "
|
|
2486
|
-
{ type: "function", name: "
|
|
2721
|
+
{ type: "function", name: "feeCollector", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2722
|
+
{ type: "function", name: "stakingContract", inputs: [], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2723
|
+
{ type: "function", name: "VERIFIED_VEXA_REQUIREMENT", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2724
|
+
{ type: "function", name: "MIN_SEED_AMOUNT", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2725
|
+
{ type: "function", name: "UNVERIFIED_CAP_MULTIPLIER", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2726
|
+
{ type: "function", name: "VERIFIED_CAP_MULTIPLIER", inputs: [], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
2487
2727
|
{ type: "function", name: "allowedAssets", inputs: [{ name: "asset", type: "address" }], outputs: [{ type: "bool" }], stateMutability: "view" },
|
|
2488
2728
|
{ type: "function", name: "vaults", inputs: [{ name: "agentId", type: "uint256" }, { name: "asset", type: "address" }], outputs: [{ type: "address" }], stateMutability: "view" },
|
|
2489
2729
|
{ type: "function", name: "agentVaultCount", inputs: [{ name: "agentId", type: "uint256" }], outputs: [{ type: "uint256" }], stateMutability: "view" },
|
|
@@ -2496,14 +2736,9 @@ var EXAGENT_VAULT_FACTORY_ABI = [
|
|
|
2496
2736
|
},
|
|
2497
2737
|
{
|
|
2498
2738
|
type: "function",
|
|
2499
|
-
name: "
|
|
2500
|
-
inputs: [],
|
|
2501
|
-
outputs: [
|
|
2502
|
-
{ name: "veXARequired", type: "uint256" },
|
|
2503
|
-
{ name: "burnFee", type: "uint256" },
|
|
2504
|
-
{ name: "stakingContract", type: "address" },
|
|
2505
|
-
{ name: "exaToken", type: "address" }
|
|
2506
|
-
],
|
|
2739
|
+
name: "canCreateVerifiedVault",
|
|
2740
|
+
inputs: [{ name: "agentId", type: "uint256" }],
|
|
2741
|
+
outputs: [{ name: "isVerified", type: "bool" }, { name: "reason", type: "string" }],
|
|
2507
2742
|
stateMutability: "view"
|
|
2508
2743
|
},
|
|
2509
2744
|
// Write functions
|
|
@@ -2513,6 +2748,7 @@ var EXAGENT_VAULT_FACTORY_ABI = [
|
|
|
2513
2748
|
inputs: [
|
|
2514
2749
|
{ name: "agentId", type: "uint256" },
|
|
2515
2750
|
{ name: "asset", type: "address" },
|
|
2751
|
+
{ name: "seedAmount", type: "uint256" },
|
|
2516
2752
|
{ name: "name", type: "string" },
|
|
2517
2753
|
{ name: "symbol", type: "string" },
|
|
2518
2754
|
{ name: "feeRecipient", type: "address" }
|
|
@@ -2554,50 +2790,51 @@ var ExagentVaultFactory = class {
|
|
|
2554
2790
|
this.address = factoryAddress;
|
|
2555
2791
|
this.publicClient = publicClient;
|
|
2556
2792
|
this.walletClient = walletClient;
|
|
2793
|
+
if (!chain) {
|
|
2794
|
+
throw new Error("Chain parameter is required");
|
|
2795
|
+
}
|
|
2557
2796
|
this.chain = chain;
|
|
2558
2797
|
this.account = account;
|
|
2559
2798
|
}
|
|
2560
2799
|
// ============ Read Functions ============
|
|
2561
2800
|
/**
|
|
2562
|
-
* Get vault creation requirements
|
|
2801
|
+
* Get vault creation requirements (mainnet: seed-based, no burn fee)
|
|
2563
2802
|
*/
|
|
2564
2803
|
async getRequirements() {
|
|
2565
|
-
|
|
2566
|
-
|
|
2804
|
+
const [veXARequired, minSeedAmount, unverifiedCapMultiplier, verifiedCapMultiplier, stakingContract] = await Promise.all([
|
|
2805
|
+
this.publicClient.readContract({
|
|
2567
2806
|
address: this.address,
|
|
2568
2807
|
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2569
|
-
functionName: "
|
|
2570
|
-
})
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
};
|
|
2600
|
-
}
|
|
2808
|
+
functionName: "VERIFIED_VEXA_REQUIREMENT"
|
|
2809
|
+
}),
|
|
2810
|
+
this.publicClient.readContract({
|
|
2811
|
+
address: this.address,
|
|
2812
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2813
|
+
functionName: "MIN_SEED_AMOUNT"
|
|
2814
|
+
}),
|
|
2815
|
+
this.publicClient.readContract({
|
|
2816
|
+
address: this.address,
|
|
2817
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2818
|
+
functionName: "UNVERIFIED_CAP_MULTIPLIER"
|
|
2819
|
+
}),
|
|
2820
|
+
this.publicClient.readContract({
|
|
2821
|
+
address: this.address,
|
|
2822
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2823
|
+
functionName: "VERIFIED_CAP_MULTIPLIER"
|
|
2824
|
+
}),
|
|
2825
|
+
this.publicClient.readContract({
|
|
2826
|
+
address: this.address,
|
|
2827
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2828
|
+
functionName: "stakingContract"
|
|
2829
|
+
})
|
|
2830
|
+
]);
|
|
2831
|
+
return {
|
|
2832
|
+
veXARequired,
|
|
2833
|
+
minSeedAmount,
|
|
2834
|
+
unverifiedCapMultiplier,
|
|
2835
|
+
verifiedCapMultiplier,
|
|
2836
|
+
stakingContract
|
|
2837
|
+
};
|
|
2601
2838
|
}
|
|
2602
2839
|
/**
|
|
2603
2840
|
* Check if an address can create a vault
|
|
@@ -2615,6 +2852,22 @@ var ExagentVaultFactory = class {
|
|
|
2615
2852
|
reason: result[1]
|
|
2616
2853
|
};
|
|
2617
2854
|
}
|
|
2855
|
+
/**
|
|
2856
|
+
* Check if an agent can create a verified vault (higher deposit cap)
|
|
2857
|
+
* @param agentId Agent ID to check
|
|
2858
|
+
*/
|
|
2859
|
+
async canCreateVerifiedVault(agentId) {
|
|
2860
|
+
const result = await this.publicClient.readContract({
|
|
2861
|
+
address: this.address,
|
|
2862
|
+
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2863
|
+
functionName: "canCreateVerifiedVault",
|
|
2864
|
+
args: [agentId]
|
|
2865
|
+
});
|
|
2866
|
+
return {
|
|
2867
|
+
isVerified: result[0],
|
|
2868
|
+
reason: result[1]
|
|
2869
|
+
};
|
|
2870
|
+
}
|
|
2618
2871
|
/**
|
|
2619
2872
|
* Check if an asset is whitelisted for vault creation
|
|
2620
2873
|
* @param asset Asset address to check
|
|
@@ -2664,8 +2917,8 @@ var ExagentVaultFactory = class {
|
|
|
2664
2917
|
}
|
|
2665
2918
|
// ============ Write Functions ============
|
|
2666
2919
|
/**
|
|
2667
|
-
* Create a new vault for an agent
|
|
2668
|
-
* @param options Vault creation options
|
|
2920
|
+
* Create a new vault for an agent (mainnet: requires seed amount)
|
|
2921
|
+
* @param options Vault creation options including seedAmount
|
|
2669
2922
|
* @returns Transaction hash
|
|
2670
2923
|
*/
|
|
2671
2924
|
async createVault(options) {
|
|
@@ -2677,7 +2930,7 @@ var ExagentVaultFactory = class {
|
|
|
2677
2930
|
address: this.address,
|
|
2678
2931
|
abi: EXAGENT_VAULT_FACTORY_ABI,
|
|
2679
2932
|
functionName: "createVault",
|
|
2680
|
-
args: [options.agentId, options.asset, options.name, options.symbol, feeRecipient],
|
|
2933
|
+
args: [options.agentId, options.asset, options.seedAmount, options.name, options.symbol, feeRecipient],
|
|
2681
2934
|
account: this.account,
|
|
2682
2935
|
chain: this.chain
|
|
2683
2936
|
});
|
|
@@ -2688,7 +2941,7 @@ var ExagentVaultFactory = class {
|
|
|
2688
2941
|
* Check all requirements and create a vault if possible
|
|
2689
2942
|
* Returns detailed status about each requirement
|
|
2690
2943
|
*/
|
|
2691
|
-
async checkAndCreateVault(agentId, asset, name, symbol, feeRecipient) {
|
|
2944
|
+
async checkAndCreateVault(agentId, asset, seedAmount, name, symbol, feeRecipient) {
|
|
2692
2945
|
const [canCreateResult, assetAllowed, hasExisting] = await Promise.all([
|
|
2693
2946
|
this.canCreateVault(this.account?.address ?? "0x0000000000000000000000000000000000000000"),
|
|
2694
2947
|
this.isAssetAllowed(asset),
|
|
@@ -2727,6 +2980,7 @@ var ExagentVaultFactory = class {
|
|
|
2727
2980
|
const txHash = await this.createVault({
|
|
2728
2981
|
agentId,
|
|
2729
2982
|
asset,
|
|
2983
|
+
seedAmount,
|
|
2730
2984
|
name,
|
|
2731
2985
|
symbol,
|
|
2732
2986
|
feeRecipient
|
|
@@ -2756,28 +3010,11 @@ var ExagentVaultFactory = class {
|
|
|
2756
3010
|
}
|
|
2757
3011
|
}
|
|
2758
3012
|
};
|
|
2759
|
-
|
|
2760
|
-
// src/index.ts
|
|
2761
|
-
var TESTNET_ADDRESSES = {
|
|
2762
|
-
registry: "0xCF48C341e3FebeCA5ECB7eb2535f61A2Ba855d9C",
|
|
2763
|
-
// V4 UUPS proxy
|
|
2764
|
-
token: "0x66c39b0ad96B3f5eE198Fef913c6636353a48A87",
|
|
2765
|
-
staking: "0x439441468e1b1b616E9D36b80969C241F261A011",
|
|
2766
|
-
router: "0xc0c27eEE047E414CD716D06C2444CF2073113d5C",
|
|
2767
|
-
// V3 with config epochs
|
|
2768
|
-
vaultFactory: "0x5c099daaE33801a907Bb57011c6749655b55dc75",
|
|
2769
|
-
feeCollector: "0xcB57b03a50df054b9C738Df1324C17A4fDe4fe46",
|
|
2770
|
-
buyback: "0x35cdEa810A130A846265682e5c71A68A507aB895",
|
|
2771
|
-
serviceEscrow: "0x74a3496b148DEE735ac388299aF9Ac2F7C4EdCBf",
|
|
2772
|
-
usdc: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
|
|
2773
|
-
// Circle's Base Sepolia USDC (only vault asset)
|
|
2774
|
-
};
|
|
2775
3013
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2776
3014
|
0 && (module.exports = {
|
|
2777
3015
|
CHAIN_CONFIG,
|
|
2778
3016
|
CONTRACT_ADDRESSES,
|
|
2779
3017
|
DEX_ADDRESSES,
|
|
2780
|
-
DISCOUNT_TIERS,
|
|
2781
3018
|
EXAGENT_API_CONFIG,
|
|
2782
3019
|
EXAGENT_STAKING_ABI,
|
|
2783
3020
|
EXAGENT_VAULT_FACTORY_ABI,
|
|
@@ -2786,6 +3023,8 @@ var TESTNET_ADDRESSES = {
|
|
|
2786
3023
|
ExagentStaking,
|
|
2787
3024
|
ExagentVault,
|
|
2788
3025
|
ExagentVaultFactory,
|
|
2789
|
-
|
|
2790
|
-
ZERO_X_CONFIG
|
|
3026
|
+
SDK_VERSION,
|
|
3027
|
+
ZERO_X_CONFIG,
|
|
3028
|
+
buildGlobalAgentId,
|
|
3029
|
+
parseGlobalAgentId
|
|
2791
3030
|
});
|