@moltium/world-core 0.1.22 → 0.1.24
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/{CardFetcher-4ENWKI6E.js → CardFetcher-IMUPYNEQ.js} +2 -2
- package/dist/CardFetcher-ZD4YSGJE.cjs +9 -0
- package/dist/{CardFetcher-UCJGPZ7X.cjs.map → CardFetcher-ZD4YSGJE.cjs.map} +1 -1
- package/dist/{chunk-DHQFXIEW.cjs → chunk-WI7EASJJ.cjs} +30 -6
- package/dist/chunk-WI7EASJJ.cjs.map +1 -0
- package/dist/{chunk-DWXNX5V3.js → chunk-Y563WZWH.js} +30 -6
- package/dist/chunk-Y563WZWH.js.map +1 -0
- package/dist/index.cjs +280 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +95 -66
- package/dist/index.d.ts +95 -66
- package/dist/index.js +241 -15
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/CardFetcher-UCJGPZ7X.cjs +0 -9
- package/dist/chunk-DHQFXIEW.cjs.map +0 -1
- package/dist/chunk-DWXNX5V3.js.map +0 -1
- /package/dist/{CardFetcher-4ENWKI6E.js.map → CardFetcher-IMUPYNEQ.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4;
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5;
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkWI7EASJJcjs = require('./chunk-WI7EASJJ.cjs');
|
|
7
7
|
|
|
8
8
|
// src/config/types.ts
|
|
9
9
|
function profileFromCard(card, walletAddress) {
|
|
@@ -430,7 +430,7 @@ async function createLevelDBAdapter(config) {
|
|
|
430
430
|
var _uuid = require('uuid');
|
|
431
431
|
|
|
432
432
|
// src/discovery/AgentEvaluator.ts
|
|
433
|
-
var logger2 =
|
|
433
|
+
var logger2 = _chunkWI7EASJJcjs.createLogger.call(void 0, "AgentEvaluator");
|
|
434
434
|
var AgentEvaluator = class {
|
|
435
435
|
constructor(rules) {
|
|
436
436
|
this.rules = rules;
|
|
@@ -544,7 +544,7 @@ var AgentEvaluator = class {
|
|
|
544
544
|
|
|
545
545
|
// src/blockchain/BlockchainClient.ts
|
|
546
546
|
var _ethers = require('ethers');
|
|
547
|
-
var logger3 =
|
|
547
|
+
var logger3 = _chunkWI7EASJJcjs.createLogger.call(void 0, "BlockchainClient");
|
|
548
548
|
var AGENT_REGISTRY_ABI = [
|
|
549
549
|
"function registerAgent(string agentUrl, string name) external",
|
|
550
550
|
"function isAgentValid(address wallet) external view returns (bool)",
|
|
@@ -567,8 +567,8 @@ var WORLD_TOKEN_ABI = [
|
|
|
567
567
|
"function balanceOf(address account) external view returns (uint256)",
|
|
568
568
|
"function transfer(address to, uint256 amount) external returns (bool)"
|
|
569
569
|
];
|
|
570
|
-
var BlockchainClient = class {
|
|
571
|
-
constructor(config) {
|
|
570
|
+
var BlockchainClient = (_class2 = class {
|
|
571
|
+
constructor(config) {;_class2.prototype.__init4.call(this);
|
|
572
572
|
this.config = config;
|
|
573
573
|
this.provider = new _ethers.ethers.JsonRpcProvider(config.rpcUrl);
|
|
574
574
|
this.wallet = new _ethers.ethers.Wallet(config.privateKey, this.provider);
|
|
@@ -766,7 +766,7 @@ var BlockchainClient = class {
|
|
|
766
766
|
return this.wallet.address;
|
|
767
767
|
}
|
|
768
768
|
/**
|
|
769
|
-
* Get entry fee in MON
|
|
769
|
+
* Get entry fee in MON (formatted)
|
|
770
770
|
*/
|
|
771
771
|
async getEntryFee() {
|
|
772
772
|
if (!this.membershipContract) {
|
|
@@ -780,13 +780,85 @@ var BlockchainClient = class {
|
|
|
780
780
|
return "0";
|
|
781
781
|
}
|
|
782
782
|
}
|
|
783
|
-
|
|
783
|
+
/**
|
|
784
|
+
* Get entry fee in wei (raw BigInt string)
|
|
785
|
+
*/
|
|
786
|
+
async getEntryFeeWei() {
|
|
787
|
+
if (!this.membershipContract) {
|
|
788
|
+
return "0";
|
|
789
|
+
}
|
|
790
|
+
try {
|
|
791
|
+
const fee = await this.membershipContract.entryFee();
|
|
792
|
+
return fee.toString();
|
|
793
|
+
} catch (error) {
|
|
794
|
+
logger3.error("Failed to get entry fee (wei)", { error: error.message });
|
|
795
|
+
return "0";
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
// Track used payment tx hashes to prevent replay attacks
|
|
799
|
+
__init4() {this.usedPayments = /* @__PURE__ */ new Set()}
|
|
800
|
+
/**
|
|
801
|
+
* Verify a payment transaction from an agent.
|
|
802
|
+
* Checks: tx confirmed, correct sender, correct recipient (world wallet), sufficient amount.
|
|
803
|
+
* Prevents replay attacks by tracking used tx hashes.
|
|
804
|
+
*/
|
|
805
|
+
async verifyPayment(txHash, expectedSender, expectedAmountWei) {
|
|
806
|
+
const normalizedHash = txHash.toLowerCase();
|
|
807
|
+
if (this.usedPayments.has(normalizedHash)) {
|
|
808
|
+
logger3.warn("Payment verification: transaction already used", { txHash });
|
|
809
|
+
return false;
|
|
810
|
+
}
|
|
811
|
+
try {
|
|
812
|
+
const receipt = await this.provider.getTransactionReceipt(txHash);
|
|
813
|
+
if (!receipt || receipt.status !== 1) {
|
|
814
|
+
logger3.warn("Payment verification: transaction not confirmed or failed", { txHash });
|
|
815
|
+
return false;
|
|
816
|
+
}
|
|
817
|
+
const tx = await this.provider.getTransaction(txHash);
|
|
818
|
+
if (!tx) {
|
|
819
|
+
logger3.warn("Payment verification: transaction not found", { txHash });
|
|
820
|
+
return false;
|
|
821
|
+
}
|
|
822
|
+
if (tx.from.toLowerCase() !== expectedSender.toLowerCase()) {
|
|
823
|
+
logger3.warn("Payment verification: wrong sender", {
|
|
824
|
+
expected: expectedSender,
|
|
825
|
+
actual: tx.from
|
|
826
|
+
});
|
|
827
|
+
return false;
|
|
828
|
+
}
|
|
829
|
+
if (_optionalChain([tx, 'access', _13 => _13.to, 'optionalAccess', _14 => _14.toLowerCase, 'call', _15 => _15()]) !== this.wallet.address.toLowerCase()) {
|
|
830
|
+
logger3.warn("Payment verification: wrong recipient", {
|
|
831
|
+
expected: this.wallet.address,
|
|
832
|
+
actual: tx.to
|
|
833
|
+
});
|
|
834
|
+
return false;
|
|
835
|
+
}
|
|
836
|
+
if (tx.value < BigInt(expectedAmountWei)) {
|
|
837
|
+
logger3.warn("Payment verification: insufficient amount", {
|
|
838
|
+
expected: expectedAmountWei,
|
|
839
|
+
actual: tx.value.toString()
|
|
840
|
+
});
|
|
841
|
+
return false;
|
|
842
|
+
}
|
|
843
|
+
this.usedPayments.add(normalizedHash);
|
|
844
|
+
logger3.info("Payment verified successfully", {
|
|
845
|
+
txHash,
|
|
846
|
+
sender: tx.from,
|
|
847
|
+
amount: _ethers.ethers.formatEther(tx.value)
|
|
848
|
+
});
|
|
849
|
+
return true;
|
|
850
|
+
} catch (error) {
|
|
851
|
+
logger3.error("Payment verification error", { txHash, error: error.message });
|
|
852
|
+
return false;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}, _class2);
|
|
784
856
|
|
|
785
857
|
// src/a2a/WorldA2AClient.ts
|
|
786
858
|
var _core = require('@moltium/core');
|
|
787
|
-
var logger4 =
|
|
788
|
-
var WorldA2AClient = (
|
|
789
|
-
|
|
859
|
+
var logger4 = _chunkWI7EASJJcjs.createLogger.call(void 0, "WorldA2AClient");
|
|
860
|
+
var WorldA2AClient = (_class3 = class {constructor() { _class3.prototype.__init5.call(this); }
|
|
861
|
+
__init5() {this.clients = /* @__PURE__ */ new Map()}
|
|
790
862
|
/**
|
|
791
863
|
* Add an agent to the client pool
|
|
792
864
|
*/
|
|
@@ -827,7 +899,7 @@ var WorldA2AClient = (_class2 = class {constructor() { _class2.prototype.__init4
|
|
|
827
899
|
logger4.error(`Failed to send A2A message to ${agentUrl}:`, error);
|
|
828
900
|
return {
|
|
829
901
|
success: false,
|
|
830
|
-
error: _optionalChain([error, 'optionalAccess',
|
|
902
|
+
error: _optionalChain([error, 'optionalAccess', _16 => _16.message]) || String(error),
|
|
831
903
|
agentUrl
|
|
832
904
|
};
|
|
833
905
|
}
|
|
@@ -879,12 +951,12 @@ var WorldA2AClient = (_class2 = class {constructor() { _class2.prototype.__init4
|
|
|
879
951
|
return url;
|
|
880
952
|
}
|
|
881
953
|
}
|
|
882
|
-
},
|
|
954
|
+
}, _class3);
|
|
883
955
|
|
|
884
956
|
// src/engine/WorldActions.ts
|
|
885
|
-
var logger5 =
|
|
886
|
-
var WorldActionsRegistry = (
|
|
887
|
-
|
|
957
|
+
var logger5 = _chunkWI7EASJJcjs.createLogger.call(void 0, "WorldActions");
|
|
958
|
+
var WorldActionsRegistry = (_class4 = class {constructor() { _class4.prototype.__init6.call(this); }
|
|
959
|
+
__init6() {this.actions = /* @__PURE__ */ new Map()}
|
|
888
960
|
/**
|
|
889
961
|
* Register a world action
|
|
890
962
|
*/
|
|
@@ -974,11 +1046,11 @@ var WorldActionsRegistry = (_class3 = class {constructor() { _class3.prototype._
|
|
|
974
1046
|
...a.parameters && { parameters: a.parameters }
|
|
975
1047
|
}));
|
|
976
1048
|
}
|
|
977
|
-
},
|
|
1049
|
+
}, _class4);
|
|
978
1050
|
|
|
979
1051
|
// src/engine/ActionProcessor.ts
|
|
980
1052
|
|
|
981
|
-
var logger6 =
|
|
1053
|
+
var logger6 = _chunkWI7EASJJcjs.createLogger.call(void 0, "ActionProcessor");
|
|
982
1054
|
var ActionProcessor = class {
|
|
983
1055
|
constructor(rules, actionsRegistry) {
|
|
984
1056
|
this.rules = rules;
|
|
@@ -1080,16 +1152,16 @@ var ActionProcessor = class {
|
|
|
1080
1152
|
|
|
1081
1153
|
// src/engine/TickOrchestrator.ts
|
|
1082
1154
|
|
|
1083
|
-
var logger7 =
|
|
1155
|
+
var logger7 = _chunkWI7EASJJcjs.createLogger.call(void 0, "TickOrchestrator");
|
|
1084
1156
|
var TickOrchestrator = class {
|
|
1085
1157
|
constructor(a2aClient, actionsRegistry, rules, config) {
|
|
1086
1158
|
this.a2aClient = a2aClient;
|
|
1087
1159
|
this.actionsRegistry = actionsRegistry;
|
|
1088
1160
|
this.actionProcessor = new ActionProcessor(rules, actionsRegistry);
|
|
1089
1161
|
this.orchestrationConfig = {
|
|
1090
|
-
broadcastOnTick: _nullishCoalesce(_optionalChain([config, 'optionalAccess',
|
|
1091
|
-
tickTimeout: _nullishCoalesce(_optionalChain([config, 'optionalAccess',
|
|
1092
|
-
promptTemplate: _optionalChain([config, 'optionalAccess',
|
|
1162
|
+
broadcastOnTick: _nullishCoalesce(_optionalChain([config, 'optionalAccess', _17 => _17.broadcastOnTick]), () => ( true)),
|
|
1163
|
+
tickTimeout: _nullishCoalesce(_optionalChain([config, 'optionalAccess', _18 => _18.tickTimeout]), () => ( 1e4)),
|
|
1164
|
+
promptTemplate: _optionalChain([config, 'optionalAccess', _19 => _19.promptTemplate])
|
|
1093
1165
|
};
|
|
1094
1166
|
}
|
|
1095
1167
|
|
|
@@ -1245,31 +1317,72 @@ var TickOrchestrator = class {
|
|
|
1245
1317
|
};
|
|
1246
1318
|
|
|
1247
1319
|
// src/a2a/MessageRouter.ts
|
|
1248
|
-
var logger8 =
|
|
1320
|
+
var logger8 = _chunkWI7EASJJcjs.createLogger.call(void 0, "MessageRouter");
|
|
1321
|
+
var c = {
|
|
1322
|
+
reset: "\x1B[0m",
|
|
1323
|
+
bold: "\x1B[1m",
|
|
1324
|
+
dim: "\x1B[2m",
|
|
1325
|
+
blue: "\x1B[34m",
|
|
1326
|
+
green: "\x1B[32m",
|
|
1327
|
+
yellow: "\x1B[33m",
|
|
1328
|
+
magenta: "\x1B[35m",
|
|
1329
|
+
cyan: "\x1B[36m",
|
|
1330
|
+
red: "\x1B[31m",
|
|
1331
|
+
gray: "\x1B[90m"
|
|
1332
|
+
};
|
|
1249
1333
|
var MessageRouter = class {
|
|
1250
1334
|
constructor(a2aClient, getAgents) {
|
|
1251
1335
|
this.a2aClient = a2aClient;
|
|
1252
1336
|
this.getAgents = getAgents;
|
|
1253
1337
|
}
|
|
1338
|
+
/**
|
|
1339
|
+
* Extract base URL (protocol://host:port) from a full URL for comparison.
|
|
1340
|
+
* Agent cards use full URLs (e.g. http://localhost:3001/a2a/jsonrpc)
|
|
1341
|
+
* while agents send base URLs (e.g. http://localhost:3001).
|
|
1342
|
+
*/
|
|
1343
|
+
extractBaseUrl(url) {
|
|
1344
|
+
try {
|
|
1345
|
+
const parsed = new URL(url);
|
|
1346
|
+
return `${parsed.protocol}//${parsed.host}`;
|
|
1347
|
+
} catch (e6) {
|
|
1348
|
+
return url;
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
/**
|
|
1352
|
+
* Find an agent by URL, normalizing both sides to base URL for comparison
|
|
1353
|
+
*/
|
|
1354
|
+
findAgent(agents, url) {
|
|
1355
|
+
const baseUrl = this.extractBaseUrl(url);
|
|
1356
|
+
return agents.find((a) => this.extractBaseUrl(a.url) === baseUrl);
|
|
1357
|
+
}
|
|
1254
1358
|
/**
|
|
1255
1359
|
* Route a message from one agent to another
|
|
1256
1360
|
*/
|
|
1257
1361
|
async route(fromAgentUrl, toAgentUrl, message) {
|
|
1258
1362
|
const agents = this.getAgents();
|
|
1259
|
-
const sender =
|
|
1363
|
+
const sender = this.findAgent(agents, fromAgentUrl);
|
|
1260
1364
|
if (!sender) {
|
|
1365
|
+
logger8.warn(`Message rejected \u2014 sender not in world: ${fromAgentUrl}`);
|
|
1261
1366
|
return {
|
|
1262
1367
|
success: false,
|
|
1263
1368
|
error: `Sender not in world: ${fromAgentUrl}`
|
|
1264
1369
|
};
|
|
1265
1370
|
}
|
|
1266
|
-
const recipient =
|
|
1371
|
+
const recipient = this.findAgent(agents, toAgentUrl);
|
|
1267
1372
|
if (!recipient) {
|
|
1373
|
+
logger8.warn(`Message rejected \u2014 recipient not in world: ${toAgentUrl}`);
|
|
1268
1374
|
return {
|
|
1269
1375
|
success: false,
|
|
1270
1376
|
error: `Recipient not in world: ${toAgentUrl}`
|
|
1271
1377
|
};
|
|
1272
1378
|
}
|
|
1379
|
+
console.log(
|
|
1380
|
+
`
|
|
1381
|
+
${c.cyan}\u2501\u2501\u2501 MESSAGE \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${c.reset}
|
|
1382
|
+
${c.bold}${c.blue}${sender.name}${c.reset} ${c.dim}\u2192${c.reset} ${c.bold}${c.green}${recipient.name}${c.reset}
|
|
1383
|
+
${c.dim}\u2502${c.reset} ${this.truncate(message, 300)}
|
|
1384
|
+
${c.cyan}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${c.reset}`
|
|
1385
|
+
);
|
|
1273
1386
|
const wrappedMessage = JSON.stringify({
|
|
1274
1387
|
type: "world_message",
|
|
1275
1388
|
from: {
|
|
@@ -1279,19 +1392,33 @@ var MessageRouter = class {
|
|
|
1279
1392
|
},
|
|
1280
1393
|
message
|
|
1281
1394
|
});
|
|
1282
|
-
|
|
1283
|
-
return this.a2aClient.sendToAgent(toAgentUrl, wrappedMessage, {
|
|
1395
|
+
const response = await this.a2aClient.sendToAgent(toAgentUrl, wrappedMessage, {
|
|
1284
1396
|
type: "world_message",
|
|
1285
1397
|
fromAgentUrl
|
|
1286
1398
|
});
|
|
1399
|
+
if (response.success && response.reply) {
|
|
1400
|
+
console.log(
|
|
1401
|
+
`
|
|
1402
|
+
${c.green}\u2501\u2501\u2501 REPLY \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${c.reset}
|
|
1403
|
+
${c.bold}${c.green}${recipient.name}${c.reset} ${c.dim}\u2192${c.reset} ${c.bold}${c.blue}${sender.name}${c.reset}
|
|
1404
|
+
${c.dim}\u2502${c.reset} ${this.truncate(response.reply, 300)}
|
|
1405
|
+
${c.green}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${c.reset}`
|
|
1406
|
+
);
|
|
1407
|
+
} else if (!response.success) {
|
|
1408
|
+
console.log(
|
|
1409
|
+
`${c.red} \u2717 ${recipient.name} failed to respond: ${response.error || "no response"}${c.reset}`
|
|
1410
|
+
);
|
|
1411
|
+
}
|
|
1412
|
+
return response;
|
|
1287
1413
|
}
|
|
1288
1414
|
/**
|
|
1289
1415
|
* Broadcast a message from one agent to all other agents in the world
|
|
1290
1416
|
*/
|
|
1291
1417
|
async routeToAll(fromAgentUrl, message) {
|
|
1292
1418
|
const agents = this.getAgents();
|
|
1293
|
-
const sender =
|
|
1419
|
+
const sender = this.findAgent(agents, fromAgentUrl);
|
|
1294
1420
|
if (!sender) {
|
|
1421
|
+
logger8.warn(`Broadcast rejected \u2014 sender not in world: ${fromAgentUrl}`);
|
|
1295
1422
|
const result = /* @__PURE__ */ new Map();
|
|
1296
1423
|
result.set(fromAgentUrl, {
|
|
1297
1424
|
success: false,
|
|
@@ -1299,6 +1426,15 @@ var MessageRouter = class {
|
|
|
1299
1426
|
});
|
|
1300
1427
|
return result;
|
|
1301
1428
|
}
|
|
1429
|
+
const senderBaseUrl = this.extractBaseUrl(fromAgentUrl);
|
|
1430
|
+
const recipients = agents.filter((a) => this.extractBaseUrl(a.url) !== senderBaseUrl);
|
|
1431
|
+
console.log(
|
|
1432
|
+
`
|
|
1433
|
+
${c.yellow}\u2501\u2501\u2501 BROADCAST \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${c.reset}
|
|
1434
|
+
${c.bold}${c.blue}${sender.name}${c.reset} ${c.dim}\u2192${c.reset} ${c.bold}${c.yellow}ALL (${recipients.length} agents)${c.reset}
|
|
1435
|
+
${c.dim}\u2502${c.reset} ${this.truncate(message, 300)}
|
|
1436
|
+
${c.yellow}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${c.reset}`
|
|
1437
|
+
);
|
|
1302
1438
|
const wrappedMessage = JSON.stringify({
|
|
1303
1439
|
type: "world_broadcast",
|
|
1304
1440
|
from: {
|
|
@@ -1309,7 +1445,6 @@ var MessageRouter = class {
|
|
|
1309
1445
|
message
|
|
1310
1446
|
});
|
|
1311
1447
|
const results = /* @__PURE__ */ new Map();
|
|
1312
|
-
const recipients = agents.filter((a) => a.url !== fromAgentUrl);
|
|
1313
1448
|
const promises = recipients.map(async (recipient) => {
|
|
1314
1449
|
const response = await this.a2aClient.sendToAgent(
|
|
1315
1450
|
recipient.url,
|
|
@@ -1317,17 +1452,38 @@ var MessageRouter = class {
|
|
|
1317
1452
|
{ type: "world_broadcast", fromAgentUrl }
|
|
1318
1453
|
);
|
|
1319
1454
|
results.set(recipient.url, response);
|
|
1455
|
+
if (response.success && response.reply) {
|
|
1456
|
+
console.log(
|
|
1457
|
+
`${c.green} \u21A9 ${c.bold}${recipient.name}${c.reset}${c.green} replied:${c.reset} ${this.truncate(response.reply, 200)}`
|
|
1458
|
+
);
|
|
1459
|
+
} else if (!response.success) {
|
|
1460
|
+
console.log(
|
|
1461
|
+
`${c.red} \u2717 ${recipient.name} failed: ${response.error || "no response"}${c.reset}`
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1320
1464
|
});
|
|
1321
1465
|
await Promise.allSettled(promises);
|
|
1322
|
-
|
|
1466
|
+
const succeeded = Array.from(results.values()).filter((r) => r.success).length;
|
|
1467
|
+
const failed = Array.from(results.values()).filter((r) => !r.success).length;
|
|
1468
|
+
console.log(
|
|
1469
|
+
`${c.dim} Broadcast complete: ${c.green}${succeeded} replied${c.reset}${c.dim}${failed > 0 ? `, ${c.red}${failed} failed${c.reset}` : ""}${c.reset}
|
|
1470
|
+
`
|
|
1471
|
+
);
|
|
1323
1472
|
return results;
|
|
1324
1473
|
}
|
|
1474
|
+
/**
|
|
1475
|
+
* Truncate long messages for logging
|
|
1476
|
+
*/
|
|
1477
|
+
truncate(text, maxLen) {
|
|
1478
|
+
if (text.length <= maxLen) return text;
|
|
1479
|
+
return text.slice(0, maxLen) + "...";
|
|
1480
|
+
}
|
|
1325
1481
|
};
|
|
1326
1482
|
|
|
1327
1483
|
// src/engine/World.ts
|
|
1328
|
-
var logger9 =
|
|
1329
|
-
var World = (
|
|
1330
|
-
constructor(config) {;
|
|
1484
|
+
var logger9 = _chunkWI7EASJJcjs.createLogger.call(void 0, "World");
|
|
1485
|
+
var World = (_class5 = class {
|
|
1486
|
+
constructor(config) {;_class5.prototype.__init7.call(this);_class5.prototype.__init8.call(this);_class5.prototype.__init9.call(this);_class5.prototype.__init10.call(this);
|
|
1331
1487
|
this.config = config;
|
|
1332
1488
|
validateWorldConfig(config);
|
|
1333
1489
|
this.state = {
|
|
@@ -1338,7 +1494,7 @@ var World = (_class4 = class {
|
|
|
1338
1494
|
metadata: {}
|
|
1339
1495
|
};
|
|
1340
1496
|
this.agents = /* @__PURE__ */ new Map();
|
|
1341
|
-
this.cardFetcher = new (0,
|
|
1497
|
+
this.cardFetcher = new (0, _chunkWI7EASJJcjs.CardFetcher)();
|
|
1342
1498
|
this.evaluator = new AgentEvaluator(config.admission);
|
|
1343
1499
|
this.a2aClient = new WorldA2AClient();
|
|
1344
1500
|
this.actionsRegistry = new WorldActionsRegistry();
|
|
@@ -1359,17 +1515,17 @@ var World = (_class4 = class {
|
|
|
1359
1515
|
logger9.info(`World "${config.name}" created`, {
|
|
1360
1516
|
type: config.type || "generic",
|
|
1361
1517
|
maxAgents: config.admission.maxAgents,
|
|
1362
|
-
orchestration: !!_optionalChain([config, 'access',
|
|
1518
|
+
orchestration: !!_optionalChain([config, 'access', _20 => _20.orchestration, 'optionalAccess', _21 => _21.broadcastOnTick])
|
|
1363
1519
|
});
|
|
1364
1520
|
}
|
|
1365
1521
|
|
|
1366
1522
|
|
|
1367
|
-
|
|
1368
|
-
|
|
1523
|
+
__init7() {this.persistence = null}
|
|
1524
|
+
__init8() {this.blockchainClient = null}
|
|
1369
1525
|
|
|
1370
1526
|
|
|
1371
|
-
|
|
1372
|
-
|
|
1527
|
+
__init9() {this.tickInterval = null}
|
|
1528
|
+
__init10() {this.autoSaveInterval = null}
|
|
1373
1529
|
// Agent-World bridge components
|
|
1374
1530
|
|
|
1375
1531
|
|
|
@@ -1425,7 +1581,7 @@ var World = (_class4 = class {
|
|
|
1425
1581
|
this.setState("ready");
|
|
1426
1582
|
logger9.info("World initialized successfully", {
|
|
1427
1583
|
agents: this.agents.size,
|
|
1428
|
-
persistence: _optionalChain([this, 'access',
|
|
1584
|
+
persistence: _optionalChain([this, 'access', _22 => _22.config, 'access', _23 => _23.persistence, 'optionalAccess', _24 => _24.type]) || "none"
|
|
1429
1585
|
});
|
|
1430
1586
|
} catch (error) {
|
|
1431
1587
|
logger9.error("Failed to initialize world:", error);
|
|
@@ -1448,7 +1604,7 @@ var World = (_class4 = class {
|
|
|
1448
1604
|
type: "world_started",
|
|
1449
1605
|
timestamp: Date.now()
|
|
1450
1606
|
});
|
|
1451
|
-
if (_optionalChain([this, 'access',
|
|
1607
|
+
if (_optionalChain([this, 'access', _25 => _25.config, 'access', _26 => _26.simulation, 'optionalAccess', _27 => _27.tickIntervalMs])) {
|
|
1452
1608
|
this.startTicking();
|
|
1453
1609
|
}
|
|
1454
1610
|
}
|
|
@@ -1476,24 +1632,61 @@ var World = (_class4 = class {
|
|
|
1476
1632
|
});
|
|
1477
1633
|
logger9.info("World stopped");
|
|
1478
1634
|
}
|
|
1635
|
+
/**
|
|
1636
|
+
* Get the blockchain client (for server endpoints)
|
|
1637
|
+
*/
|
|
1638
|
+
getBlockchainClient() {
|
|
1639
|
+
return this.blockchainClient;
|
|
1640
|
+
}
|
|
1479
1641
|
/**
|
|
1480
1642
|
* Admit an agent to the world
|
|
1481
1643
|
*/
|
|
1482
|
-
async admitAgent(card, walletAddress) {
|
|
1644
|
+
async admitAgent(card, walletAddress, paymentTxHash) {
|
|
1645
|
+
if (this.agents.has(card.url)) {
|
|
1646
|
+
logger9.info(`Agent already in world, skipping re-admission: ${card.name}`);
|
|
1647
|
+
return;
|
|
1648
|
+
}
|
|
1483
1649
|
const decision = await this.evaluator.evaluate(card, this.agents.size, walletAddress);
|
|
1484
1650
|
if (!decision.admitted) {
|
|
1485
1651
|
throw new Error(`Agent admission denied: ${decision.reason}`);
|
|
1486
1652
|
}
|
|
1487
|
-
if (this.blockchainClient && _optionalChain([this, 'access',
|
|
1653
|
+
if (this.blockchainClient && _optionalChain([this, 'access', _28 => _28.config, 'access', _29 => _29.blockchain, 'optionalAccess', _30 => _30.enforceOnChainValidation]) && walletAddress) {
|
|
1488
1654
|
const isValid = await this.blockchainClient.validateAgent(walletAddress);
|
|
1489
1655
|
if (!isValid) {
|
|
1490
1656
|
throw new Error("Agent not registered in on-chain AgentRegistry");
|
|
1491
1657
|
}
|
|
1492
1658
|
logger9.info(`Agent validated on-chain: ${card.name}`);
|
|
1493
1659
|
}
|
|
1494
|
-
if (this.blockchainClient && _optionalChain([this, 'access',
|
|
1660
|
+
if (this.blockchainClient && _optionalChain([this, 'access', _31 => _31.config, 'access', _32 => _32.blockchain, 'optionalAccess', _33 => _33.requireMembership])) {
|
|
1661
|
+
if (!walletAddress) {
|
|
1662
|
+
throw new Error(
|
|
1663
|
+
"This world requires blockchain membership. Provide a walletAddress when joining. Set AGENT_WALLET_PRIVATE_KEY in your .env file to auto-derive a wallet address."
|
|
1664
|
+
);
|
|
1665
|
+
}
|
|
1495
1666
|
const hasMembership = await this.blockchainClient.hasMembership(walletAddress);
|
|
1496
1667
|
if (!hasMembership) {
|
|
1668
|
+
const entryFeeWei = await this.blockchainClient.getEntryFeeWei();
|
|
1669
|
+
if (entryFeeWei !== "0" && BigInt(entryFeeWei) > 0n) {
|
|
1670
|
+
if (!paymentTxHash) {
|
|
1671
|
+
throw new Error(
|
|
1672
|
+
`Entry fee required: ${entryFeeWei} wei. Query GET /world/join-info for payment details, pay the fee, then include paymentTxHash in your join request.`
|
|
1673
|
+
);
|
|
1674
|
+
}
|
|
1675
|
+
const paymentValid = await this.blockchainClient.verifyPayment(
|
|
1676
|
+
paymentTxHash,
|
|
1677
|
+
walletAddress,
|
|
1678
|
+
entryFeeWei
|
|
1679
|
+
);
|
|
1680
|
+
if (!paymentValid) {
|
|
1681
|
+
throw new Error(
|
|
1682
|
+
`Payment verification failed for tx ${paymentTxHash}. Ensure the transaction is confirmed, sent from ${walletAddress}, to ${this.blockchainClient.getWalletAddress()}, for at least ${entryFeeWei} wei.`
|
|
1683
|
+
);
|
|
1684
|
+
}
|
|
1685
|
+
logger9.info(`Entry fee payment verified for ${card.name}`, {
|
|
1686
|
+
txHash: paymentTxHash,
|
|
1687
|
+
amount: entryFeeWei
|
|
1688
|
+
});
|
|
1689
|
+
}
|
|
1497
1690
|
logger9.info(`Minting membership NFT for agent: ${card.name}`);
|
|
1498
1691
|
await this.blockchainClient.mintMembership(walletAddress);
|
|
1499
1692
|
} else {
|
|
@@ -1599,7 +1792,7 @@ var World = (_class4 = class {
|
|
|
1599
1792
|
* Start auto-save interval
|
|
1600
1793
|
*/
|
|
1601
1794
|
startAutoSave() {
|
|
1602
|
-
const interval = _optionalChain([this, 'access',
|
|
1795
|
+
const interval = _optionalChain([this, 'access', _34 => _34.config, 'access', _35 => _35.persistence, 'optionalAccess', _36 => _36.autoSaveIntervalMs]) || 1e4;
|
|
1603
1796
|
this.autoSaveInterval = setInterval(async () => {
|
|
1604
1797
|
if (this.persistence) {
|
|
1605
1798
|
await this.persistence.saveState(this.state);
|
|
@@ -1635,22 +1828,22 @@ var World = (_class4 = class {
|
|
|
1635
1828
|
id: _uuid.v4.call(void 0, ),
|
|
1636
1829
|
type: "tick_error",
|
|
1637
1830
|
timestamp: Date.now(),
|
|
1638
|
-
data: { tick: this.state.tick, error: _optionalChain([error, 'optionalAccess',
|
|
1831
|
+
data: { tick: this.state.tick, error: _optionalChain([error, 'optionalAccess', _37 => _37.message]) || String(error) }
|
|
1639
1832
|
});
|
|
1640
1833
|
}
|
|
1641
1834
|
logger9.debug(`Tick ${this.state.tick}`);
|
|
1642
|
-
if (_optionalChain([this, 'access',
|
|
1835
|
+
if (_optionalChain([this, 'access', _38 => _38.config, 'access', _39 => _39.simulation, 'optionalAccess', _40 => _40.maxTicks]) && this.state.tick >= this.config.simulation.maxTicks) {
|
|
1643
1836
|
logger9.info("Max ticks reached, stopping world");
|
|
1644
1837
|
await this.stop();
|
|
1645
1838
|
}
|
|
1646
1839
|
}, interval);
|
|
1647
1840
|
logger9.info(`Simulation ticking enabled (interval: ${interval}ms)`);
|
|
1648
1841
|
}
|
|
1649
|
-
},
|
|
1842
|
+
}, _class5);
|
|
1650
1843
|
|
|
1651
1844
|
// src/server/app.ts
|
|
1652
1845
|
var _express = require('express'); var _express2 = _interopRequireDefault(_express);
|
|
1653
|
-
var logger10 =
|
|
1846
|
+
var logger10 = _chunkWI7EASJJcjs.createLogger.call(void 0, "WorldServer");
|
|
1654
1847
|
function createWorldApp(world) {
|
|
1655
1848
|
const app = _express2.default.call(void 0, );
|
|
1656
1849
|
app.use(_express2.default.json());
|
|
@@ -1677,9 +1870,40 @@ function createWorldApp(world) {
|
|
|
1677
1870
|
}
|
|
1678
1871
|
});
|
|
1679
1872
|
});
|
|
1873
|
+
app.get("/world/join-info", async (req, res) => {
|
|
1874
|
+
try {
|
|
1875
|
+
const blockchain = world.config.blockchain;
|
|
1876
|
+
const client = world.getBlockchainClient();
|
|
1877
|
+
if (!blockchain || !client) {
|
|
1878
|
+
return res.json({
|
|
1879
|
+
worldName: world.config.name,
|
|
1880
|
+
requiresPayment: false,
|
|
1881
|
+
entryFee: "0",
|
|
1882
|
+
paymentAddress: null,
|
|
1883
|
+
chainId: null,
|
|
1884
|
+
rpcUrl: null
|
|
1885
|
+
});
|
|
1886
|
+
}
|
|
1887
|
+
const entryFeeWei = await client.getEntryFeeWei();
|
|
1888
|
+
res.json({
|
|
1889
|
+
worldName: world.config.name,
|
|
1890
|
+
requiresPayment: entryFeeWei !== "0" && BigInt(entryFeeWei) > 0n,
|
|
1891
|
+
entryFee: entryFeeWei,
|
|
1892
|
+
paymentAddress: client.getWalletAddress(),
|
|
1893
|
+
chainId: blockchain.chainId || null,
|
|
1894
|
+
rpcUrl: blockchain.rpcUrl
|
|
1895
|
+
});
|
|
1896
|
+
} catch (error) {
|
|
1897
|
+
logger10.error("Failed to get join info:", error);
|
|
1898
|
+
res.status(500).json({
|
|
1899
|
+
success: false,
|
|
1900
|
+
error: error.message || "Failed to get join info"
|
|
1901
|
+
});
|
|
1902
|
+
}
|
|
1903
|
+
});
|
|
1680
1904
|
app.post("/world/join", async (req, res) => {
|
|
1681
1905
|
try {
|
|
1682
|
-
const { agentUrl, walletAddress } = req.body;
|
|
1906
|
+
const { agentUrl, walletAddress, paymentTxHash } = req.body;
|
|
1683
1907
|
if (!agentUrl) {
|
|
1684
1908
|
return res.status(400).json({
|
|
1685
1909
|
success: false,
|
|
@@ -1687,9 +1911,10 @@ function createWorldApp(world) {
|
|
|
1687
1911
|
});
|
|
1688
1912
|
}
|
|
1689
1913
|
logger10.info(`Agent join request from: ${agentUrl}`, {
|
|
1690
|
-
wallet: walletAddress || "none"
|
|
1914
|
+
wallet: walletAddress || "none",
|
|
1915
|
+
paymentTx: paymentTxHash ? `${paymentTxHash.slice(0, 10)}...` : "none"
|
|
1691
1916
|
});
|
|
1692
|
-
const cardFetcher = new (await Promise.resolve().then(() => _interopRequireWildcard(require("./CardFetcher-
|
|
1917
|
+
const cardFetcher = new (await Promise.resolve().then(() => _interopRequireWildcard(require("./CardFetcher-ZD4YSGJE.cjs")))).CardFetcher();
|
|
1693
1918
|
const result = await cardFetcher.fetchCard(agentUrl);
|
|
1694
1919
|
if (!result.success || !result.card) {
|
|
1695
1920
|
return res.status(400).json({
|
|
@@ -1697,7 +1922,7 @@ function createWorldApp(world) {
|
|
|
1697
1922
|
error: `Failed to fetch agent card: ${result.error}`
|
|
1698
1923
|
});
|
|
1699
1924
|
}
|
|
1700
|
-
await world.admitAgent(result.card, walletAddress);
|
|
1925
|
+
await world.admitAgent(result.card, walletAddress, paymentTxHash);
|
|
1701
1926
|
res.json({
|
|
1702
1927
|
success: true,
|
|
1703
1928
|
message: "Agent admitted to world",
|
|
@@ -1855,6 +2080,7 @@ async function startWorldServer(world) {
|
|
|
1855
2080
|
logger10.info("");
|
|
1856
2081
|
logger10.info("Endpoints:");
|
|
1857
2082
|
logger10.info(` GET / - World info`);
|
|
2083
|
+
logger10.info(` GET /world/join-info - Join requirements & entry fee`);
|
|
1858
2084
|
logger10.info(` POST /world/join - Agent join request`);
|
|
1859
2085
|
logger10.info(` GET /world/agents - List agents`);
|
|
1860
2086
|
logger10.info(` GET /world/state - World state`);
|
|
@@ -1904,5 +2130,5 @@ async function startWorldServer(world) {
|
|
|
1904
2130
|
|
|
1905
2131
|
|
|
1906
2132
|
|
|
1907
|
-
exports.ActionProcessor = ActionProcessor; exports.AdmissionRulesSchema = AdmissionRulesSchema; exports.AgentEvaluator = AgentEvaluator; exports.BlockchainClient = BlockchainClient; exports.BlockchainConfigSchema = BlockchainConfigSchema; exports.CardFetcher =
|
|
2133
|
+
exports.ActionProcessor = ActionProcessor; exports.AdmissionRulesSchema = AdmissionRulesSchema; exports.AgentEvaluator = AgentEvaluator; exports.BlockchainClient = BlockchainClient; exports.BlockchainConfigSchema = BlockchainConfigSchema; exports.CardFetcher = _chunkWI7EASJJcjs.CardFetcher; exports.InMemoryAdapter = InMemoryAdapter; exports.MessageRouter = MessageRouter; exports.PersistenceConfigSchema = PersistenceConfigSchema; exports.TickOrchestrator = TickOrchestrator; exports.TokenConfigSchema = TokenConfigSchema; exports.World = World; exports.WorldA2AClient = WorldA2AClient; exports.WorldActionsRegistry = WorldActionsRegistry; exports.WorldConfigSchema = WorldConfigSchema; exports.createLogger = _chunkWI7EASJJcjs.createLogger; exports.createPersistence = createPersistence; exports.createWorldApp = createWorldApp; exports.isValidWorldConfig = isValidWorldConfig; exports.logger = _chunkWI7EASJJcjs.logger; exports.normalizeAgentUrl = _chunkWI7EASJJcjs.normalizeAgentUrl; exports.profileFromCard = profileFromCard; exports.startWorldServer = startWorldServer; exports.validateWorldConfig = validateWorldConfig;
|
|
1908
2134
|
//# sourceMappingURL=index.cjs.map
|