@dimcool/mcp 0.1.13 → 0.1.17

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.
Files changed (2) hide show
  1. package/dist/index.js +183 -31
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -21539,6 +21539,27 @@ var VoteAccountLayout = BufferLayout.struct([
21539
21539
  BufferLayout.seq(BufferLayout.struct([BufferLayout.nu64("epoch"), BufferLayout.nu64("credits"), BufferLayout.nu64("prevCredits")]), BufferLayout.offset(BufferLayout.u32(), -8), "epochCredits"),
21540
21540
  BufferLayout.struct([BufferLayout.nu64("slot"), BufferLayout.nu64("timestamp")], "lastTimestamp")
21541
21541
  ]);
21542
+ function base64ToBytes(base64) {
21543
+ if (typeof Buffer !== "undefined") {
21544
+ return Buffer.from(base64, "base64");
21545
+ }
21546
+ const binary = atob(base64);
21547
+ const bytes = new Uint8Array(binary.length);
21548
+ for (let i = 0; i < binary.length; i++) {
21549
+ bytes[i] = binary.charCodeAt(i);
21550
+ }
21551
+ return bytes;
21552
+ }
21553
+ function bytesToBase64(bytes) {
21554
+ if (typeof Buffer !== "undefined") {
21555
+ return Buffer.from(bytes).toString("base64");
21556
+ }
21557
+ let binary = "";
21558
+ for (let i = 0; i < bytes.length; i++) {
21559
+ binary += String.fromCharCode(bytes[i]);
21560
+ }
21561
+ return btoa(binary);
21562
+ }
21542
21563
  var HttpClient = class {
21543
21564
  constructor(baseUrl, storage, logger2, appId, autoPayConfig) {
21544
21565
  this.baseUrl = baseUrl.replace(/\/$/, "");
@@ -21810,11 +21831,11 @@ var HttpClient = class {
21810
21831
  }
21811
21832
  }
21812
21833
  );
21813
- const unsignedTx = Transaction.from(
21814
- Buffer.from(prepare.transaction, "base64")
21815
- );
21834
+ const unsignedTx = Transaction.from(base64ToBytes(prepare.transaction));
21816
21835
  const signedTx = await this.signTransactionHandler(unsignedTx);
21817
- const signedTransaction = signedTx.serialize({ requireAllSignatures: false }).toString("base64");
21836
+ const signedTransaction = bytesToBase64(
21837
+ signedTx.serialize({ requireAllSignatures: false })
21838
+ );
21818
21839
  const submitted = await this.post(
21819
21840
  "/payments/submit",
21820
21841
  {
@@ -21828,19 +21849,6 @@ var HttpClient = class {
21828
21849
  return submitted.paymentProof;
21829
21850
  }
21830
21851
  };
21831
- function toBase64(bytes) {
21832
- if (typeof Buffer !== "undefined") {
21833
- return Buffer.from(bytes).toString("base64");
21834
- }
21835
- let binary = "";
21836
- for (let i = 0; i < bytes.length; i++) {
21837
- binary += String.fromCharCode(bytes[i]);
21838
- }
21839
- if (typeof btoa === "undefined") {
21840
- throw new Error("Base64 encoding is not available in this environment");
21841
- }
21842
- return btoa(binary);
21843
- }
21844
21852
  var Auth = class {
21845
21853
  constructor(http2, storage, wallet, logger2) {
21846
21854
  this.http = http2;
@@ -21905,7 +21913,7 @@ var Auth = class {
21905
21913
  }
21906
21914
  const { message } = await this.generateHandshake(address);
21907
21915
  const signatureResult = await this.wallet.signMessage(message);
21908
- const signedMessage = typeof signatureResult === "string" ? signatureResult : toBase64(signatureResult);
21916
+ const signedMessage = typeof signatureResult === "string" ? signatureResult : bytesToBase64(signatureResult);
21909
21917
  this.logger.debug("Auth.loginWithWallet called", {
21910
21918
  address,
21911
21919
  walletMeta: options?.walletMeta
@@ -22379,11 +22387,11 @@ var Games = class {
22379
22387
  );
22380
22388
  }
22381
22389
  const prepared = await this.prepareGameDonation(gameId, amountMinor);
22382
- const unsignedTx = Transaction.from(
22383
- Buffer.from(prepared.transaction, "base64")
22384
- );
22390
+ const unsignedTx = Transaction.from(base64ToBytes(prepared.transaction));
22385
22391
  const signedTx = await this.wallet.signTransaction(unsignedTx);
22386
- const signedTransaction = signedTx.serialize({ requireAllSignatures: false }).toString("base64");
22392
+ const signedTransaction = bytesToBase64(
22393
+ signedTx.serialize({ requireAllSignatures: false })
22394
+ );
22387
22395
  const result = await this.donateToGame(
22388
22396
  gameId,
22389
22397
  amountMinor,
@@ -22651,11 +22659,11 @@ var Tips = class {
22651
22659
  }
22652
22660
  const { publicKey: senderAddress } = await this.wallet.loadWallet();
22653
22661
  const prepared = await this.prepare({ recipientUsername, amount });
22654
- const unsignedTx = Transaction.from(
22655
- Buffer.from(prepared.transaction, "base64")
22656
- );
22662
+ const unsignedTx = Transaction.from(base64ToBytes(prepared.transaction));
22657
22663
  const signedTx = await this.wallet.signTransaction(unsignedTx);
22658
- const signedTxBase64 = signedTx.serialize({ requireAllSignatures: false }).toString("base64");
22664
+ const signedTxBase64 = bytesToBase64(
22665
+ signedTx.serialize({ requireAllSignatures: false })
22666
+ );
22659
22667
  const transfer = await this.wallet.submitTransfer(
22660
22668
  signedTxBase64,
22661
22669
  senderAddress,
@@ -23020,11 +23028,11 @@ var Wallet = class {
23020
23028
  amount,
23021
23029
  token
23022
23030
  );
23023
- const unsignedTx = Transaction.from(
23024
- Buffer.from(prepared.transaction, "base64")
23025
- );
23031
+ const unsignedTx = Transaction.from(base64ToBytes(prepared.transaction));
23026
23032
  const signedTx = await this.signTransaction(unsignedTx);
23027
- const signedTxBase64 = signedTx.serialize({ requireAllSignatures: false }).toString("base64");
23033
+ const signedTxBase64 = bytesToBase64(
23034
+ signedTx.serialize({ requireAllSignatures: false })
23035
+ );
23028
23036
  const submitted = await this.submitTransfer(
23029
23037
  signedTxBase64,
23030
23038
  senderAddress,
@@ -25138,6 +25146,8 @@ var DimClient = class {
25138
25146
  config;
25139
25147
  authenticated = false;
25140
25148
  userId = null;
25149
+ eventQueue = [];
25150
+ unsubscribers = [];
25141
25151
  constructor(config) {
25142
25152
  this.config = config;
25143
25153
  const secretKeyBytes = bs58.decode(config.walletPrivateKey);
@@ -25200,6 +25210,39 @@ var DimClient = class {
25200
25210
  async ensureConnected(timeoutMs = 1e4) {
25201
25211
  await this.sdk.ensureWebSocketConnected(timeoutMs);
25202
25212
  }
25213
+ /**
25214
+ * Subscribe to key WS events and buffer them for agent consumption.
25215
+ * Call after authenticate() when the WS transport is connected.
25216
+ */
25217
+ startEventListeners() {
25218
+ const events = [
25219
+ "chat:message",
25220
+ "notification",
25221
+ "lobby:matched",
25222
+ "lobby:invitation",
25223
+ "game:turn",
25224
+ "game:completed"
25225
+ ];
25226
+ for (const event of events) {
25227
+ this.unsubscribers.push(
25228
+ this.sdk.events.subscribe(event, (payload) => {
25229
+ this.eventQueue.push({
25230
+ event,
25231
+ payload,
25232
+ at: (/* @__PURE__ */ new Date()).toISOString()
25233
+ });
25234
+ })
25235
+ );
25236
+ }
25237
+ }
25238
+ /** Drain all buffered events since last call. */
25239
+ drainEvents() {
25240
+ return this.eventQueue.splice(0);
25241
+ }
25242
+ /** Peek at buffered event count without draining. */
25243
+ get pendingEventCount() {
25244
+ return this.eventQueue.length;
25245
+ }
25203
25246
  /**
25204
25247
  * Get the Keypair for transaction signing.
25205
25248
  */
@@ -25218,6 +25261,7 @@ function registerAuthTools(server2, client) {
25218
25261
  async () => {
25219
25262
  try {
25220
25263
  const result = await client.authenticate();
25264
+ client.startEventListeners();
25221
25265
  const nextSteps = [];
25222
25266
  if (result.username == null || result.username === "") {
25223
25267
  nextSteps.push(
@@ -26797,6 +26841,105 @@ function registerMarketTools(server2, client) {
26797
26841
  );
26798
26842
  }
26799
26843
 
26844
+ // src/tools/notifications.ts
26845
+ function registerNotificationsTools(server2, client) {
26846
+ server2.tool(
26847
+ "dim_get_pending_events",
26848
+ "Drain buffered real-time events (DMs, challenges, game turns, match notifications). Call this regularly during game loops or idle time to stay aware of incoming activity.",
26849
+ {},
26850
+ async () => {
26851
+ try {
26852
+ const events = client.drainEvents();
26853
+ return {
26854
+ content: [
26855
+ {
26856
+ type: "text",
26857
+ text: JSON.stringify(
26858
+ {
26859
+ count: events.length,
26860
+ events,
26861
+ hint: events.length === 0 ? "No new events since last check." : "Process these events and take action as needed."
26862
+ },
26863
+ null,
26864
+ 2
26865
+ )
26866
+ }
26867
+ ]
26868
+ };
26869
+ } catch (error) {
26870
+ return {
26871
+ content: [
26872
+ {
26873
+ type: "text",
26874
+ text: `Failed to get pending events: ${error instanceof Error ? error.message : String(error)}`
26875
+ }
26876
+ ],
26877
+ isError: true
26878
+ };
26879
+ }
26880
+ }
26881
+ );
26882
+ server2.tool(
26883
+ "dim_check_notifications",
26884
+ "Check all pending items in one call: unread notifications (challenges, game results), unread DM threads, and incoming friend requests. Use this to catch up after being idle.",
26885
+ {},
26886
+ async () => {
26887
+ try {
26888
+ if (!client.isAuthenticated) {
26889
+ return {
26890
+ content: [
26891
+ {
26892
+ type: "text",
26893
+ text: "Not authenticated. Call dim_login first."
26894
+ }
26895
+ ],
26896
+ isError: true
26897
+ };
26898
+ }
26899
+ const [notifications, dmThreads, friendRequests] = await Promise.all([
26900
+ client.sdk.notifications.list({ page: 1, limit: 20 }),
26901
+ client.sdk.chat.listDmThreads(),
26902
+ client.sdk.users.getIncomingFriendRequests()
26903
+ ]);
26904
+ const unreadDms = dmThreads.filter(
26905
+ (t) => (t.unreadCount ?? 0) > 0
26906
+ );
26907
+ return {
26908
+ content: [
26909
+ {
26910
+ type: "text",
26911
+ text: JSON.stringify(
26912
+ {
26913
+ unreadNotificationCount: notifications.unreadCount,
26914
+ notifications: notifications.notifications.filter(
26915
+ (n) => !n.read
26916
+ ),
26917
+ unreadDmThreads: unreadDms,
26918
+ incomingFriendRequests: friendRequests,
26919
+ pendingWsEvents: client.pendingEventCount,
26920
+ hint: "Use dim_get_pending_events to drain buffered real-time events."
26921
+ },
26922
+ null,
26923
+ 2
26924
+ )
26925
+ }
26926
+ ]
26927
+ };
26928
+ } catch (error) {
26929
+ return {
26930
+ content: [
26931
+ {
26932
+ type: "text",
26933
+ text: `Failed to check notifications: ${error instanceof Error ? error.message : String(error)}`
26934
+ }
26935
+ ],
26936
+ isError: true
26937
+ };
26938
+ }
26939
+ }
26940
+ );
26941
+ }
26942
+
26800
26943
  // src/tools/instructions.ts
26801
26944
  var DIM_INSTRUCTIONS = [
26802
26945
  {
@@ -26929,7 +27072,15 @@ var DIM_INSTRUCTIONS = [
26929
27072
  name: "dim_redeem_shares",
26930
27073
  description: "Redeem shares after market resolution."
26931
27074
  },
26932
- { name: "dim_get_market_analytics", description: "Get market analytics." }
27075
+ { name: "dim_get_market_analytics", description: "Get market analytics." },
27076
+ {
27077
+ name: "dim_get_pending_events",
27078
+ description: "Drain buffered real-time events (DMs, challenges, game turns). Call regularly to stay aware."
27079
+ },
27080
+ {
27081
+ name: "dim_check_notifications",
27082
+ description: "Check unread notifications, unread DM threads, and incoming friend requests in one call."
27083
+ }
26933
27084
  ];
26934
27085
  function registerInstructionsTool(server2) {
26935
27086
  server2.tool(
@@ -27163,6 +27314,7 @@ function createDimMcpServer(config) {
27163
27314
  registerReferralTools(server2, client);
27164
27315
  registerSupportTools(server2, client);
27165
27316
  registerMarketTools(server2, client);
27317
+ registerNotificationsTools(server2, client);
27166
27318
  registerResources(server2, client);
27167
27319
  return { server: server2, client };
27168
27320
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dimcool/mcp",
3
- "version": "0.1.13",
3
+ "version": "0.1.17",
4
4
  "description": "MCP server for DIM — lets AI agents play games, chat, send USDC, and earn referral income on the DIM platform",
5
5
  "type": "module",
6
6
  "bin": {