@moltium/world-core 0.1.22 → 0.1.23

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.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 _chunkDHQFXIEWcjs = require('./chunk-DHQFXIEW.cjs');
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 = _chunkDHQFXIEWcjs.createLogger.call(void 0, "AgentEvaluator");
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 = _chunkDHQFXIEWcjs.createLogger.call(void 0, "BlockchainClient");
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 = _chunkDHQFXIEWcjs.createLogger.call(void 0, "WorldA2AClient");
788
- var WorldA2AClient = (_class2 = class {constructor() { _class2.prototype.__init4.call(this); }
789
- __init4() {this.clients = /* @__PURE__ */ new Map()}
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', _13 => _13.message]) || String(error),
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
- }, _class2);
954
+ }, _class3);
883
955
 
884
956
  // src/engine/WorldActions.ts
885
- var logger5 = _chunkDHQFXIEWcjs.createLogger.call(void 0, "WorldActions");
886
- var WorldActionsRegistry = (_class3 = class {constructor() { _class3.prototype.__init5.call(this); }
887
- __init5() {this.actions = /* @__PURE__ */ new Map()}
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
- }, _class3);
1049
+ }, _class4);
978
1050
 
979
1051
  // src/engine/ActionProcessor.ts
980
1052
 
981
- var logger6 = _chunkDHQFXIEWcjs.createLogger.call(void 0, "ActionProcessor");
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 = _chunkDHQFXIEWcjs.createLogger.call(void 0, "TickOrchestrator");
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', _14 => _14.broadcastOnTick]), () => ( true)),
1091
- tickTimeout: _nullishCoalesce(_optionalChain([config, 'optionalAccess', _15 => _15.tickTimeout]), () => ( 1e4)),
1092
- promptTemplate: _optionalChain([config, 'optionalAccess', _16 => _16.promptTemplate])
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,7 +1317,19 @@ var TickOrchestrator = class {
1245
1317
  };
1246
1318
 
1247
1319
  // src/a2a/MessageRouter.ts
1248
- var logger8 = _chunkDHQFXIEWcjs.createLogger.call(void 0, "MessageRouter");
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;
@@ -1258,6 +1342,7 @@ var MessageRouter = class {
1258
1342
  const agents = this.getAgents();
1259
1343
  const sender = agents.find((a) => a.url === fromAgentUrl);
1260
1344
  if (!sender) {
1345
+ logger8.warn(`Message rejected \u2014 sender not in world: ${fromAgentUrl}`);
1261
1346
  return {
1262
1347
  success: false,
1263
1348
  error: `Sender not in world: ${fromAgentUrl}`
@@ -1265,11 +1350,19 @@ var MessageRouter = class {
1265
1350
  }
1266
1351
  const recipient = agents.find((a) => a.url === toAgentUrl);
1267
1352
  if (!recipient) {
1353
+ logger8.warn(`Message rejected \u2014 recipient not in world: ${toAgentUrl}`);
1268
1354
  return {
1269
1355
  success: false,
1270
1356
  error: `Recipient not in world: ${toAgentUrl}`
1271
1357
  };
1272
1358
  }
1359
+ console.log(
1360
+ `
1361
+ ${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}
1362
+ ${c.bold}${c.blue}${sender.name}${c.reset} ${c.dim}\u2192${c.reset} ${c.bold}${c.green}${recipient.name}${c.reset}
1363
+ ${c.dim}\u2502${c.reset} ${this.truncate(message, 300)}
1364
+ ${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}`
1365
+ );
1273
1366
  const wrappedMessage = JSON.stringify({
1274
1367
  type: "world_message",
1275
1368
  from: {
@@ -1279,11 +1372,24 @@ var MessageRouter = class {
1279
1372
  },
1280
1373
  message
1281
1374
  });
1282
- logger8.info(`Routing message: ${sender.name} \u2192 ${recipient.name}`);
1283
- return this.a2aClient.sendToAgent(toAgentUrl, wrappedMessage, {
1375
+ const response = await this.a2aClient.sendToAgent(toAgentUrl, wrappedMessage, {
1284
1376
  type: "world_message",
1285
1377
  fromAgentUrl
1286
1378
  });
1379
+ if (response.success && response.reply) {
1380
+ console.log(
1381
+ `
1382
+ ${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}
1383
+ ${c.bold}${c.green}${recipient.name}${c.reset} ${c.dim}\u2192${c.reset} ${c.bold}${c.blue}${sender.name}${c.reset}
1384
+ ${c.dim}\u2502${c.reset} ${this.truncate(response.reply, 300)}
1385
+ ${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}`
1386
+ );
1387
+ } else if (!response.success) {
1388
+ console.log(
1389
+ `${c.red} \u2717 ${recipient.name} failed to respond: ${response.error || "no response"}${c.reset}`
1390
+ );
1391
+ }
1392
+ return response;
1287
1393
  }
1288
1394
  /**
1289
1395
  * Broadcast a message from one agent to all other agents in the world
@@ -1292,6 +1398,7 @@ var MessageRouter = class {
1292
1398
  const agents = this.getAgents();
1293
1399
  const sender = agents.find((a) => a.url === fromAgentUrl);
1294
1400
  if (!sender) {
1401
+ logger8.warn(`Broadcast rejected \u2014 sender not in world: ${fromAgentUrl}`);
1295
1402
  const result = /* @__PURE__ */ new Map();
1296
1403
  result.set(fromAgentUrl, {
1297
1404
  success: false,
@@ -1299,6 +1406,14 @@ var MessageRouter = class {
1299
1406
  });
1300
1407
  return result;
1301
1408
  }
1409
+ const recipients = agents.filter((a) => a.url !== fromAgentUrl);
1410
+ console.log(
1411
+ `
1412
+ ${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}
1413
+ ${c.bold}${c.blue}${sender.name}${c.reset} ${c.dim}\u2192${c.reset} ${c.bold}${c.yellow}ALL (${recipients.length} agents)${c.reset}
1414
+ ${c.dim}\u2502${c.reset} ${this.truncate(message, 300)}
1415
+ ${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}`
1416
+ );
1302
1417
  const wrappedMessage = JSON.stringify({
1303
1418
  type: "world_broadcast",
1304
1419
  from: {
@@ -1309,7 +1424,6 @@ var MessageRouter = class {
1309
1424
  message
1310
1425
  });
1311
1426
  const results = /* @__PURE__ */ new Map();
1312
- const recipients = agents.filter((a) => a.url !== fromAgentUrl);
1313
1427
  const promises = recipients.map(async (recipient) => {
1314
1428
  const response = await this.a2aClient.sendToAgent(
1315
1429
  recipient.url,
@@ -1317,17 +1431,38 @@ var MessageRouter = class {
1317
1431
  { type: "world_broadcast", fromAgentUrl }
1318
1432
  );
1319
1433
  results.set(recipient.url, response);
1434
+ if (response.success && response.reply) {
1435
+ console.log(
1436
+ `${c.green} \u21A9 ${c.bold}${recipient.name}${c.reset}${c.green} replied:${c.reset} ${this.truncate(response.reply, 200)}`
1437
+ );
1438
+ } else if (!response.success) {
1439
+ console.log(
1440
+ `${c.red} \u2717 ${recipient.name} failed: ${response.error || "no response"}${c.reset}`
1441
+ );
1442
+ }
1320
1443
  });
1321
1444
  await Promise.allSettled(promises);
1322
- logger8.info(`Broadcast from ${sender.name} to ${recipients.length} agents`);
1445
+ const succeeded = Array.from(results.values()).filter((r) => r.success).length;
1446
+ const failed = Array.from(results.values()).filter((r) => !r.success).length;
1447
+ console.log(
1448
+ `${c.dim} Broadcast complete: ${c.green}${succeeded} replied${c.reset}${c.dim}${failed > 0 ? `, ${c.red}${failed} failed${c.reset}` : ""}${c.reset}
1449
+ `
1450
+ );
1323
1451
  return results;
1324
1452
  }
1453
+ /**
1454
+ * Truncate long messages for logging
1455
+ */
1456
+ truncate(text, maxLen) {
1457
+ if (text.length <= maxLen) return text;
1458
+ return text.slice(0, maxLen) + "...";
1459
+ }
1325
1460
  };
1326
1461
 
1327
1462
  // src/engine/World.ts
1328
- var logger9 = _chunkDHQFXIEWcjs.createLogger.call(void 0, "World");
1329
- var World = (_class4 = class {
1330
- constructor(config) {;_class4.prototype.__init6.call(this);_class4.prototype.__init7.call(this);_class4.prototype.__init8.call(this);_class4.prototype.__init9.call(this);
1463
+ var logger9 = _chunkWI7EASJJcjs.createLogger.call(void 0, "World");
1464
+ var World = (_class5 = class {
1465
+ constructor(config) {;_class5.prototype.__init7.call(this);_class5.prototype.__init8.call(this);_class5.prototype.__init9.call(this);_class5.prototype.__init10.call(this);
1331
1466
  this.config = config;
1332
1467
  validateWorldConfig(config);
1333
1468
  this.state = {
@@ -1338,7 +1473,7 @@ var World = (_class4 = class {
1338
1473
  metadata: {}
1339
1474
  };
1340
1475
  this.agents = /* @__PURE__ */ new Map();
1341
- this.cardFetcher = new (0, _chunkDHQFXIEWcjs.CardFetcher)();
1476
+ this.cardFetcher = new (0, _chunkWI7EASJJcjs.CardFetcher)();
1342
1477
  this.evaluator = new AgentEvaluator(config.admission);
1343
1478
  this.a2aClient = new WorldA2AClient();
1344
1479
  this.actionsRegistry = new WorldActionsRegistry();
@@ -1359,17 +1494,17 @@ var World = (_class4 = class {
1359
1494
  logger9.info(`World "${config.name}" created`, {
1360
1495
  type: config.type || "generic",
1361
1496
  maxAgents: config.admission.maxAgents,
1362
- orchestration: !!_optionalChain([config, 'access', _17 => _17.orchestration, 'optionalAccess', _18 => _18.broadcastOnTick])
1497
+ orchestration: !!_optionalChain([config, 'access', _20 => _20.orchestration, 'optionalAccess', _21 => _21.broadcastOnTick])
1363
1498
  });
1364
1499
  }
1365
1500
 
1366
1501
 
1367
- __init6() {this.persistence = null}
1368
- __init7() {this.blockchainClient = null}
1502
+ __init7() {this.persistence = null}
1503
+ __init8() {this.blockchainClient = null}
1369
1504
 
1370
1505
 
1371
- __init8() {this.tickInterval = null}
1372
- __init9() {this.autoSaveInterval = null}
1506
+ __init9() {this.tickInterval = null}
1507
+ __init10() {this.autoSaveInterval = null}
1373
1508
  // Agent-World bridge components
1374
1509
 
1375
1510
 
@@ -1425,7 +1560,7 @@ var World = (_class4 = class {
1425
1560
  this.setState("ready");
1426
1561
  logger9.info("World initialized successfully", {
1427
1562
  agents: this.agents.size,
1428
- persistence: _optionalChain([this, 'access', _19 => _19.config, 'access', _20 => _20.persistence, 'optionalAccess', _21 => _21.type]) || "none"
1563
+ persistence: _optionalChain([this, 'access', _22 => _22.config, 'access', _23 => _23.persistence, 'optionalAccess', _24 => _24.type]) || "none"
1429
1564
  });
1430
1565
  } catch (error) {
1431
1566
  logger9.error("Failed to initialize world:", error);
@@ -1448,7 +1583,7 @@ var World = (_class4 = class {
1448
1583
  type: "world_started",
1449
1584
  timestamp: Date.now()
1450
1585
  });
1451
- if (_optionalChain([this, 'access', _22 => _22.config, 'access', _23 => _23.simulation, 'optionalAccess', _24 => _24.tickIntervalMs])) {
1586
+ if (_optionalChain([this, 'access', _25 => _25.config, 'access', _26 => _26.simulation, 'optionalAccess', _27 => _27.tickIntervalMs])) {
1452
1587
  this.startTicking();
1453
1588
  }
1454
1589
  }
@@ -1476,24 +1611,52 @@ var World = (_class4 = class {
1476
1611
  });
1477
1612
  logger9.info("World stopped");
1478
1613
  }
1614
+ /**
1615
+ * Get the blockchain client (for server endpoints)
1616
+ */
1617
+ getBlockchainClient() {
1618
+ return this.blockchainClient;
1619
+ }
1479
1620
  /**
1480
1621
  * Admit an agent to the world
1481
1622
  */
1482
- async admitAgent(card, walletAddress) {
1623
+ async admitAgent(card, walletAddress, paymentTxHash) {
1483
1624
  const decision = await this.evaluator.evaluate(card, this.agents.size, walletAddress);
1484
1625
  if (!decision.admitted) {
1485
1626
  throw new Error(`Agent admission denied: ${decision.reason}`);
1486
1627
  }
1487
- if (this.blockchainClient && _optionalChain([this, 'access', _25 => _25.config, 'access', _26 => _26.blockchain, 'optionalAccess', _27 => _27.enforceOnChainValidation]) && walletAddress) {
1628
+ if (this.blockchainClient && _optionalChain([this, 'access', _28 => _28.config, 'access', _29 => _29.blockchain, 'optionalAccess', _30 => _30.enforceOnChainValidation]) && walletAddress) {
1488
1629
  const isValid = await this.blockchainClient.validateAgent(walletAddress);
1489
1630
  if (!isValid) {
1490
1631
  throw new Error("Agent not registered in on-chain AgentRegistry");
1491
1632
  }
1492
1633
  logger9.info(`Agent validated on-chain: ${card.name}`);
1493
1634
  }
1494
- if (this.blockchainClient && _optionalChain([this, 'access', _28 => _28.config, 'access', _29 => _29.blockchain, 'optionalAccess', _30 => _30.requireMembership]) && walletAddress) {
1635
+ if (this.blockchainClient && _optionalChain([this, 'access', _31 => _31.config, 'access', _32 => _32.blockchain, 'optionalAccess', _33 => _33.requireMembership]) && walletAddress) {
1495
1636
  const hasMembership = await this.blockchainClient.hasMembership(walletAddress);
1496
1637
  if (!hasMembership) {
1638
+ const entryFeeWei = await this.blockchainClient.getEntryFeeWei();
1639
+ if (entryFeeWei !== "0" && BigInt(entryFeeWei) > 0n) {
1640
+ if (!paymentTxHash) {
1641
+ throw new Error(
1642
+ `Entry fee required: ${entryFeeWei} wei. Query GET /world/join-info for payment details, pay the fee, then include paymentTxHash in your join request.`
1643
+ );
1644
+ }
1645
+ const paymentValid = await this.blockchainClient.verifyPayment(
1646
+ paymentTxHash,
1647
+ walletAddress,
1648
+ entryFeeWei
1649
+ );
1650
+ if (!paymentValid) {
1651
+ throw new Error(
1652
+ `Payment verification failed for tx ${paymentTxHash}. Ensure the transaction is confirmed, sent from ${walletAddress}, to ${this.blockchainClient.getWalletAddress()}, for at least ${entryFeeWei} wei.`
1653
+ );
1654
+ }
1655
+ logger9.info(`Entry fee payment verified for ${card.name}`, {
1656
+ txHash: paymentTxHash,
1657
+ amount: entryFeeWei
1658
+ });
1659
+ }
1497
1660
  logger9.info(`Minting membership NFT for agent: ${card.name}`);
1498
1661
  await this.blockchainClient.mintMembership(walletAddress);
1499
1662
  } else {
@@ -1599,7 +1762,7 @@ var World = (_class4 = class {
1599
1762
  * Start auto-save interval
1600
1763
  */
1601
1764
  startAutoSave() {
1602
- const interval = _optionalChain([this, 'access', _31 => _31.config, 'access', _32 => _32.persistence, 'optionalAccess', _33 => _33.autoSaveIntervalMs]) || 1e4;
1765
+ const interval = _optionalChain([this, 'access', _34 => _34.config, 'access', _35 => _35.persistence, 'optionalAccess', _36 => _36.autoSaveIntervalMs]) || 1e4;
1603
1766
  this.autoSaveInterval = setInterval(async () => {
1604
1767
  if (this.persistence) {
1605
1768
  await this.persistence.saveState(this.state);
@@ -1635,22 +1798,22 @@ var World = (_class4 = class {
1635
1798
  id: _uuid.v4.call(void 0, ),
1636
1799
  type: "tick_error",
1637
1800
  timestamp: Date.now(),
1638
- data: { tick: this.state.tick, error: _optionalChain([error, 'optionalAccess', _34 => _34.message]) || String(error) }
1801
+ data: { tick: this.state.tick, error: _optionalChain([error, 'optionalAccess', _37 => _37.message]) || String(error) }
1639
1802
  });
1640
1803
  }
1641
1804
  logger9.debug(`Tick ${this.state.tick}`);
1642
- if (_optionalChain([this, 'access', _35 => _35.config, 'access', _36 => _36.simulation, 'optionalAccess', _37 => _37.maxTicks]) && this.state.tick >= this.config.simulation.maxTicks) {
1805
+ if (_optionalChain([this, 'access', _38 => _38.config, 'access', _39 => _39.simulation, 'optionalAccess', _40 => _40.maxTicks]) && this.state.tick >= this.config.simulation.maxTicks) {
1643
1806
  logger9.info("Max ticks reached, stopping world");
1644
1807
  await this.stop();
1645
1808
  }
1646
1809
  }, interval);
1647
1810
  logger9.info(`Simulation ticking enabled (interval: ${interval}ms)`);
1648
1811
  }
1649
- }, _class4);
1812
+ }, _class5);
1650
1813
 
1651
1814
  // src/server/app.ts
1652
1815
  var _express = require('express'); var _express2 = _interopRequireDefault(_express);
1653
- var logger10 = _chunkDHQFXIEWcjs.createLogger.call(void 0, "WorldServer");
1816
+ var logger10 = _chunkWI7EASJJcjs.createLogger.call(void 0, "WorldServer");
1654
1817
  function createWorldApp(world) {
1655
1818
  const app = _express2.default.call(void 0, );
1656
1819
  app.use(_express2.default.json());
@@ -1677,9 +1840,40 @@ function createWorldApp(world) {
1677
1840
  }
1678
1841
  });
1679
1842
  });
1843
+ app.get("/world/join-info", async (req, res) => {
1844
+ try {
1845
+ const blockchain = world.config.blockchain;
1846
+ const client = world.getBlockchainClient();
1847
+ if (!blockchain || !client) {
1848
+ return res.json({
1849
+ worldName: world.config.name,
1850
+ requiresPayment: false,
1851
+ entryFee: "0",
1852
+ paymentAddress: null,
1853
+ chainId: null,
1854
+ rpcUrl: null
1855
+ });
1856
+ }
1857
+ const entryFeeWei = await client.getEntryFeeWei();
1858
+ res.json({
1859
+ worldName: world.config.name,
1860
+ requiresPayment: entryFeeWei !== "0" && BigInt(entryFeeWei) > 0n,
1861
+ entryFee: entryFeeWei,
1862
+ paymentAddress: client.getWalletAddress(),
1863
+ chainId: blockchain.chainId || null,
1864
+ rpcUrl: blockchain.rpcUrl
1865
+ });
1866
+ } catch (error) {
1867
+ logger10.error("Failed to get join info:", error);
1868
+ res.status(500).json({
1869
+ success: false,
1870
+ error: error.message || "Failed to get join info"
1871
+ });
1872
+ }
1873
+ });
1680
1874
  app.post("/world/join", async (req, res) => {
1681
1875
  try {
1682
- const { agentUrl, walletAddress } = req.body;
1876
+ const { agentUrl, walletAddress, paymentTxHash } = req.body;
1683
1877
  if (!agentUrl) {
1684
1878
  return res.status(400).json({
1685
1879
  success: false,
@@ -1687,9 +1881,10 @@ function createWorldApp(world) {
1687
1881
  });
1688
1882
  }
1689
1883
  logger10.info(`Agent join request from: ${agentUrl}`, {
1690
- wallet: walletAddress || "none"
1884
+ wallet: walletAddress || "none",
1885
+ paymentTx: paymentTxHash ? `${paymentTxHash.slice(0, 10)}...` : "none"
1691
1886
  });
1692
- const cardFetcher = new (await Promise.resolve().then(() => _interopRequireWildcard(require("./CardFetcher-UCJGPZ7X.cjs")))).CardFetcher();
1887
+ const cardFetcher = new (await Promise.resolve().then(() => _interopRequireWildcard(require("./CardFetcher-ZD4YSGJE.cjs")))).CardFetcher();
1693
1888
  const result = await cardFetcher.fetchCard(agentUrl);
1694
1889
  if (!result.success || !result.card) {
1695
1890
  return res.status(400).json({
@@ -1697,7 +1892,7 @@ function createWorldApp(world) {
1697
1892
  error: `Failed to fetch agent card: ${result.error}`
1698
1893
  });
1699
1894
  }
1700
- await world.admitAgent(result.card, walletAddress);
1895
+ await world.admitAgent(result.card, walletAddress, paymentTxHash);
1701
1896
  res.json({
1702
1897
  success: true,
1703
1898
  message: "Agent admitted to world",
@@ -1855,6 +2050,7 @@ async function startWorldServer(world) {
1855
2050
  logger10.info("");
1856
2051
  logger10.info("Endpoints:");
1857
2052
  logger10.info(` GET / - World info`);
2053
+ logger10.info(` GET /world/join-info - Join requirements & entry fee`);
1858
2054
  logger10.info(` POST /world/join - Agent join request`);
1859
2055
  logger10.info(` GET /world/agents - List agents`);
1860
2056
  logger10.info(` GET /world/state - World state`);
@@ -1904,5 +2100,5 @@ async function startWorldServer(world) {
1904
2100
 
1905
2101
 
1906
2102
 
1907
- exports.ActionProcessor = ActionProcessor; exports.AdmissionRulesSchema = AdmissionRulesSchema; exports.AgentEvaluator = AgentEvaluator; exports.BlockchainClient = BlockchainClient; exports.BlockchainConfigSchema = BlockchainConfigSchema; exports.CardFetcher = _chunkDHQFXIEWcjs.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 = _chunkDHQFXIEWcjs.createLogger; exports.createPersistence = createPersistence; exports.createWorldApp = createWorldApp; exports.isValidWorldConfig = isValidWorldConfig; exports.logger = _chunkDHQFXIEWcjs.logger; exports.normalizeAgentUrl = _chunkDHQFXIEWcjs.normalizeAgentUrl; exports.profileFromCard = profileFromCard; exports.startWorldServer = startWorldServer; exports.validateWorldConfig = validateWorldConfig;
2103
+ 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
2104
  //# sourceMappingURL=index.cjs.map