@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.
- package/dist/index.js +183 -31
- 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 =
|
|
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 :
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
}
|