@dimcool/dimclaw 0.1.30 → 0.1.31
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 +273 -33
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -32884,6 +32884,9 @@ var Admin = class {
|
|
|
32884
32884
|
this.http = http2;
|
|
32885
32885
|
this.logger = logger2;
|
|
32886
32886
|
}
|
|
32887
|
+
async getInternalBots() {
|
|
32888
|
+
return this.http.get("/admin/internal-bots");
|
|
32889
|
+
}
|
|
32887
32890
|
async getUserById(id) {
|
|
32888
32891
|
return this.http.get(`/admin/users/${id}`);
|
|
32889
32892
|
}
|
|
@@ -35507,8 +35510,21 @@ function createGameActionsStore(transport) {
|
|
|
35507
35510
|
});
|
|
35508
35511
|
};
|
|
35509
35512
|
const isNonRpsState = (state) => Boolean(state && !isRpsState(state));
|
|
35513
|
+
const pendingEvents = /* @__PURE__ */ new Map();
|
|
35514
|
+
function enqueue(gameId, event) {
|
|
35515
|
+
const q = pendingEvents.get(gameId) ?? [];
|
|
35516
|
+
q.push(event);
|
|
35517
|
+
pendingEvents.set(gameId, q);
|
|
35518
|
+
}
|
|
35519
|
+
function drainQueue(gameId) {
|
|
35520
|
+
const q = pendingEvents.get(gameId);
|
|
35521
|
+
if (!q?.length) return;
|
|
35522
|
+
pendingEvents.delete(gameId);
|
|
35523
|
+
for (const ev of q) applyWsEvent(ev);
|
|
35524
|
+
}
|
|
35510
35525
|
const setBaseState = (gameId, state) => {
|
|
35511
35526
|
updateState(gameId, state);
|
|
35527
|
+
drainQueue(gameId);
|
|
35512
35528
|
};
|
|
35513
35529
|
const clearState = (gameId) => {
|
|
35514
35530
|
store.updateState((state) => {
|
|
@@ -35518,6 +35534,7 @@ function createGameActionsStore(transport) {
|
|
|
35518
35534
|
const { [gameId]: _, ...rest } = state.statesByGameId;
|
|
35519
35535
|
return { ...state, statesByGameId: rest };
|
|
35520
35536
|
});
|
|
35537
|
+
pendingEvents.delete(gameId);
|
|
35521
35538
|
};
|
|
35522
35539
|
const applyWsEvent = (event) => {
|
|
35523
35540
|
switch (event.event) {
|
|
@@ -35536,7 +35553,10 @@ function createGameActionsStore(transport) {
|
|
|
35536
35553
|
}
|
|
35537
35554
|
case "game:rps:starting": {
|
|
35538
35555
|
const current = store.getState().statesByGameId[event.payload.gameId];
|
|
35539
|
-
if (!current || !isRpsState(current))
|
|
35556
|
+
if (!current || !isRpsState(current)) {
|
|
35557
|
+
enqueue(event.payload.gameId, event);
|
|
35558
|
+
return;
|
|
35559
|
+
}
|
|
35540
35560
|
const betAmount = typeof event.payload.betAmount === "number" ? event.payload.betAmount : void 0;
|
|
35541
35561
|
const startedAt = typeof event.payload.startedAt === "string" ? event.payload.startedAt : current.roundState.startedAt;
|
|
35542
35562
|
const bufferEndsAt = typeof event.payload.bufferEndsAt === "string" ? event.payload.bufferEndsAt : current.roundState.selectionEndsAt;
|
|
@@ -35557,7 +35577,10 @@ function createGameActionsStore(transport) {
|
|
|
35557
35577
|
}
|
|
35558
35578
|
case "game:rps:round:started": {
|
|
35559
35579
|
const current = store.getState().statesByGameId[event.payload.gameId];
|
|
35560
|
-
if (!current || !isRpsState(current))
|
|
35580
|
+
if (!current || !isRpsState(current)) {
|
|
35581
|
+
enqueue(event.payload.gameId, event);
|
|
35582
|
+
return;
|
|
35583
|
+
}
|
|
35561
35584
|
const actions = {};
|
|
35562
35585
|
const baseUsers = /* @__PURE__ */ new Set();
|
|
35563
35586
|
Object.keys(current.roundState.actions).forEach(
|
|
@@ -35591,7 +35614,10 @@ function createGameActionsStore(transport) {
|
|
|
35591
35614
|
}
|
|
35592
35615
|
case "game:rps:action:received": {
|
|
35593
35616
|
const current = store.getState().statesByGameId[event.payload.gameId];
|
|
35594
|
-
if (!current || !isRpsState(current))
|
|
35617
|
+
if (!current || !isRpsState(current)) {
|
|
35618
|
+
enqueue(event.payload.gameId, event);
|
|
35619
|
+
return;
|
|
35620
|
+
}
|
|
35595
35621
|
const updated = {
|
|
35596
35622
|
...current,
|
|
35597
35623
|
roundState: {
|
|
@@ -35610,7 +35636,10 @@ function createGameActionsStore(transport) {
|
|
|
35610
35636
|
}
|
|
35611
35637
|
case "game:rps:timer:cutoff": {
|
|
35612
35638
|
const current = store.getState().statesByGameId[event.payload.gameId];
|
|
35613
|
-
if (!current || !isRpsState(current))
|
|
35639
|
+
if (!current || !isRpsState(current)) {
|
|
35640
|
+
enqueue(event.payload.gameId, event);
|
|
35641
|
+
return;
|
|
35642
|
+
}
|
|
35614
35643
|
const updated = {
|
|
35615
35644
|
...current,
|
|
35616
35645
|
roundState: {
|
|
@@ -35624,7 +35653,10 @@ function createGameActionsStore(transport) {
|
|
|
35624
35653
|
}
|
|
35625
35654
|
case "game:rps:round:reveal": {
|
|
35626
35655
|
const current = store.getState().statesByGameId[event.payload.gameId];
|
|
35627
|
-
if (!current || !isRpsState(current))
|
|
35656
|
+
if (!current || !isRpsState(current)) {
|
|
35657
|
+
enqueue(event.payload.gameId, event);
|
|
35658
|
+
return;
|
|
35659
|
+
}
|
|
35628
35660
|
const actions = {};
|
|
35629
35661
|
const payloadActions = event.payload.actions;
|
|
35630
35662
|
Object.keys(payloadActions || {}).forEach((userId) => {
|
|
@@ -35648,7 +35680,10 @@ function createGameActionsStore(transport) {
|
|
|
35648
35680
|
}
|
|
35649
35681
|
case "game:rps:round:completed": {
|
|
35650
35682
|
const current = store.getState().statesByGameId[event.payload.gameId];
|
|
35651
|
-
if (!current || !isRpsState(current))
|
|
35683
|
+
if (!current || !isRpsState(current)) {
|
|
35684
|
+
enqueue(event.payload.gameId, event);
|
|
35685
|
+
return;
|
|
35686
|
+
}
|
|
35652
35687
|
const roundHistory = [
|
|
35653
35688
|
...current.roundHistory || [],
|
|
35654
35689
|
{
|
|
@@ -35673,7 +35708,10 @@ function createGameActionsStore(transport) {
|
|
|
35673
35708
|
}
|
|
35674
35709
|
case "game:rps:timeout": {
|
|
35675
35710
|
const current = store.getState().statesByGameId[event.payload.gameId];
|
|
35676
|
-
if (!current || !isRpsState(current))
|
|
35711
|
+
if (!current || !isRpsState(current)) {
|
|
35712
|
+
enqueue(event.payload.gameId, event);
|
|
35713
|
+
return;
|
|
35714
|
+
}
|
|
35677
35715
|
const timedOutUser = event.payload.playerId;
|
|
35678
35716
|
const action = event.payload.action;
|
|
35679
35717
|
const updated = {
|
|
@@ -35698,7 +35736,10 @@ function createGameActionsStore(transport) {
|
|
|
35698
35736
|
const payload = event.payload;
|
|
35699
35737
|
const { gameId } = payload;
|
|
35700
35738
|
const current = store.getState().statesByGameId[gameId];
|
|
35701
|
-
if (!current)
|
|
35739
|
+
if (!current) {
|
|
35740
|
+
enqueue(gameId, event);
|
|
35741
|
+
return;
|
|
35742
|
+
}
|
|
35702
35743
|
const updated = isRpsCompletionPayload(payload) && isRpsState(current) ? {
|
|
35703
35744
|
...current,
|
|
35704
35745
|
status: "completed",
|
|
@@ -35747,11 +35788,15 @@ function createGameActionsStore(transport) {
|
|
|
35747
35788
|
const current = store.getState().statesByGameId[gameId];
|
|
35748
35789
|
const updated = current ? { ...current, ...incoming } : incoming;
|
|
35749
35790
|
updateState(gameId, updated);
|
|
35791
|
+
drainQueue(gameId);
|
|
35750
35792
|
break;
|
|
35751
35793
|
}
|
|
35752
35794
|
case "game:rematch:requested": {
|
|
35753
35795
|
const current = store.getState().statesByGameId[event.payload.gameId];
|
|
35754
|
-
if (!current)
|
|
35796
|
+
if (!current) {
|
|
35797
|
+
enqueue(event.payload.gameId, event);
|
|
35798
|
+
return;
|
|
35799
|
+
}
|
|
35755
35800
|
const requestedBy = event.payload.requestedBy;
|
|
35756
35801
|
const userId = event.payload.userId;
|
|
35757
35802
|
const requested = new Set(
|
|
@@ -35767,7 +35812,10 @@ function createGameActionsStore(transport) {
|
|
|
35767
35812
|
}
|
|
35768
35813
|
case "game:rematch:cancelled": {
|
|
35769
35814
|
const current = store.getState().statesByGameId[event.payload.gameId];
|
|
35770
|
-
if (!current)
|
|
35815
|
+
if (!current) {
|
|
35816
|
+
enqueue(event.payload.gameId, event);
|
|
35817
|
+
return;
|
|
35818
|
+
}
|
|
35771
35819
|
const requestedBy = event.payload.requestedBy ?? [];
|
|
35772
35820
|
const updated = {
|
|
35773
35821
|
...current,
|
|
@@ -35778,7 +35826,10 @@ function createGameActionsStore(transport) {
|
|
|
35778
35826
|
}
|
|
35779
35827
|
case "game:rematch:started": {
|
|
35780
35828
|
const current = store.getState().statesByGameId[event.payload.gameId];
|
|
35781
|
-
if (!current)
|
|
35829
|
+
if (!current) {
|
|
35830
|
+
enqueue(event.payload.gameId, event);
|
|
35831
|
+
return;
|
|
35832
|
+
}
|
|
35782
35833
|
const updated = {
|
|
35783
35834
|
...current,
|
|
35784
35835
|
rematchRequestedBy: event.payload.playerIds ?? []
|
|
@@ -35789,7 +35840,10 @@ function createGameActionsStore(transport) {
|
|
|
35789
35840
|
case "game:pot:updated": {
|
|
35790
35841
|
const { gameId, totalPotMinor } = event.payload;
|
|
35791
35842
|
const current = store.getState().statesByGameId[gameId];
|
|
35792
|
-
if (!current)
|
|
35843
|
+
if (!current) {
|
|
35844
|
+
enqueue(gameId, event);
|
|
35845
|
+
return;
|
|
35846
|
+
}
|
|
35793
35847
|
const updated = {
|
|
35794
35848
|
...current,
|
|
35795
35849
|
totalPotMinor
|
|
@@ -35802,12 +35856,123 @@ function createGameActionsStore(transport) {
|
|
|
35802
35856
|
}
|
|
35803
35857
|
};
|
|
35804
35858
|
const joinGame = (gameId) => transport.joinRoom(`game:${gameId}`);
|
|
35859
|
+
const getCountdownDigit = (gameId, nowMs) => {
|
|
35860
|
+
const state = store.getState().statesByGameId[gameId];
|
|
35861
|
+
if (!state) return null;
|
|
35862
|
+
if (isRpsState(state)) {
|
|
35863
|
+
if (state.roundState.phase !== "starting") return null;
|
|
35864
|
+
const remaining = new Date(state.roundState.selectionEndsAt).getTime() - nowMs;
|
|
35865
|
+
if (remaining <= 0) return null;
|
|
35866
|
+
return Math.ceil(remaining / 1e3);
|
|
35867
|
+
}
|
|
35868
|
+
const bufferEndsAt = state.bufferEndsAt;
|
|
35869
|
+
if (bufferEndsAt) {
|
|
35870
|
+
const remaining = new Date(bufferEndsAt).getTime() - nowMs;
|
|
35871
|
+
if (remaining <= 0) return null;
|
|
35872
|
+
return Math.ceil(remaining / 1e3);
|
|
35873
|
+
}
|
|
35874
|
+
return null;
|
|
35875
|
+
};
|
|
35876
|
+
const getChessClockTimes = (gameId, nowMs) => {
|
|
35877
|
+
const state = store.getState().statesByGameId[gameId];
|
|
35878
|
+
if (!state || state.gameType !== "chess") return null;
|
|
35879
|
+
const s = state;
|
|
35880
|
+
let whiteMs = s.whiteTimeMs ?? 0;
|
|
35881
|
+
let blackMs = s.blackTimeMs ?? 0;
|
|
35882
|
+
if (s.status === "active" && s.currentPlayerId) {
|
|
35883
|
+
const startedAt = Date.parse(s.turnStartedAt);
|
|
35884
|
+
if (!Number.isNaN(startedAt)) {
|
|
35885
|
+
const elapsed = Math.max(0, nowMs - startedAt);
|
|
35886
|
+
if (s.currentPlayerId === s.whitePlayerId) {
|
|
35887
|
+
whiteMs = Math.max(0, whiteMs - elapsed);
|
|
35888
|
+
} else if (s.currentPlayerId === s.blackPlayerId) {
|
|
35889
|
+
blackMs = Math.max(0, blackMs - elapsed);
|
|
35890
|
+
}
|
|
35891
|
+
}
|
|
35892
|
+
}
|
|
35893
|
+
return { whiteTimeMs: whiteMs, blackTimeMs: blackMs };
|
|
35894
|
+
};
|
|
35895
|
+
const getChessCapturedPieces = (gameId) => {
|
|
35896
|
+
const state = store.getState().statesByGameId[gameId];
|
|
35897
|
+
if (!state || state.gameType !== "chess") return null;
|
|
35898
|
+
const fen = state.fen;
|
|
35899
|
+
if (!fen) return { capturedByWhite: [], capturedByBlack: [] };
|
|
35900
|
+
const placement = fen.split(" ")[0];
|
|
35901
|
+
const white = {};
|
|
35902
|
+
const black = {};
|
|
35903
|
+
for (const char of placement) {
|
|
35904
|
+
if (char === "/" || char >= "1" && char <= "8") continue;
|
|
35905
|
+
const lower = char.toLowerCase();
|
|
35906
|
+
if (char === lower) {
|
|
35907
|
+
black[lower] = (black[lower] ?? 0) + 1;
|
|
35908
|
+
} else {
|
|
35909
|
+
white[lower] = (white[lower] ?? 0) + 1;
|
|
35910
|
+
}
|
|
35911
|
+
}
|
|
35912
|
+
const INITIAL = {
|
|
35913
|
+
p: 8,
|
|
35914
|
+
r: 2,
|
|
35915
|
+
n: 2,
|
|
35916
|
+
b: 2,
|
|
35917
|
+
q: 1,
|
|
35918
|
+
k: 1
|
|
35919
|
+
};
|
|
35920
|
+
const capturedByWhite = [];
|
|
35921
|
+
const capturedByBlack = [];
|
|
35922
|
+
for (const [type2, initial] of Object.entries(INITIAL)) {
|
|
35923
|
+
const missingBlack = initial - (black[type2] ?? 0);
|
|
35924
|
+
for (let i = 0; i < missingBlack; i++) capturedByWhite.push(`b${type2}`);
|
|
35925
|
+
const missingWhite = initial - (white[type2] ?? 0);
|
|
35926
|
+
for (let i = 0; i < missingWhite; i++) capturedByBlack.push(`w${type2}`);
|
|
35927
|
+
}
|
|
35928
|
+
return { capturedByWhite, capturedByBlack };
|
|
35929
|
+
};
|
|
35930
|
+
const getTicTacToeClockTimes = (gameId, nowMs) => {
|
|
35931
|
+
const state = store.getState().statesByGameId[gameId];
|
|
35932
|
+
if (!state || state.gameType !== "tic-tac-toe") return null;
|
|
35933
|
+
const s = state;
|
|
35934
|
+
let xMs = s.xTimeMs ?? 0;
|
|
35935
|
+
let oMs = s.oTimeMs ?? 0;
|
|
35936
|
+
if (s.status === "active" && s.currentPlayerId) {
|
|
35937
|
+
const currentMark = s.playerMarks[s.currentPlayerId];
|
|
35938
|
+
const startedAt = Date.parse(s.turnStartedAt);
|
|
35939
|
+
if (!Number.isNaN(startedAt)) {
|
|
35940
|
+
const elapsed = Math.max(0, nowMs - startedAt);
|
|
35941
|
+
if (currentMark === "X") xMs = Math.max(0, xMs - elapsed);
|
|
35942
|
+
else if (currentMark === "O") oMs = Math.max(0, oMs - elapsed);
|
|
35943
|
+
}
|
|
35944
|
+
}
|
|
35945
|
+
return { xTimeMs: xMs, oTimeMs: oMs };
|
|
35946
|
+
};
|
|
35947
|
+
const getConnect4ClockTimes = (gameId, nowMs) => {
|
|
35948
|
+
const state = store.getState().statesByGameId[gameId];
|
|
35949
|
+
if (!state || state.gameType !== "connect-four") return null;
|
|
35950
|
+
const s = state;
|
|
35951
|
+
let redMs = s.redTimeMs ?? 0;
|
|
35952
|
+
let yellowMs = s.yellowTimeMs ?? 0;
|
|
35953
|
+
if (s.status === "active" && s.currentPlayerId) {
|
|
35954
|
+
const currentColor = s.playerColors[s.currentPlayerId];
|
|
35955
|
+
const startedAt = Date.parse(s.turnStartedAt);
|
|
35956
|
+
if (!Number.isNaN(startedAt)) {
|
|
35957
|
+
const elapsed = Math.max(0, nowMs - startedAt);
|
|
35958
|
+
if (currentColor === "RED") redMs = Math.max(0, redMs - elapsed);
|
|
35959
|
+
else if (currentColor === "YELLOW")
|
|
35960
|
+
yellowMs = Math.max(0, yellowMs - elapsed);
|
|
35961
|
+
}
|
|
35962
|
+
}
|
|
35963
|
+
return { redTimeMs: redMs, yellowTimeMs: yellowMs };
|
|
35964
|
+
};
|
|
35805
35965
|
return {
|
|
35806
35966
|
store,
|
|
35807
35967
|
setBaseState,
|
|
35808
35968
|
clearState,
|
|
35809
35969
|
applyWsEvent,
|
|
35810
|
-
joinGame
|
|
35970
|
+
joinGame,
|
|
35971
|
+
getCountdownDigit,
|
|
35972
|
+
getChessClockTimes,
|
|
35973
|
+
getChessCapturedPieces,
|
|
35974
|
+
getTicTacToeClockTimes,
|
|
35975
|
+
getConnect4ClockTimes
|
|
35811
35976
|
};
|
|
35812
35977
|
}
|
|
35813
35978
|
function isRpsState(state) {
|
|
@@ -36465,12 +36630,14 @@ var WsRouter = class {
|
|
|
36465
36630
|
}
|
|
36466
36631
|
const decoded = decodeWsEvent(eventName, payload);
|
|
36467
36632
|
if (!decoded) return;
|
|
36468
|
-
|
|
36469
|
-
|
|
36470
|
-
this.deps.
|
|
36471
|
-
this.deps.
|
|
36472
|
-
this.deps.
|
|
36473
|
-
this.deps.
|
|
36633
|
+
const serverTs = payload !== null && typeof payload === "object" ? payload._serverTs : void 0;
|
|
36634
|
+
const event = serverTs !== void 0 ? { ...decoded, _serverTs: serverTs } : decoded;
|
|
36635
|
+
this.deps.lobbyStore.applyWsEvent(event);
|
|
36636
|
+
this.deps.gameStore.applyWsEvent(event);
|
|
36637
|
+
this.deps.gameActionsStore.applyWsEvent(event);
|
|
36638
|
+
this.deps.chatStore.applyWsEvent(event);
|
|
36639
|
+
this.deps.dmThreadsStore.applyWsEvent(event);
|
|
36640
|
+
this.deps.notificationsStore.applyWsEvent(event);
|
|
36474
36641
|
});
|
|
36475
36642
|
}
|
|
36476
36643
|
stop() {
|
|
@@ -36482,12 +36649,14 @@ var WsRouter = class {
|
|
|
36482
36649
|
this.transport.subscribeEvent(eventName, (payload) => {
|
|
36483
36650
|
const decoded = decodeWsEvent(eventName, payload);
|
|
36484
36651
|
if (!decoded) return;
|
|
36485
|
-
|
|
36486
|
-
|
|
36487
|
-
this.deps.
|
|
36488
|
-
this.deps.
|
|
36489
|
-
this.deps.
|
|
36490
|
-
this.deps.
|
|
36652
|
+
const serverTs = payload !== null && typeof payload === "object" ? payload._serverTs : void 0;
|
|
36653
|
+
const event = serverTs !== void 0 ? { ...decoded, _serverTs: serverTs } : decoded;
|
|
36654
|
+
this.deps.lobbyStore.applyWsEvent(event);
|
|
36655
|
+
this.deps.gameStore.applyWsEvent(event);
|
|
36656
|
+
this.deps.gameActionsStore.applyWsEvent(event);
|
|
36657
|
+
this.deps.chatStore.applyWsEvent(event);
|
|
36658
|
+
this.deps.dmThreadsStore.applyWsEvent(event);
|
|
36659
|
+
this.deps.notificationsStore.applyWsEvent(event);
|
|
36491
36660
|
});
|
|
36492
36661
|
}
|
|
36493
36662
|
}
|
|
@@ -36767,6 +36936,28 @@ var esm_default4 = esm_default3(ALPHABET2);
|
|
|
36767
36936
|
|
|
36768
36937
|
// ../dim-agent-core/src/client.ts
|
|
36769
36938
|
var import_tweetnacl = __toESM(require_nacl_fast(), 1);
|
|
36939
|
+
function decodeJwtSub(token) {
|
|
36940
|
+
try {
|
|
36941
|
+
const parts2 = token.split(".");
|
|
36942
|
+
if (parts2.length < 2) return null;
|
|
36943
|
+
const base64 = parts2[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
36944
|
+
const json = Buffer.from(base64, "base64").toString("utf-8");
|
|
36945
|
+
const parsed = JSON.parse(json);
|
|
36946
|
+
return typeof parsed.sub === "string" ? parsed.sub : null;
|
|
36947
|
+
} catch {
|
|
36948
|
+
return null;
|
|
36949
|
+
}
|
|
36950
|
+
}
|
|
36951
|
+
function signatureToBytes(sig) {
|
|
36952
|
+
if (sig.includes("-") || sig.includes("_")) {
|
|
36953
|
+
const padded = sig.replace(/-/g, "+").replace(/_/g, "/") + "==".slice(sig.length % 4 === 0 ? 4 : sig.length % 4);
|
|
36954
|
+
return new Uint8Array(Buffer.from(padded, "base64"));
|
|
36955
|
+
}
|
|
36956
|
+
if (/[+/=]/.test(sig)) {
|
|
36957
|
+
return new Uint8Array(Buffer.from(sig, "base64"));
|
|
36958
|
+
}
|
|
36959
|
+
return esm_default4.decode(sig);
|
|
36960
|
+
}
|
|
36770
36961
|
var DimAgentClient = class {
|
|
36771
36962
|
sdk;
|
|
36772
36963
|
agentConfig;
|
|
@@ -36793,10 +36984,19 @@ var DimAgentClient = class {
|
|
|
36793
36984
|
} else {
|
|
36794
36985
|
this.keypair = null;
|
|
36795
36986
|
}
|
|
36987
|
+
const storage = new NodeStorage();
|
|
36988
|
+
if (config.accessToken) {
|
|
36989
|
+
storage.set(TOKEN_KEY, config.accessToken);
|
|
36990
|
+
const sub = decodeJwtSub(config.accessToken);
|
|
36991
|
+
if (sub) {
|
|
36992
|
+
this.authenticated = true;
|
|
36993
|
+
this.userId = sub;
|
|
36994
|
+
}
|
|
36995
|
+
}
|
|
36796
36996
|
this.sdk = new SDK({
|
|
36797
36997
|
appId: "dim-agents",
|
|
36798
36998
|
baseUrl: config.apiUrl || "https://api.dim.cool",
|
|
36799
|
-
storage
|
|
36999
|
+
storage,
|
|
36800
37000
|
autoPay: {
|
|
36801
37001
|
enabled: !this.externalSignerMode,
|
|
36802
37002
|
maxAmountMinor: 25e3,
|
|
@@ -36900,10 +37100,10 @@ var DimAgentClient = class {
|
|
|
36900
37100
|
/**
|
|
36901
37101
|
* Complete authentication using an externally provided signature (external signer mode).
|
|
36902
37102
|
* @param address - Solana wallet address (base58)
|
|
36903
|
-
* @param
|
|
37103
|
+
* @param signature - Detached ed25519 signature in base58, base64, or base64url (from sign_solana_message)
|
|
36904
37104
|
*/
|
|
36905
|
-
async completeAuth(address,
|
|
36906
|
-
const signatureBytes =
|
|
37105
|
+
async completeAuth(address, signature) {
|
|
37106
|
+
const signatureBytes = signatureToBytes(signature);
|
|
36907
37107
|
const signedMessage = Buffer.from(signatureBytes).toString("base64");
|
|
36908
37108
|
const response = await this.sdk.auth.loginWithExternalSignature(
|
|
36909
37109
|
address,
|
|
@@ -37057,7 +37257,7 @@ async function requestAuthMessage(client, args) {
|
|
|
37057
37257
|
data: {
|
|
37058
37258
|
message,
|
|
37059
37259
|
address: args.address,
|
|
37060
|
-
nextStep: 'Sign this message with sign_solana_message (networkId: "solana:mainnet"), then call dim_complete_login with the address and the base58
|
|
37260
|
+
nextStep: 'Sign this message with sign_solana_message (networkId: "solana:mainnet"), then call dim_complete_login with the address and the signature. Accepted formats: base58, base64, or base64url (all formats returned by wallet MCPs are accepted).'
|
|
37061
37261
|
}
|
|
37062
37262
|
};
|
|
37063
37263
|
} catch (error) {
|
|
@@ -39231,6 +39431,22 @@ async function getGameHistory(client, args) {
|
|
|
39231
39431
|
};
|
|
39232
39432
|
}
|
|
39233
39433
|
}
|
|
39434
|
+
async function reportUser(client, args) {
|
|
39435
|
+
try {
|
|
39436
|
+
await client.sdk.reports.create(args.userId, args.reason);
|
|
39437
|
+
return {
|
|
39438
|
+
data: {
|
|
39439
|
+
success: true,
|
|
39440
|
+
hint: "Report submitted. The DIM moderation team will review it."
|
|
39441
|
+
}
|
|
39442
|
+
};
|
|
39443
|
+
} catch (error) {
|
|
39444
|
+
return {
|
|
39445
|
+
error: `Failed to report user: ${error instanceof Error ? error.message : String(error)}`,
|
|
39446
|
+
isError: true
|
|
39447
|
+
};
|
|
39448
|
+
}
|
|
39449
|
+
}
|
|
39234
39450
|
async function getMyStats(client) {
|
|
39235
39451
|
try {
|
|
39236
39452
|
if (!client.currentUserId) {
|
|
@@ -39276,7 +39492,7 @@ var TOOL_DEFINITIONS = [
|
|
|
39276
39492
|
},
|
|
39277
39493
|
{
|
|
39278
39494
|
name: "dim_complete_login",
|
|
39279
|
-
description: "External wallet login step 2: provide the wallet address and
|
|
39495
|
+
description: "External wallet login step 2: provide the wallet address and signature from sign_solana_message to complete authentication with DIM.",
|
|
39280
39496
|
params: {
|
|
39281
39497
|
address: {
|
|
39282
39498
|
type: "string",
|
|
@@ -39285,7 +39501,7 @@ var TOOL_DEFINITIONS = [
|
|
|
39285
39501
|
},
|
|
39286
39502
|
signature: {
|
|
39287
39503
|
type: "string",
|
|
39288
|
-
description: "
|
|
39504
|
+
description: "Signature from sign_solana_message \u2014 base58, base64, or base64url accepted",
|
|
39289
39505
|
required: true
|
|
39290
39506
|
}
|
|
39291
39507
|
},
|
|
@@ -39729,6 +39945,23 @@ var TOOL_DEFINITIONS = [
|
|
|
39729
39945
|
params: {},
|
|
39730
39946
|
execute: (c) => getMyStats(c)
|
|
39731
39947
|
},
|
|
39948
|
+
{
|
|
39949
|
+
name: "dim_report_user",
|
|
39950
|
+
description: "Report a user for cheating, harassment, or other violations. Rate limited to 5 reports per hour.",
|
|
39951
|
+
params: {
|
|
39952
|
+
userId: {
|
|
39953
|
+
type: "string",
|
|
39954
|
+
description: "The ID of the user to report",
|
|
39955
|
+
required: true
|
|
39956
|
+
},
|
|
39957
|
+
reason: {
|
|
39958
|
+
type: "string",
|
|
39959
|
+
description: "Reason for the report (max 300 characters)",
|
|
39960
|
+
required: true
|
|
39961
|
+
}
|
|
39962
|
+
},
|
|
39963
|
+
execute: (c, a) => reportUser(c, a)
|
|
39964
|
+
},
|
|
39732
39965
|
{
|
|
39733
39966
|
name: "dim_create_lobby",
|
|
39734
39967
|
description: "Create a new game lobby. Bet amount is in USDC dollars (e.g., 1.00 for $1.00). A 1% fee (min 1 cent) is charged per player.",
|
|
@@ -40293,11 +40526,18 @@ async function executeWithAuthRetry(client, tool, params) {
|
|
|
40293
40526
|
if (tool.name === "dim_login") {
|
|
40294
40527
|
return tool.execute(client, params);
|
|
40295
40528
|
}
|
|
40529
|
+
if (client.externalSignerMode) {
|
|
40530
|
+
return tool.execute(client, params);
|
|
40531
|
+
}
|
|
40296
40532
|
try {
|
|
40297
40533
|
const result = await tool.execute(client, params);
|
|
40298
40534
|
if (!result.error && !result.isError) return result;
|
|
40299
40535
|
if (!isUnauthorizedResult(result)) return result;
|
|
40300
|
-
|
|
40536
|
+
try {
|
|
40537
|
+
await client.authenticate();
|
|
40538
|
+
} catch {
|
|
40539
|
+
return { error: UNAUTHORIZED_MESSAGE, isError: true };
|
|
40540
|
+
}
|
|
40301
40541
|
const retryResult = await tool.execute(client, params);
|
|
40302
40542
|
if (retryResult.isError || retryResult.error) {
|
|
40303
40543
|
if (isUnauthorizedResult(retryResult)) {
|
package/package.json
CHANGED