@dimcool/dimclaw 0.1.26 → 0.1.28
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 +829 -173
- package/index.ts +16 -1
- package/openclaw.plugin.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5478,17 +5478,17 @@ function v35_default(name, version2, hashfunc) {
|
|
|
5478
5478
|
} catch (err) {
|
|
5479
5479
|
}
|
|
5480
5480
|
generateUUID.DNS = DNS;
|
|
5481
|
-
generateUUID.URL =
|
|
5481
|
+
generateUUID.URL = URL2;
|
|
5482
5482
|
return generateUUID;
|
|
5483
5483
|
}
|
|
5484
|
-
var DNS,
|
|
5484
|
+
var DNS, URL2;
|
|
5485
5485
|
var init_v35 = __esm({
|
|
5486
5486
|
"../../node_modules/jayson/node_modules/uuid/dist/esm-node/v35.js"() {
|
|
5487
5487
|
"use strict";
|
|
5488
5488
|
init_stringify();
|
|
5489
5489
|
init_parse();
|
|
5490
5490
|
DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
|
|
5491
|
-
|
|
5491
|
+
URL2 = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
|
|
5492
5492
|
}
|
|
5493
5493
|
});
|
|
5494
5494
|
|
|
@@ -6513,14 +6513,14 @@ var require_url_state_machine = __commonJS({
|
|
|
6513
6513
|
return url3.replace(/\u0009|\u000A|\u000D/g, "");
|
|
6514
6514
|
}
|
|
6515
6515
|
function shortenPath(url3) {
|
|
6516
|
-
const
|
|
6517
|
-
if (
|
|
6516
|
+
const path3 = url3.path;
|
|
6517
|
+
if (path3.length === 0) {
|
|
6518
6518
|
return;
|
|
6519
6519
|
}
|
|
6520
|
-
if (url3.scheme === "file" &&
|
|
6520
|
+
if (url3.scheme === "file" && path3.length === 1 && isNormalizedWindowsDriveLetter(path3[0])) {
|
|
6521
6521
|
return;
|
|
6522
6522
|
}
|
|
6523
|
-
|
|
6523
|
+
path3.pop();
|
|
6524
6524
|
}
|
|
6525
6525
|
function includesCredentials(url3) {
|
|
6526
6526
|
return url3.username !== "" || url3.password !== "";
|
|
@@ -7360,8 +7360,8 @@ var require_URL = __commonJS({
|
|
|
7360
7360
|
var utils = require_utils();
|
|
7361
7361
|
var Impl = require_URL_impl();
|
|
7362
7362
|
var impl = utils.implSymbol;
|
|
7363
|
-
function
|
|
7364
|
-
if (!this || this[impl] || !(this instanceof
|
|
7363
|
+
function URL4(url3) {
|
|
7364
|
+
if (!this || this[impl] || !(this instanceof URL4)) {
|
|
7365
7365
|
throw new TypeError("Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function.");
|
|
7366
7366
|
}
|
|
7367
7367
|
if (arguments.length < 1) {
|
|
@@ -7377,7 +7377,7 @@ var require_URL = __commonJS({
|
|
|
7377
7377
|
}
|
|
7378
7378
|
module.exports.setup(this, args);
|
|
7379
7379
|
}
|
|
7380
|
-
|
|
7380
|
+
URL4.prototype.toJSON = function toJSON() {
|
|
7381
7381
|
if (!this || !module.exports.is(this)) {
|
|
7382
7382
|
throw new TypeError("Illegal invocation");
|
|
7383
7383
|
}
|
|
@@ -7387,7 +7387,7 @@ var require_URL = __commonJS({
|
|
|
7387
7387
|
}
|
|
7388
7388
|
return this[impl].toJSON.apply(this[impl], args);
|
|
7389
7389
|
};
|
|
7390
|
-
Object.defineProperty(
|
|
7390
|
+
Object.defineProperty(URL4.prototype, "href", {
|
|
7391
7391
|
get() {
|
|
7392
7392
|
return this[impl].href;
|
|
7393
7393
|
},
|
|
@@ -7398,20 +7398,20 @@ var require_URL = __commonJS({
|
|
|
7398
7398
|
enumerable: true,
|
|
7399
7399
|
configurable: true
|
|
7400
7400
|
});
|
|
7401
|
-
|
|
7401
|
+
URL4.prototype.toString = function() {
|
|
7402
7402
|
if (!this || !module.exports.is(this)) {
|
|
7403
7403
|
throw new TypeError("Illegal invocation");
|
|
7404
7404
|
}
|
|
7405
7405
|
return this.href;
|
|
7406
7406
|
};
|
|
7407
|
-
Object.defineProperty(
|
|
7407
|
+
Object.defineProperty(URL4.prototype, "origin", {
|
|
7408
7408
|
get() {
|
|
7409
7409
|
return this[impl].origin;
|
|
7410
7410
|
},
|
|
7411
7411
|
enumerable: true,
|
|
7412
7412
|
configurable: true
|
|
7413
7413
|
});
|
|
7414
|
-
Object.defineProperty(
|
|
7414
|
+
Object.defineProperty(URL4.prototype, "protocol", {
|
|
7415
7415
|
get() {
|
|
7416
7416
|
return this[impl].protocol;
|
|
7417
7417
|
},
|
|
@@ -7422,7 +7422,7 @@ var require_URL = __commonJS({
|
|
|
7422
7422
|
enumerable: true,
|
|
7423
7423
|
configurable: true
|
|
7424
7424
|
});
|
|
7425
|
-
Object.defineProperty(
|
|
7425
|
+
Object.defineProperty(URL4.prototype, "username", {
|
|
7426
7426
|
get() {
|
|
7427
7427
|
return this[impl].username;
|
|
7428
7428
|
},
|
|
@@ -7433,7 +7433,7 @@ var require_URL = __commonJS({
|
|
|
7433
7433
|
enumerable: true,
|
|
7434
7434
|
configurable: true
|
|
7435
7435
|
});
|
|
7436
|
-
Object.defineProperty(
|
|
7436
|
+
Object.defineProperty(URL4.prototype, "password", {
|
|
7437
7437
|
get() {
|
|
7438
7438
|
return this[impl].password;
|
|
7439
7439
|
},
|
|
@@ -7444,7 +7444,7 @@ var require_URL = __commonJS({
|
|
|
7444
7444
|
enumerable: true,
|
|
7445
7445
|
configurable: true
|
|
7446
7446
|
});
|
|
7447
|
-
Object.defineProperty(
|
|
7447
|
+
Object.defineProperty(URL4.prototype, "host", {
|
|
7448
7448
|
get() {
|
|
7449
7449
|
return this[impl].host;
|
|
7450
7450
|
},
|
|
@@ -7455,7 +7455,7 @@ var require_URL = __commonJS({
|
|
|
7455
7455
|
enumerable: true,
|
|
7456
7456
|
configurable: true
|
|
7457
7457
|
});
|
|
7458
|
-
Object.defineProperty(
|
|
7458
|
+
Object.defineProperty(URL4.prototype, "hostname", {
|
|
7459
7459
|
get() {
|
|
7460
7460
|
return this[impl].hostname;
|
|
7461
7461
|
},
|
|
@@ -7466,7 +7466,7 @@ var require_URL = __commonJS({
|
|
|
7466
7466
|
enumerable: true,
|
|
7467
7467
|
configurable: true
|
|
7468
7468
|
});
|
|
7469
|
-
Object.defineProperty(
|
|
7469
|
+
Object.defineProperty(URL4.prototype, "port", {
|
|
7470
7470
|
get() {
|
|
7471
7471
|
return this[impl].port;
|
|
7472
7472
|
},
|
|
@@ -7477,7 +7477,7 @@ var require_URL = __commonJS({
|
|
|
7477
7477
|
enumerable: true,
|
|
7478
7478
|
configurable: true
|
|
7479
7479
|
});
|
|
7480
|
-
Object.defineProperty(
|
|
7480
|
+
Object.defineProperty(URL4.prototype, "pathname", {
|
|
7481
7481
|
get() {
|
|
7482
7482
|
return this[impl].pathname;
|
|
7483
7483
|
},
|
|
@@ -7488,7 +7488,7 @@ var require_URL = __commonJS({
|
|
|
7488
7488
|
enumerable: true,
|
|
7489
7489
|
configurable: true
|
|
7490
7490
|
});
|
|
7491
|
-
Object.defineProperty(
|
|
7491
|
+
Object.defineProperty(URL4.prototype, "search", {
|
|
7492
7492
|
get() {
|
|
7493
7493
|
return this[impl].search;
|
|
7494
7494
|
},
|
|
@@ -7499,7 +7499,7 @@ var require_URL = __commonJS({
|
|
|
7499
7499
|
enumerable: true,
|
|
7500
7500
|
configurable: true
|
|
7501
7501
|
});
|
|
7502
|
-
Object.defineProperty(
|
|
7502
|
+
Object.defineProperty(URL4.prototype, "hash", {
|
|
7503
7503
|
get() {
|
|
7504
7504
|
return this[impl].hash;
|
|
7505
7505
|
},
|
|
@@ -7515,7 +7515,7 @@ var require_URL = __commonJS({
|
|
|
7515
7515
|
return !!obj && obj[impl] instanceof Impl.implementation;
|
|
7516
7516
|
},
|
|
7517
7517
|
create(constructorArgs, privateData) {
|
|
7518
|
-
let obj = Object.create(
|
|
7518
|
+
let obj = Object.create(URL4.prototype);
|
|
7519
7519
|
this.setup(obj, constructorArgs, privateData);
|
|
7520
7520
|
return obj;
|
|
7521
7521
|
},
|
|
@@ -7525,10 +7525,10 @@ var require_URL = __commonJS({
|
|
|
7525
7525
|
obj[impl] = new Impl.implementation(constructorArgs, privateData);
|
|
7526
7526
|
obj[impl][utils.wrapperSymbol] = obj;
|
|
7527
7527
|
},
|
|
7528
|
-
interface:
|
|
7528
|
+
interface: URL4,
|
|
7529
7529
|
expose: {
|
|
7530
|
-
Window: { URL:
|
|
7531
|
-
Worker: { URL:
|
|
7530
|
+
Window: { URL: URL4 },
|
|
7531
|
+
Worker: { URL: URL4 }
|
|
7532
7532
|
}
|
|
7533
7533
|
};
|
|
7534
7534
|
}
|
|
@@ -7576,8 +7576,8 @@ var require_constants = __commonJS({
|
|
|
7576
7576
|
var require_node_gyp_build = __commonJS({
|
|
7577
7577
|
"../../node_modules/node-gyp-build/node-gyp-build.js"(exports, module) {
|
|
7578
7578
|
"use strict";
|
|
7579
|
-
var
|
|
7580
|
-
var
|
|
7579
|
+
var fs2 = __require("fs");
|
|
7580
|
+
var path3 = __require("path");
|
|
7581
7581
|
var os = __require("os");
|
|
7582
7582
|
var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
7583
7583
|
var vars = process.config && process.config.variables || {};
|
|
@@ -7594,21 +7594,21 @@ var require_node_gyp_build = __commonJS({
|
|
|
7594
7594
|
return runtimeRequire(load.resolve(dir));
|
|
7595
7595
|
}
|
|
7596
7596
|
load.resolve = load.path = function(dir) {
|
|
7597
|
-
dir =
|
|
7597
|
+
dir = path3.resolve(dir || ".");
|
|
7598
7598
|
try {
|
|
7599
|
-
var name = runtimeRequire(
|
|
7599
|
+
var name = runtimeRequire(path3.join(dir, "package.json")).name.toUpperCase().replace(/-/g, "_");
|
|
7600
7600
|
if (process.env[name + "_PREBUILD"]) dir = process.env[name + "_PREBUILD"];
|
|
7601
7601
|
} catch (err) {
|
|
7602
7602
|
}
|
|
7603
7603
|
if (!prebuildsOnly) {
|
|
7604
|
-
var release = getFirst(
|
|
7604
|
+
var release = getFirst(path3.join(dir, "build/Release"), matchBuild);
|
|
7605
7605
|
if (release) return release;
|
|
7606
|
-
var debug12 = getFirst(
|
|
7606
|
+
var debug12 = getFirst(path3.join(dir, "build/Debug"), matchBuild);
|
|
7607
7607
|
if (debug12) return debug12;
|
|
7608
7608
|
}
|
|
7609
|
-
var prebuild =
|
|
7609
|
+
var prebuild = resolve2(dir);
|
|
7610
7610
|
if (prebuild) return prebuild;
|
|
7611
|
-
var nearby =
|
|
7611
|
+
var nearby = resolve2(path3.dirname(process.execPath));
|
|
7612
7612
|
if (nearby) return nearby;
|
|
7613
7613
|
var target = [
|
|
7614
7614
|
"platform=" + platform,
|
|
@@ -7624,27 +7624,27 @@ var require_node_gyp_build = __commonJS({
|
|
|
7624
7624
|
// eslint-disable-line
|
|
7625
7625
|
].filter(Boolean).join(" ");
|
|
7626
7626
|
throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
|
|
7627
|
-
function
|
|
7628
|
-
var tuples = readdirSync(
|
|
7627
|
+
function resolve2(dir2) {
|
|
7628
|
+
var tuples = readdirSync(path3.join(dir2, "prebuilds")).map(parseTuple);
|
|
7629
7629
|
var tuple2 = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0];
|
|
7630
7630
|
if (!tuple2) return;
|
|
7631
|
-
var prebuilds =
|
|
7631
|
+
var prebuilds = path3.join(dir2, "prebuilds", tuple2.name);
|
|
7632
7632
|
var parsed = readdirSync(prebuilds).map(parseTags);
|
|
7633
7633
|
var candidates = parsed.filter(matchTags(runtime, abi));
|
|
7634
7634
|
var winner = candidates.sort(compareTags(runtime))[0];
|
|
7635
|
-
if (winner) return
|
|
7635
|
+
if (winner) return path3.join(prebuilds, winner.file);
|
|
7636
7636
|
}
|
|
7637
7637
|
};
|
|
7638
7638
|
function readdirSync(dir) {
|
|
7639
7639
|
try {
|
|
7640
|
-
return
|
|
7640
|
+
return fs2.readdirSync(dir);
|
|
7641
7641
|
} catch (err) {
|
|
7642
7642
|
return [];
|
|
7643
7643
|
}
|
|
7644
7644
|
}
|
|
7645
7645
|
function getFirst(dir, filter) {
|
|
7646
7646
|
var files = readdirSync(dir).filter(filter);
|
|
7647
|
-
return files[0] &&
|
|
7647
|
+
return files[0] && path3.join(dir, files[0]);
|
|
7648
7648
|
}
|
|
7649
7649
|
function matchBuild(name) {
|
|
7650
7650
|
return /\.node$/.test(name);
|
|
@@ -7731,7 +7731,7 @@ var require_node_gyp_build = __commonJS({
|
|
|
7731
7731
|
return typeof window !== "undefined" && window.process && window.process.type === "renderer";
|
|
7732
7732
|
}
|
|
7733
7733
|
function isAlpine(platform2) {
|
|
7734
|
-
return platform2 === "linux" &&
|
|
7734
|
+
return platform2 === "linux" && fs2.existsSync("/etc/alpine-release");
|
|
7735
7735
|
}
|
|
7736
7736
|
load.parseTags = parseTags;
|
|
7737
7737
|
load.matchTags = matchTags;
|
|
@@ -10017,7 +10017,7 @@ var require_websocket = __commonJS({
|
|
|
10017
10017
|
var tls = __require("tls");
|
|
10018
10018
|
var { randomBytes: randomBytes2, createHash } = __require("crypto");
|
|
10019
10019
|
var { Duplex, Readable: Readable2 } = __require("stream");
|
|
10020
|
-
var { URL:
|
|
10020
|
+
var { URL: URL4 } = __require("url");
|
|
10021
10021
|
var PerMessageDeflate = require_permessage_deflate();
|
|
10022
10022
|
var Receiver3 = require_receiver();
|
|
10023
10023
|
var Sender3 = require_sender();
|
|
@@ -10507,11 +10507,11 @@ var require_websocket = __commonJS({
|
|
|
10507
10507
|
);
|
|
10508
10508
|
}
|
|
10509
10509
|
let parsedUrl;
|
|
10510
|
-
if (address instanceof
|
|
10510
|
+
if (address instanceof URL4) {
|
|
10511
10511
|
parsedUrl = address;
|
|
10512
10512
|
} else {
|
|
10513
10513
|
try {
|
|
10514
|
-
parsedUrl = new
|
|
10514
|
+
parsedUrl = new URL4(address);
|
|
10515
10515
|
} catch (e) {
|
|
10516
10516
|
throw new SyntaxError(`Invalid URL: ${address}`);
|
|
10517
10517
|
}
|
|
@@ -10648,7 +10648,7 @@ var require_websocket = __commonJS({
|
|
|
10648
10648
|
req.abort();
|
|
10649
10649
|
let addr;
|
|
10650
10650
|
try {
|
|
10651
|
-
addr = new
|
|
10651
|
+
addr = new URL4(location2, address);
|
|
10652
10652
|
} catch (e) {
|
|
10653
10653
|
const err = new SyntaxError(`Invalid URL: ${location2}`);
|
|
10654
10654
|
emitErrorAndClose(websocket, err);
|
|
@@ -11587,7 +11587,7 @@ var require_eventemitter3 = __commonJS({
|
|
|
11587
11587
|
var require_XMLHttpRequest = __commonJS({
|
|
11588
11588
|
"../../node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js"(exports, module) {
|
|
11589
11589
|
"use strict";
|
|
11590
|
-
var
|
|
11590
|
+
var fs2 = __require("fs");
|
|
11591
11591
|
var Url2 = __require("url");
|
|
11592
11592
|
var spawn = __require("child_process").spawn;
|
|
11593
11593
|
module.exports = XMLHttpRequest3;
|
|
@@ -11745,7 +11745,7 @@ var require_XMLHttpRequest = __commonJS({
|
|
|
11745
11745
|
throw new Error("XMLHttpRequest: Only GET method is supported");
|
|
11746
11746
|
}
|
|
11747
11747
|
if (settings.async) {
|
|
11748
|
-
|
|
11748
|
+
fs2.readFile(unescape(url3.pathname), function(error, data2) {
|
|
11749
11749
|
if (error) {
|
|
11750
11750
|
self2.handleError(error, error.errno || -1);
|
|
11751
11751
|
} else {
|
|
@@ -11757,7 +11757,7 @@ var require_XMLHttpRequest = __commonJS({
|
|
|
11757
11757
|
});
|
|
11758
11758
|
} else {
|
|
11759
11759
|
try {
|
|
11760
|
-
this.response =
|
|
11760
|
+
this.response = fs2.readFileSync(unescape(url3.pathname));
|
|
11761
11761
|
this.responseText = this.response.toString("utf8");
|
|
11762
11762
|
this.status = 200;
|
|
11763
11763
|
setState(self2.DONE);
|
|
@@ -11883,15 +11883,15 @@ var require_XMLHttpRequest = __commonJS({
|
|
|
11883
11883
|
} else {
|
|
11884
11884
|
var contentFile = ".node-xmlhttprequest-content-" + process.pid;
|
|
11885
11885
|
var syncFile = ".node-xmlhttprequest-sync-" + process.pid;
|
|
11886
|
-
|
|
11886
|
+
fs2.writeFileSync(syncFile, "", "utf8");
|
|
11887
11887
|
var execString = "var http = require('http'), https = require('https'), fs = require('fs');var doRequest = http" + (ssl ? "s" : "") + ".request;var options = " + JSON.stringify(options) + ";var responseText = '';var responseData = Buffer.alloc(0);var req = doRequest(options, function(response) {response.on('data', function(chunk) { var data = Buffer.from(chunk); responseText += data.toString('utf8'); responseData = Buffer.concat([responseData, data]);});response.on('end', function() {fs.writeFileSync('" + contentFile + "', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText, data: responseData.toString('base64')}}), 'utf8');fs.unlinkSync('" + syncFile + "');});response.on('error', function(error) {fs.writeFileSync('" + contentFile + "', 'NODE-XMLHTTPREQUEST-ERROR:' + JSON.stringify(error), 'utf8');fs.unlinkSync('" + syncFile + "');});}).on('error', function(error) {fs.writeFileSync('" + contentFile + "', 'NODE-XMLHTTPREQUEST-ERROR:' + JSON.stringify(error), 'utf8');fs.unlinkSync('" + syncFile + "');});" + (data ? "req.write('" + JSON.stringify(data).slice(1, -1).replace(/'/g, "\\'") + "');" : "") + "req.end();";
|
|
11888
11888
|
var syncProc = spawn(process.argv[0], ["-e", execString]);
|
|
11889
11889
|
var statusText;
|
|
11890
|
-
while (
|
|
11890
|
+
while (fs2.existsSync(syncFile)) {
|
|
11891
11891
|
}
|
|
11892
|
-
self2.responseText =
|
|
11892
|
+
self2.responseText = fs2.readFileSync(contentFile, "utf8");
|
|
11893
11893
|
syncProc.stdin.end();
|
|
11894
|
-
|
|
11894
|
+
fs2.unlinkSync(contentFile);
|
|
11895
11895
|
if (self2.responseText.match(/^NODE-XMLHTTPREQUEST-ERROR:/)) {
|
|
11896
11896
|
var errorObj = JSON.parse(self2.responseText.replace(/^NODE-XMLHTTPREQUEST-ERROR:/, ""));
|
|
11897
11897
|
self2.handleError(errorObj, 503);
|
|
@@ -14959,7 +14959,7 @@ var require_websocket2 = __commonJS({
|
|
|
14959
14959
|
var tls = __require("tls");
|
|
14960
14960
|
var { randomBytes: randomBytes2, createHash } = __require("crypto");
|
|
14961
14961
|
var { Duplex, Readable: Readable2 } = __require("stream");
|
|
14962
|
-
var { URL:
|
|
14962
|
+
var { URL: URL4 } = __require("url");
|
|
14963
14963
|
var PerMessageDeflate = require_permessage_deflate2();
|
|
14964
14964
|
var Receiver3 = require_receiver2();
|
|
14965
14965
|
var Sender3 = require_sender2();
|
|
@@ -15449,11 +15449,11 @@ var require_websocket2 = __commonJS({
|
|
|
15449
15449
|
);
|
|
15450
15450
|
}
|
|
15451
15451
|
let parsedUrl;
|
|
15452
|
-
if (address instanceof
|
|
15452
|
+
if (address instanceof URL4) {
|
|
15453
15453
|
parsedUrl = address;
|
|
15454
15454
|
} else {
|
|
15455
15455
|
try {
|
|
15456
|
-
parsedUrl = new
|
|
15456
|
+
parsedUrl = new URL4(address);
|
|
15457
15457
|
} catch (e) {
|
|
15458
15458
|
throw new SyntaxError(`Invalid URL: ${address}`);
|
|
15459
15459
|
}
|
|
@@ -15590,7 +15590,7 @@ var require_websocket2 = __commonJS({
|
|
|
15590
15590
|
req.abort();
|
|
15591
15591
|
let addr;
|
|
15592
15592
|
try {
|
|
15593
|
-
addr = new
|
|
15593
|
+
addr = new URL4(location2, address);
|
|
15594
15594
|
} catch (e) {
|
|
15595
15595
|
const err = new SyntaxError(`Invalid URL: ${location2}`);
|
|
15596
15596
|
emitErrorAndClose(websocket, err);
|
|
@@ -18589,8 +18589,8 @@ var require_nacl_fast = __commonJS({
|
|
|
18589
18589
|
});
|
|
18590
18590
|
|
|
18591
18591
|
// index.ts
|
|
18592
|
-
import { mkdir, readFile, rename, writeFile } from "fs/promises";
|
|
18593
|
-
import
|
|
18592
|
+
import { mkdir, readFile as readFile2, rename, writeFile } from "fs/promises";
|
|
18593
|
+
import path2 from "path";
|
|
18594
18594
|
|
|
18595
18595
|
// ../../node_modules/@solana/web3.js/lib/index.esm.js
|
|
18596
18596
|
import { Buffer as Buffer2 } from "buffer";
|
|
@@ -21589,8 +21589,8 @@ var StructError = class extends TypeError {
|
|
|
21589
21589
|
constructor(failure, failures) {
|
|
21590
21590
|
let cached;
|
|
21591
21591
|
const { message, explanation, ...rest } = failure;
|
|
21592
|
-
const { path:
|
|
21593
|
-
const msg =
|
|
21592
|
+
const { path: path3 } = failure;
|
|
21593
|
+
const msg = path3.length === 0 ? message : `At path: ${path3.join(".")} -- ${message}`;
|
|
21594
21594
|
super(explanation ?? msg);
|
|
21595
21595
|
if (explanation != null)
|
|
21596
21596
|
this.cause = msg;
|
|
@@ -21628,15 +21628,15 @@ function toFailure(result, context, struct2, value2) {
|
|
|
21628
21628
|
} else if (typeof result === "string") {
|
|
21629
21629
|
result = { message: result };
|
|
21630
21630
|
}
|
|
21631
|
-
const { path:
|
|
21631
|
+
const { path: path3, branch } = context;
|
|
21632
21632
|
const { type: type2 } = struct2;
|
|
21633
21633
|
const { refinement, message = `Expected a value of type \`${type2}\`${refinement ? ` with refinement \`${refinement}\`` : ""}, but received: \`${print(value2)}\`` } = result;
|
|
21634
21634
|
return {
|
|
21635
21635
|
value: value2,
|
|
21636
21636
|
type: type2,
|
|
21637
21637
|
refinement,
|
|
21638
|
-
key:
|
|
21639
|
-
path:
|
|
21638
|
+
key: path3[path3.length - 1],
|
|
21639
|
+
path: path3,
|
|
21640
21640
|
branch,
|
|
21641
21641
|
...result,
|
|
21642
21642
|
message
|
|
@@ -21654,8 +21654,8 @@ function* toFailures(result, context, struct2, value2) {
|
|
|
21654
21654
|
}
|
|
21655
21655
|
}
|
|
21656
21656
|
function* run(value2, struct2, options = {}) {
|
|
21657
|
-
const { path:
|
|
21658
|
-
const ctx = { path:
|
|
21657
|
+
const { path: path3 = [], branch = [value2], coerce: coerce2 = false, mask: mask2 = false } = options;
|
|
21658
|
+
const ctx = { path: path3, branch, mask: mask2 };
|
|
21659
21659
|
if (coerce2) {
|
|
21660
21660
|
value2 = struct2.coercer(value2, ctx);
|
|
21661
21661
|
}
|
|
@@ -21667,7 +21667,7 @@ function* run(value2, struct2, options = {}) {
|
|
|
21667
21667
|
}
|
|
21668
21668
|
for (let [k, v, s] of struct2.entries(value2, ctx)) {
|
|
21669
21669
|
const ts = run(v, s, {
|
|
21670
|
-
path: k === void 0 ?
|
|
21670
|
+
path: k === void 0 ? path3 : [...path3, k],
|
|
21671
21671
|
branch: k === void 0 ? branch : [...branch, v],
|
|
21672
21672
|
coerce: coerce2,
|
|
21673
21673
|
mask: mask2,
|
|
@@ -22282,7 +22282,7 @@ function consumeBody() {
|
|
|
22282
22282
|
let accum = [];
|
|
22283
22283
|
let accumBytes = 0;
|
|
22284
22284
|
let abort = false;
|
|
22285
|
-
return new Body.Promise(function(
|
|
22285
|
+
return new Body.Promise(function(resolve2, reject) {
|
|
22286
22286
|
let resTimeout;
|
|
22287
22287
|
if (_this4.timeout) {
|
|
22288
22288
|
resTimeout = setTimeout(function() {
|
|
@@ -22316,7 +22316,7 @@ function consumeBody() {
|
|
|
22316
22316
|
}
|
|
22317
22317
|
clearTimeout(resTimeout);
|
|
22318
22318
|
try {
|
|
22319
|
-
|
|
22319
|
+
resolve2(Buffer.concat(accum, accumBytes));
|
|
22320
22320
|
} catch (err) {
|
|
22321
22321
|
reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, "system", err));
|
|
22322
22322
|
}
|
|
@@ -22817,12 +22817,12 @@ Object.defineProperty(Response.prototype, Symbol.toStringTag, {
|
|
|
22817
22817
|
configurable: true
|
|
22818
22818
|
});
|
|
22819
22819
|
var INTERNALS$2 = /* @__PURE__ */ Symbol("Request internals");
|
|
22820
|
-
var
|
|
22820
|
+
var URL3 = Url.URL || import_whatwg_url.default.URL;
|
|
22821
22821
|
var parse_url = Url.parse;
|
|
22822
22822
|
var format_url = Url.format;
|
|
22823
22823
|
function parseURL(urlStr) {
|
|
22824
22824
|
if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) {
|
|
22825
|
-
urlStr = new
|
|
22825
|
+
urlStr = new URL3(urlStr).toString();
|
|
22826
22826
|
}
|
|
22827
22827
|
return parse_url(urlStr);
|
|
22828
22828
|
}
|
|
@@ -22991,7 +22991,7 @@ function fetch2(url3, opts) {
|
|
|
22991
22991
|
throw new Error("native promise missing, set fetch.Promise to your favorite alternative");
|
|
22992
22992
|
}
|
|
22993
22993
|
Body.Promise = fetch2.Promise;
|
|
22994
|
-
return new fetch2.Promise(function(
|
|
22994
|
+
return new fetch2.Promise(function(resolve2, reject) {
|
|
22995
22995
|
const request = new Request(url3, opts);
|
|
22996
22996
|
const options = getNodeRequestOptions(request);
|
|
22997
22997
|
const send = (options.protocol === "https:" ? https : http).request;
|
|
@@ -23124,7 +23124,7 @@ function fetch2(url3, opts) {
|
|
|
23124
23124
|
requestOpts.body = void 0;
|
|
23125
23125
|
requestOpts.headers.delete("content-length");
|
|
23126
23126
|
}
|
|
23127
|
-
|
|
23127
|
+
resolve2(fetch2(new Request(locationURL, requestOpts)));
|
|
23128
23128
|
finalize();
|
|
23129
23129
|
return;
|
|
23130
23130
|
}
|
|
@@ -23145,7 +23145,7 @@ function fetch2(url3, opts) {
|
|
|
23145
23145
|
const codings = headers.get("Content-Encoding");
|
|
23146
23146
|
if (!request.compress || request.method === "HEAD" || codings === null || res.statusCode === 204 || res.statusCode === 304) {
|
|
23147
23147
|
response = new Response(body, response_options);
|
|
23148
|
-
|
|
23148
|
+
resolve2(response);
|
|
23149
23149
|
return;
|
|
23150
23150
|
}
|
|
23151
23151
|
const zlibOptions = {
|
|
@@ -23155,7 +23155,7 @@ function fetch2(url3, opts) {
|
|
|
23155
23155
|
if (codings == "gzip" || codings == "x-gzip") {
|
|
23156
23156
|
body = body.pipe(zlib.createGunzip(zlibOptions));
|
|
23157
23157
|
response = new Response(body, response_options);
|
|
23158
|
-
|
|
23158
|
+
resolve2(response);
|
|
23159
23159
|
return;
|
|
23160
23160
|
}
|
|
23161
23161
|
if (codings == "deflate" || codings == "x-deflate") {
|
|
@@ -23167,12 +23167,12 @@ function fetch2(url3, opts) {
|
|
|
23167
23167
|
body = body.pipe(zlib.createInflateRaw());
|
|
23168
23168
|
}
|
|
23169
23169
|
response = new Response(body, response_options);
|
|
23170
|
-
|
|
23170
|
+
resolve2(response);
|
|
23171
23171
|
});
|
|
23172
23172
|
raw.on("end", function() {
|
|
23173
23173
|
if (!response) {
|
|
23174
23174
|
response = new Response(body, response_options);
|
|
23175
|
-
|
|
23175
|
+
resolve2(response);
|
|
23176
23176
|
}
|
|
23177
23177
|
});
|
|
23178
23178
|
return;
|
|
@@ -23180,11 +23180,11 @@ function fetch2(url3, opts) {
|
|
|
23180
23180
|
if (codings == "br" && typeof zlib.createBrotliDecompress === "function") {
|
|
23181
23181
|
body = body.pipe(zlib.createBrotliDecompress());
|
|
23182
23182
|
response = new Response(body, response_options);
|
|
23183
|
-
|
|
23183
|
+
resolve2(response);
|
|
23184
23184
|
return;
|
|
23185
23185
|
}
|
|
23186
23186
|
response = new Response(body, response_options);
|
|
23187
|
-
|
|
23187
|
+
resolve2(response);
|
|
23188
23188
|
});
|
|
23189
23189
|
writeToStream(req, request);
|
|
23190
23190
|
});
|
|
@@ -25913,12 +25913,12 @@ Message: ${transactionMessage}.
|
|
|
25913
25913
|
}
|
|
25914
25914
|
async getLogs(connection) {
|
|
25915
25915
|
if (!Array.isArray(this.transactionLogs)) {
|
|
25916
|
-
this.transactionLogs = new Promise((
|
|
25916
|
+
this.transactionLogs = new Promise((resolve2, reject) => {
|
|
25917
25917
|
connection.getTransaction(this.signature).then((tx) => {
|
|
25918
25918
|
if (tx && tx.meta && tx.meta.logMessages) {
|
|
25919
25919
|
const logs = tx.meta.logMessages;
|
|
25920
25920
|
this.transactionLogs = logs;
|
|
25921
|
-
|
|
25921
|
+
resolve2(logs);
|
|
25922
25922
|
} else {
|
|
25923
25923
|
reject(new Error("Log messages not found"));
|
|
25924
25924
|
}
|
|
@@ -25975,7 +25975,7 @@ async function sendAndConfirmTransaction(connection, transaction, signers, optio
|
|
|
25975
25975
|
return signature;
|
|
25976
25976
|
}
|
|
25977
25977
|
function sleep(ms) {
|
|
25978
|
-
return new Promise((
|
|
25978
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
25979
25979
|
}
|
|
25980
25980
|
function encodeData(type2, fields) {
|
|
25981
25981
|
const allocLength = type2.layout.span >= 0 ? type2.layout.span : getAlloc(type2, fields);
|
|
@@ -26554,7 +26554,7 @@ var Loader = class _Loader {
|
|
|
26554
26554
|
}
|
|
26555
26555
|
} catch {
|
|
26556
26556
|
}
|
|
26557
|
-
await new Promise((
|
|
26557
|
+
await new Promise((resolve2) => setTimeout(resolve2, Math.round(MS_PER_SLOT / 2)));
|
|
26558
26558
|
}
|
|
26559
26559
|
}
|
|
26560
26560
|
return true;
|
|
@@ -29824,12 +29824,12 @@ function parse3(str) {
|
|
|
29824
29824
|
uri.queryKey = queryKey(uri, uri["query"]);
|
|
29825
29825
|
return uri;
|
|
29826
29826
|
}
|
|
29827
|
-
function pathNames(obj,
|
|
29828
|
-
const regx = /\/{2,9}/g, names =
|
|
29829
|
-
if (
|
|
29827
|
+
function pathNames(obj, path3) {
|
|
29828
|
+
const regx = /\/{2,9}/g, names = path3.replace(regx, "/").split("/");
|
|
29829
|
+
if (path3.slice(0, 1) == "/" || path3.length === 0) {
|
|
29830
29830
|
names.splice(0, 1);
|
|
29831
29831
|
}
|
|
29832
|
-
if (
|
|
29832
|
+
if (path3.slice(-1) == "/") {
|
|
29833
29833
|
names.splice(names.length - 1, 1);
|
|
29834
29834
|
}
|
|
29835
29835
|
return names;
|
|
@@ -30446,7 +30446,7 @@ var protocol2 = Socket.protocol;
|
|
|
30446
30446
|
// ../../node_modules/socket.io-client/build/esm-debug/url.js
|
|
30447
30447
|
var import_debug7 = __toESM(require_src2(), 1);
|
|
30448
30448
|
var debug7 = (0, import_debug7.default)("socket.io-client:url");
|
|
30449
|
-
function url2(uri,
|
|
30449
|
+
function url2(uri, path3 = "", loc) {
|
|
30450
30450
|
let obj = uri;
|
|
30451
30451
|
loc = loc || typeof location !== "undefined" && location;
|
|
30452
30452
|
if (null == uri)
|
|
@@ -30480,7 +30480,7 @@ function url2(uri, path2 = "", loc) {
|
|
|
30480
30480
|
obj.path = obj.path || "/";
|
|
30481
30481
|
const ipv6 = obj.host.indexOf(":") !== -1;
|
|
30482
30482
|
const host = ipv6 ? "[" + obj.host + "]" : obj.host;
|
|
30483
|
-
obj.id = obj.protocol + "://" + host + ":" + obj.port +
|
|
30483
|
+
obj.id = obj.protocol + "://" + host + ":" + obj.port + path3;
|
|
30484
30484
|
obj.href = obj.protocol + "://" + host + (loc && loc.port === obj.port ? "" : ":" + obj.port);
|
|
30485
30485
|
return obj;
|
|
30486
30486
|
}
|
|
@@ -31130,9 +31130,9 @@ var Socket2 = class extends Emitter {
|
|
|
31130
31130
|
* @return a Promise that will be fulfilled when the server acknowledges the event
|
|
31131
31131
|
*/
|
|
31132
31132
|
emitWithAck(ev, ...args) {
|
|
31133
|
-
return new Promise((
|
|
31133
|
+
return new Promise((resolve2, reject) => {
|
|
31134
31134
|
const fn = (arg1, arg2) => {
|
|
31135
|
-
return arg1 ? reject(arg1) :
|
|
31135
|
+
return arg1 ? reject(arg1) : resolve2(arg2);
|
|
31136
31136
|
};
|
|
31137
31137
|
fn.withError = true;
|
|
31138
31138
|
args.push(fn);
|
|
@@ -32104,8 +32104,8 @@ function lookup(uri, opts) {
|
|
|
32104
32104
|
const parsed = url2(uri, opts.path || "/socket.io");
|
|
32105
32105
|
const source = parsed.source;
|
|
32106
32106
|
const id = parsed.id;
|
|
32107
|
-
const
|
|
32108
|
-
const sameNamespace = cache[id] &&
|
|
32107
|
+
const path3 = parsed.path;
|
|
32108
|
+
const sameNamespace = cache[id] && path3 in cache[id]["nsps"];
|
|
32109
32109
|
const newConnection = opts.forceNew || opts["force new connection"] || false === opts.multiplex || sameNamespace;
|
|
32110
32110
|
let io;
|
|
32111
32111
|
if (newConnection) {
|
|
@@ -33003,6 +33003,16 @@ var Admin = class {
|
|
|
33003
33003
|
);
|
|
33004
33004
|
}
|
|
33005
33005
|
};
|
|
33006
|
+
function isFile(input) {
|
|
33007
|
+
return typeof input.arrayBuffer === "function";
|
|
33008
|
+
}
|
|
33009
|
+
function buildFormDataFromPayload(payload) {
|
|
33010
|
+
const formData = new FormData();
|
|
33011
|
+
const part = payload.data instanceof Uint8Array ? payload.data : new Uint8Array(payload.data);
|
|
33012
|
+
const blob3 = new Blob([part], { type: payload.mimeType });
|
|
33013
|
+
formData.append("file", blob3, payload.filename);
|
|
33014
|
+
return formData;
|
|
33015
|
+
}
|
|
33006
33016
|
var Users = class {
|
|
33007
33017
|
constructor(http2, logger2) {
|
|
33008
33018
|
this.http = http2;
|
|
@@ -33089,14 +33099,22 @@ var Users = class {
|
|
|
33089
33099
|
async updateProfile(data) {
|
|
33090
33100
|
return this.http.patch("/users/me/profile", data);
|
|
33091
33101
|
}
|
|
33092
|
-
async uploadAvatar(
|
|
33093
|
-
const
|
|
33094
|
-
|
|
33102
|
+
async uploadAvatar(input) {
|
|
33103
|
+
const payload = isFile(input) ? {
|
|
33104
|
+
data: new Uint8Array(await input.arrayBuffer()),
|
|
33105
|
+
mimeType: input.type,
|
|
33106
|
+
filename: input.name
|
|
33107
|
+
} : input;
|
|
33108
|
+
const formData = buildFormDataFromPayload(payload);
|
|
33095
33109
|
return this.http.upload("/users/me/profile/avatar", formData);
|
|
33096
33110
|
}
|
|
33097
|
-
async uploadCoverImage(
|
|
33098
|
-
const
|
|
33099
|
-
|
|
33111
|
+
async uploadCoverImage(input) {
|
|
33112
|
+
const payload = isFile(input) ? {
|
|
33113
|
+
data: new Uint8Array(await input.arrayBuffer()),
|
|
33114
|
+
mimeType: input.type,
|
|
33115
|
+
filename: input.name
|
|
33116
|
+
} : input;
|
|
33117
|
+
const formData = buildFormDataFromPayload(payload);
|
|
33100
33118
|
return this.http.upload("/users/me/profile/cover", formData);
|
|
33101
33119
|
}
|
|
33102
33120
|
async removeAvatar() {
|
|
@@ -33236,19 +33254,18 @@ var Lobbies = class {
|
|
|
33236
33254
|
return this.http.delete(`/lobbies/admin/${lobbyId}`);
|
|
33237
33255
|
}
|
|
33238
33256
|
/**
|
|
33239
|
-
* Play again: Create a new lobby
|
|
33240
|
-
* Returns the lobby and unsigned transaction that needs to be signed
|
|
33257
|
+
* Play again: Create a new lobby and prepare deposit in one flow.
|
|
33258
|
+
* Returns the lobby and unsigned transaction that needs to be signed.
|
|
33241
33259
|
* @param gameType - The game type to play again
|
|
33242
33260
|
* @param betAmount - The bet amount (same as previous game)
|
|
33243
33261
|
* @param escrow - The escrow service instance (from sdk.escrow)
|
|
33244
33262
|
*/
|
|
33245
33263
|
async playAgain(gameType, betAmount, escrow) {
|
|
33246
33264
|
const lobby = await this.createLobby(gameType, betAmount);
|
|
33247
|
-
await escrow.
|
|
33248
|
-
const prepareResponse = await escrow.prepareDepositTransaction(lobby.id);
|
|
33265
|
+
const { transaction } = await escrow.prepareAndStartDeposit(lobby.id);
|
|
33249
33266
|
return {
|
|
33250
33267
|
lobby,
|
|
33251
|
-
unsignedTransaction:
|
|
33268
|
+
unsignedTransaction: transaction
|
|
33252
33269
|
};
|
|
33253
33270
|
}
|
|
33254
33271
|
};
|
|
@@ -33431,7 +33448,7 @@ async function withRetry(fn, options = {}) {
|
|
|
33431
33448
|
throw lastError;
|
|
33432
33449
|
}
|
|
33433
33450
|
function sleep2(ms) {
|
|
33434
|
-
return new Promise((
|
|
33451
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
33435
33452
|
}
|
|
33436
33453
|
var DEFAULT_RETRY_OPTIONS = {
|
|
33437
33454
|
maxAttempts: 3,
|
|
@@ -34112,6 +34129,17 @@ var Escrow = class {
|
|
|
34112
34129
|
`/escrow/lobby/${lobbyId}/deposit/prepare`
|
|
34113
34130
|
);
|
|
34114
34131
|
}
|
|
34132
|
+
/**
|
|
34133
|
+
* Combined prepare-and-start: validates lobby, transitions waiting→preparing,
|
|
34134
|
+
* initializes depositStatus, and prepares the unsigned transaction in one call.
|
|
34135
|
+
* Eliminates one HTTP round-trip vs startDeposits() + prepareDepositTransaction().
|
|
34136
|
+
*/
|
|
34137
|
+
async prepareAndStartDeposit(lobbyId) {
|
|
34138
|
+
return this.http.post(
|
|
34139
|
+
`/escrow/lobby/${lobbyId}/deposit/prepare-and-start`,
|
|
34140
|
+
{}
|
|
34141
|
+
);
|
|
34142
|
+
}
|
|
34115
34143
|
/**
|
|
34116
34144
|
* Submit a signed deposit transaction
|
|
34117
34145
|
* The transaction will be submitted to the Solana network and confirmed
|
|
@@ -34142,7 +34170,7 @@ var Escrow = class {
|
|
|
34142
34170
|
);
|
|
34143
34171
|
}
|
|
34144
34172
|
/**
|
|
34145
|
-
* One-call lobby deposit: start
|
|
34173
|
+
* One-call lobby deposit: prepare-and-start, sign, submit, and poll until
|
|
34146
34174
|
* the current user's deposit is confirmed. Requires sdk.wallet.setSigner() to be set.
|
|
34147
34175
|
* Returns when all required deposits are confirmed and the lobby can proceed to queue.
|
|
34148
34176
|
*
|
|
@@ -34154,8 +34182,7 @@ var Escrow = class {
|
|
|
34154
34182
|
"No signer configured. Use sdk.wallet.setSigner(...) first."
|
|
34155
34183
|
);
|
|
34156
34184
|
}
|
|
34157
|
-
await this.
|
|
34158
|
-
const { transaction } = await this.prepareDepositTransaction(lobbyId);
|
|
34185
|
+
const { transaction } = await this.prepareAndStartDeposit(lobbyId);
|
|
34159
34186
|
const unsignedTx = Transaction.from(base64ToBytes(transaction));
|
|
34160
34187
|
let signature;
|
|
34161
34188
|
if (this.wallet.isSignAndSendMode()) {
|
|
@@ -34177,7 +34204,7 @@ var Escrow = class {
|
|
|
34177
34204
|
if (status.allConfirmed && status.canProceedToQueue) {
|
|
34178
34205
|
return {
|
|
34179
34206
|
signature,
|
|
34180
|
-
status: "
|
|
34207
|
+
status: "confirmed",
|
|
34181
34208
|
canProceedToQueue: true
|
|
34182
34209
|
};
|
|
34183
34210
|
}
|
|
@@ -34189,6 +34216,39 @@ var Escrow = class {
|
|
|
34189
34216
|
canProceedToQueue: false
|
|
34190
34217
|
};
|
|
34191
34218
|
}
|
|
34219
|
+
/**
|
|
34220
|
+
* Zero-polling deposit variant using server-side awaitConfirmation.
|
|
34221
|
+
* 2 HTTP calls total, 0 client-side polling. Ideal for agents.
|
|
34222
|
+
*
|
|
34223
|
+
* Automatically uses signAndSendTransaction or signTransaction based on signer capability.
|
|
34224
|
+
*/
|
|
34225
|
+
async depositForLobbySync(lobbyId) {
|
|
34226
|
+
if (!this.wallet.hasSigner()) {
|
|
34227
|
+
throw new Error(
|
|
34228
|
+
"No signer configured. Use sdk.wallet.setSigner(...) first."
|
|
34229
|
+
);
|
|
34230
|
+
}
|
|
34231
|
+
const { transaction } = await this.prepareAndStartDeposit(lobbyId);
|
|
34232
|
+
const unsignedTx = Transaction.from(base64ToBytes(transaction));
|
|
34233
|
+
let signature;
|
|
34234
|
+
if (this.wallet.isSignAndSendMode()) {
|
|
34235
|
+
signature = await this.wallet.signAndSendTransaction(unsignedTx);
|
|
34236
|
+
await this.http.post(
|
|
34237
|
+
`/escrow/lobby/${lobbyId}/deposit/confirm-signature?awaitConfirmation=true`,
|
|
34238
|
+
{ signature }
|
|
34239
|
+
);
|
|
34240
|
+
} else {
|
|
34241
|
+
const signedTx = await this.wallet.signTransaction(unsignedTx);
|
|
34242
|
+
const signedBase64 = bytesToBase64(
|
|
34243
|
+
signedTx.serialize({ requireAllSignatures: false })
|
|
34244
|
+
);
|
|
34245
|
+
const result = await this.http.post(`/escrow/lobby/${lobbyId}/deposit/submit?awaitConfirmation=true`, {
|
|
34246
|
+
signedTransaction: signedBase64
|
|
34247
|
+
});
|
|
34248
|
+
signature = result.signature;
|
|
34249
|
+
}
|
|
34250
|
+
return { signature, status: "confirmed", canProceedToQueue: true };
|
|
34251
|
+
}
|
|
34192
34252
|
async claimLobbyDepositRefund(lobbyId, depositSignature) {
|
|
34193
34253
|
return this.http.post(
|
|
34194
34254
|
`/escrow/lobby/${lobbyId}/deposit/${depositSignature}/claim-refund`,
|
|
@@ -34201,33 +34261,6 @@ var Escrow = class {
|
|
|
34201
34261
|
{}
|
|
34202
34262
|
);
|
|
34203
34263
|
}
|
|
34204
|
-
/**
|
|
34205
|
-
* Submit a signed deposit transaction and wait until the lobby is queued/active.
|
|
34206
|
-
*
|
|
34207
|
-
* Note: the backend may auto-transition the lobby to the queue once deposits are confirmed.
|
|
34208
|
-
* In that case, calling /join-queue from the client would be redundant and can fail with
|
|
34209
|
-
* "Current status: queued".
|
|
34210
|
-
* @param lobbyId - The lobby ID
|
|
34211
|
-
* @param signedTransaction - The signed transaction (base64 encoded)
|
|
34212
|
-
* @param lobbies - The lobbies service instance (from sdk.lobbies) to read lobby status
|
|
34213
|
-
*/
|
|
34214
|
-
async submitDepositAndJoinQueue(lobbyId, signedTransaction, lobbies) {
|
|
34215
|
-
await this.submitDeposit(lobbyId, signedTransaction);
|
|
34216
|
-
const MAX_WAIT_TIME = 3e4;
|
|
34217
|
-
const POLL_INTERVAL = 1e3;
|
|
34218
|
-
const startTime = Date.now();
|
|
34219
|
-
while (Date.now() - startTime < MAX_WAIT_TIME) {
|
|
34220
|
-
const status = await this.getDepositStatus(lobbyId);
|
|
34221
|
-
if (status.allConfirmed && status.canProceedToQueue) {
|
|
34222
|
-
const lobby = await lobbies.getLobby(lobbyId);
|
|
34223
|
-
if (lobby.status === "queued" || lobby.status === "active") {
|
|
34224
|
-
return lobby;
|
|
34225
|
-
}
|
|
34226
|
-
}
|
|
34227
|
-
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL));
|
|
34228
|
-
}
|
|
34229
|
-
throw new Error("Deposit confirmation timeout");
|
|
34230
|
-
}
|
|
34231
34264
|
};
|
|
34232
34265
|
var Daily = class {
|
|
34233
34266
|
constructor(http2, logger2 = logger) {
|
|
@@ -34683,12 +34716,12 @@ var BaseWsTransport = class {
|
|
|
34683
34716
|
if (this.connectionState.connected) {
|
|
34684
34717
|
return Promise.resolve();
|
|
34685
34718
|
}
|
|
34686
|
-
return new Promise((
|
|
34719
|
+
return new Promise((resolve2, reject) => {
|
|
34687
34720
|
const timeoutId = setTimeout(() => {
|
|
34688
34721
|
this.waiters.delete(waiter);
|
|
34689
34722
|
reject(new Error("WebSocket connection timed out"));
|
|
34690
34723
|
}, timeoutMs);
|
|
34691
|
-
const waiter = { resolve, reject, timeoutId };
|
|
34724
|
+
const waiter = { resolve: resolve2, reject, timeoutId };
|
|
34692
34725
|
this.waiters.add(waiter);
|
|
34693
34726
|
});
|
|
34694
34727
|
}
|
|
@@ -34854,8 +34887,14 @@ var _StandaloneWsTransport = class _StandaloneWsTransport2 extends BaseWsTranspo
|
|
|
34854
34887
|
connecting: false,
|
|
34855
34888
|
error: null
|
|
34856
34889
|
});
|
|
34890
|
+
const wasReconnect = this.reconnectAttempts > 0;
|
|
34857
34891
|
this.reconnectAttempts = 0;
|
|
34858
34892
|
this.onReconnect();
|
|
34893
|
+
if (wasReconnect) {
|
|
34894
|
+
this.dispatchEvent("connection:reconnected", {
|
|
34895
|
+
timestamp: Date.now()
|
|
34896
|
+
});
|
|
34897
|
+
}
|
|
34859
34898
|
});
|
|
34860
34899
|
socket.on("disconnect", (reason) => {
|
|
34861
34900
|
this.updateConnectionState({ connected: false, connecting: false });
|
|
@@ -34997,7 +35036,8 @@ function createLobbyStore(transport) {
|
|
|
34997
35036
|
const store = createSdkStore({
|
|
34998
35037
|
lobbiesById: {},
|
|
34999
35038
|
matchedEvent: null,
|
|
35000
|
-
typingByLobbyId: {}
|
|
35039
|
+
typingByLobbyId: {},
|
|
35040
|
+
depositStatusByLobbyId: {}
|
|
35001
35041
|
});
|
|
35002
35042
|
const setBaseState = (lobbies) => {
|
|
35003
35043
|
const lobbiesById = {};
|
|
@@ -35077,6 +35117,15 @@ function createLobbyStore(transport) {
|
|
|
35077
35117
|
};
|
|
35078
35118
|
});
|
|
35079
35119
|
break;
|
|
35120
|
+
case "lobby:deposit:updated":
|
|
35121
|
+
store.updateState((state) => ({
|
|
35122
|
+
...state,
|
|
35123
|
+
depositStatusByLobbyId: {
|
|
35124
|
+
...state.depositStatusByLobbyId,
|
|
35125
|
+
[event.payload.lobbyId]: event.payload
|
|
35126
|
+
}
|
|
35127
|
+
}));
|
|
35128
|
+
break;
|
|
35080
35129
|
case "lobby:typing:start":
|
|
35081
35130
|
case "lobby:typing:stop":
|
|
35082
35131
|
store.updateState((state) => {
|
|
@@ -35105,12 +35154,22 @@ function createLobbyStore(transport) {
|
|
|
35105
35154
|
}
|
|
35106
35155
|
}
|
|
35107
35156
|
);
|
|
35157
|
+
const subscribeDepositUpdate = (lobbyId, callback) => store.subscribeSelector(
|
|
35158
|
+
(state) => state.depositStatusByLobbyId[lobbyId],
|
|
35159
|
+
() => {
|
|
35160
|
+
const data = store.getState().depositStatusByLobbyId[lobbyId];
|
|
35161
|
+
if (data) {
|
|
35162
|
+
callback(data);
|
|
35163
|
+
}
|
|
35164
|
+
}
|
|
35165
|
+
);
|
|
35108
35166
|
return {
|
|
35109
35167
|
store,
|
|
35110
35168
|
setBaseState,
|
|
35111
35169
|
applyWsEvent,
|
|
35112
35170
|
joinLobby,
|
|
35113
|
-
subscribeMatched
|
|
35171
|
+
subscribeMatched,
|
|
35172
|
+
subscribeDepositUpdate
|
|
35114
35173
|
};
|
|
35115
35174
|
}
|
|
35116
35175
|
function createGameStore(transport) {
|
|
@@ -35392,7 +35451,6 @@ function createGameActionsStore(transport) {
|
|
|
35392
35451
|
...current,
|
|
35393
35452
|
roundState: {
|
|
35394
35453
|
...current.roundState,
|
|
35395
|
-
phase: "completed",
|
|
35396
35454
|
timeRemaining: 0,
|
|
35397
35455
|
actions: timedOutUser ? {
|
|
35398
35456
|
...current.roundState.actions,
|
|
@@ -35437,6 +35495,22 @@ function createGameActionsStore(transport) {
|
|
|
35437
35495
|
updateState(gameId, updated);
|
|
35438
35496
|
break;
|
|
35439
35497
|
}
|
|
35498
|
+
case "game:move": {
|
|
35499
|
+
const { gameId, fen, turn, currentPlayerId, status, winnerId } = event.payload;
|
|
35500
|
+
if (!gameId) return;
|
|
35501
|
+
const current = store.getState().statesByGameId[gameId];
|
|
35502
|
+
if (!isNonRpsState(current)) return;
|
|
35503
|
+
const updated = {
|
|
35504
|
+
...current,
|
|
35505
|
+
fen,
|
|
35506
|
+
turn,
|
|
35507
|
+
currentPlayerId,
|
|
35508
|
+
status,
|
|
35509
|
+
...winnerId != null && { winnerId }
|
|
35510
|
+
};
|
|
35511
|
+
updateState(gameId, updated);
|
|
35512
|
+
break;
|
|
35513
|
+
}
|
|
35440
35514
|
case "game:state": {
|
|
35441
35515
|
const gameId = event.payload.gameId ?? event.payload.state.gameId;
|
|
35442
35516
|
if (!gameId) return;
|
|
@@ -35904,6 +35978,7 @@ var WS_EVENT_NAMES = [
|
|
|
35904
35978
|
"lobby:queue:joined",
|
|
35905
35979
|
"lobby:queue:cancelled",
|
|
35906
35980
|
"lobby:matched",
|
|
35981
|
+
"lobby:deposit:updated",
|
|
35907
35982
|
"lobby:typing:start",
|
|
35908
35983
|
"lobby:typing:stop",
|
|
35909
35984
|
"game:updated",
|
|
@@ -35980,6 +36055,11 @@ function decodeWsEvent(eventName, payload) {
|
|
|
35980
36055
|
event: "lobby:matched",
|
|
35981
36056
|
payload
|
|
35982
36057
|
};
|
|
36058
|
+
case "lobby:deposit:updated":
|
|
36059
|
+
return {
|
|
36060
|
+
event: "lobby:deposit:updated",
|
|
36061
|
+
payload
|
|
36062
|
+
};
|
|
35983
36063
|
case "lobby:typing:start":
|
|
35984
36064
|
case "lobby:typing:stop":
|
|
35985
36065
|
return {
|
|
@@ -36569,6 +36649,17 @@ var SAFETY_RULES = [
|
|
|
36569
36649
|
];
|
|
36570
36650
|
|
|
36571
36651
|
// ../dim-agent-core/src/tools/auth.ts
|
|
36652
|
+
var WALLET_LINKAGE_NOTE = "DIM is noncustodial. Your DIM wallet is the Solana address shown here; it was configured with a base58 private key at setup. Signing is done locally where this instance runs, using that private key and DIM's wallet package.";
|
|
36653
|
+
async function getSpectateUrl(client) {
|
|
36654
|
+
if (!client.currentUserId) return null;
|
|
36655
|
+
try {
|
|
36656
|
+
const user = await client.sdk.users.getUserById(client.currentUserId);
|
|
36657
|
+
const u = user;
|
|
36658
|
+
return u?.username ? `https://dim.cool/spectate/${u.username}` : null;
|
|
36659
|
+
} catch {
|
|
36660
|
+
return null;
|
|
36661
|
+
}
|
|
36662
|
+
}
|
|
36572
36663
|
async function login(client) {
|
|
36573
36664
|
try {
|
|
36574
36665
|
const result = await client.authenticate();
|
|
@@ -36598,6 +36689,7 @@ async function login(client) {
|
|
|
36598
36689
|
userId: result.userId,
|
|
36599
36690
|
username: result.username ?? null,
|
|
36600
36691
|
walletAddress: client.walletAddress,
|
|
36692
|
+
walletNote: WALLET_LINKAGE_NOTE,
|
|
36601
36693
|
safetyRules: SAFETY_RULES,
|
|
36602
36694
|
nextSteps
|
|
36603
36695
|
};
|
|
@@ -36631,7 +36723,11 @@ async function getProfile(client) {
|
|
|
36631
36723
|
};
|
|
36632
36724
|
}
|
|
36633
36725
|
const user = await client.sdk.users.getUserById(client.currentUserId);
|
|
36634
|
-
|
|
36726
|
+
const profile = {
|
|
36727
|
+
...typeof user === "object" && user !== null ? user : {},
|
|
36728
|
+
walletAddress: client.walletAddress
|
|
36729
|
+
};
|
|
36730
|
+
return { data: profile };
|
|
36635
36731
|
} catch (error) {
|
|
36636
36732
|
return {
|
|
36637
36733
|
error: `Failed to get profile: ${error instanceof Error ? error.message : String(error)}`,
|
|
@@ -36832,12 +36928,31 @@ async function listDmThreads(client) {
|
|
|
36832
36928
|
}
|
|
36833
36929
|
|
|
36834
36930
|
// ../dim-agent-core/src/tools/wallet.ts
|
|
36931
|
+
async function getWalletAddress(client) {
|
|
36932
|
+
try {
|
|
36933
|
+
return {
|
|
36934
|
+
data: {
|
|
36935
|
+
walletAddress: client.walletAddress,
|
|
36936
|
+
walletNote: WALLET_LINKAGE_NOTE
|
|
36937
|
+
}
|
|
36938
|
+
};
|
|
36939
|
+
} catch (error) {
|
|
36940
|
+
return {
|
|
36941
|
+
error: `Failed to get wallet address: ${error instanceof Error ? error.message : String(error)}`,
|
|
36942
|
+
isError: true
|
|
36943
|
+
};
|
|
36944
|
+
}
|
|
36945
|
+
}
|
|
36835
36946
|
async function getBalance(client) {
|
|
36836
36947
|
try {
|
|
36837
36948
|
const balance = await client.sdk.wallet.getBalances();
|
|
36838
36949
|
const usdcDollars = balance.usdc / 1e6;
|
|
36839
36950
|
return {
|
|
36840
|
-
data: {
|
|
36951
|
+
data: {
|
|
36952
|
+
...balance,
|
|
36953
|
+
usdcFormatted: `$${usdcDollars.toFixed(2)}`,
|
|
36954
|
+
walletAddress: client.walletAddress
|
|
36955
|
+
}
|
|
36841
36956
|
};
|
|
36842
36957
|
} catch (error) {
|
|
36843
36958
|
return {
|
|
@@ -36904,7 +37019,10 @@ async function getWalletActivity(client, args) {
|
|
|
36904
37019
|
limit: args.limit || 20
|
|
36905
37020
|
});
|
|
36906
37021
|
const claimable = activity.items.filter((i) => i.claimable === true);
|
|
36907
|
-
const data = {
|
|
37022
|
+
const data = {
|
|
37023
|
+
...activity,
|
|
37024
|
+
walletAddress: client.walletAddress
|
|
37025
|
+
};
|
|
36908
37026
|
if (claimable.length > 0) {
|
|
36909
37027
|
data.hint = `You have ${claimable.length} claimable item(s). Call dim_claim_funds with the activityId to claim each one.`;
|
|
36910
37028
|
data.claimableItems = claimable.map((i) => ({
|
|
@@ -37113,9 +37231,8 @@ function buildGameOverHint(state) {
|
|
|
37113
37231
|
const winnerId = state.winnerId;
|
|
37114
37232
|
const wonAmount = state.wonAmount;
|
|
37115
37233
|
const isDraw = state.draw === true || winnerId == null;
|
|
37116
|
-
|
|
37117
|
-
|
|
37118
|
-
return `Game over. Winner: ${winnerId}.${amountStr}`;
|
|
37234
|
+
const result = isDraw ? "Game over \u2014 it was a draw." : `Game over. Winner: ${winnerId}.${wonAmount != null ? ` Won $${(wonAmount / 1e6).toFixed(2)}.` : ""}`;
|
|
37235
|
+
return `${result} You can request a rematch with dim_request_rematch, or check dim_check_notifications for new activity.`;
|
|
37119
37236
|
}
|
|
37120
37237
|
async function fetchNewGameChat(client, gameId) {
|
|
37121
37238
|
try {
|
|
@@ -37223,13 +37340,13 @@ async function createLobby(client, args) {
|
|
|
37223
37340
|
}
|
|
37224
37341
|
async function depositForLobby(client, args) {
|
|
37225
37342
|
try {
|
|
37226
|
-
const result = await client.sdk.escrow.
|
|
37343
|
+
const result = await client.sdk.escrow.depositForLobbySync(args.lobbyId);
|
|
37227
37344
|
return {
|
|
37228
37345
|
data: {
|
|
37229
37346
|
signature: result.signature,
|
|
37230
37347
|
status: result.status,
|
|
37231
37348
|
canProceedToQueue: result.canProceedToQueue,
|
|
37232
|
-
hint:
|
|
37349
|
+
hint: "Deposit confirmed. The server auto-joins the queue when all players have deposited."
|
|
37233
37350
|
}
|
|
37234
37351
|
};
|
|
37235
37352
|
} catch (error) {
|
|
@@ -37260,13 +37377,15 @@ async function joinQueue(client, args) {
|
|
|
37260
37377
|
await client.ensureConnected();
|
|
37261
37378
|
const lobby = await client.sdk.lobbies.joinQueue(args.lobbyId);
|
|
37262
37379
|
const matched = lobby.status === "active" && lobby.gameId;
|
|
37380
|
+
const spectateUrl = matched ? await getSpectateUrl(client) : null;
|
|
37263
37381
|
return {
|
|
37264
37382
|
data: {
|
|
37265
37383
|
lobbyId: lobby.id,
|
|
37266
37384
|
status: lobby.status,
|
|
37267
37385
|
gameId: lobby.gameId || null,
|
|
37268
37386
|
matched: !!matched,
|
|
37269
|
-
|
|
37387
|
+
...spectateUrl && { spectateUrl },
|
|
37388
|
+
hint: matched ? `Game started! Call dim_game_loop with gameId "${lobby.gameId}" to play.${spectateUrl ? ` Tell the user they can spectate at ${spectateUrl}` : ""}` : "Waiting for an opponent. Poll dim_get_lobby to check for a match."
|
|
37270
37389
|
}
|
|
37271
37390
|
};
|
|
37272
37391
|
} catch (error) {
|
|
@@ -37381,13 +37500,12 @@ async function gameLoop(client, args) {
|
|
|
37381
37500
|
const store = client.sdk.gameActionsStore;
|
|
37382
37501
|
const timeout = 3e5;
|
|
37383
37502
|
const start = Date.now();
|
|
37384
|
-
|
|
37385
|
-
|
|
37386
|
-
|
|
37387
|
-
|
|
37388
|
-
|
|
37389
|
-
|
|
37390
|
-
}
|
|
37503
|
+
await client.ensureConnected();
|
|
37504
|
+
store.joinGame(gameId);
|
|
37505
|
+
const fetched = await client.sdk.games.getGameState(gameId);
|
|
37506
|
+
store.setBaseState(gameId, fetched);
|
|
37507
|
+
let state = fetched;
|
|
37508
|
+
let lastRefresh = Date.now();
|
|
37391
37509
|
while (Date.now() - start < timeout) {
|
|
37392
37510
|
state = store.store.getState().statesByGameId[gameId];
|
|
37393
37511
|
if (state?.status === "completed") {
|
|
@@ -37397,17 +37515,22 @@ async function gameLoop(client, args) {
|
|
|
37397
37515
|
return buildGameLoopReturn(client, gameId, state, "your-turn");
|
|
37398
37516
|
}
|
|
37399
37517
|
await raceTimeout(
|
|
37400
|
-
new Promise((
|
|
37518
|
+
new Promise((resolve2) => {
|
|
37401
37519
|
const unsub = store.store.subscribeSelector(
|
|
37402
37520
|
(s) => s.statesByGameId[gameId],
|
|
37403
37521
|
() => {
|
|
37404
37522
|
unsub();
|
|
37405
|
-
|
|
37523
|
+
resolve2();
|
|
37406
37524
|
}
|
|
37407
37525
|
);
|
|
37408
37526
|
}),
|
|
37409
37527
|
1e3
|
|
37410
37528
|
);
|
|
37529
|
+
if (Date.now() - lastRefresh > 5e3) {
|
|
37530
|
+
const fresh = await client.sdk.games.getGameState(gameId);
|
|
37531
|
+
store.setBaseState(gameId, fresh);
|
|
37532
|
+
lastRefresh = Date.now();
|
|
37533
|
+
}
|
|
37411
37534
|
}
|
|
37412
37535
|
state = store.store.getState().statesByGameId[gameId];
|
|
37413
37536
|
return buildGameLoopReturn(client, gameId, state ?? {}, "timeout");
|
|
@@ -37448,12 +37571,44 @@ async function inviteToLobby(client, args) {
|
|
|
37448
37571
|
};
|
|
37449
37572
|
}
|
|
37450
37573
|
}
|
|
37574
|
+
async function requestRematch(client, args) {
|
|
37575
|
+
try {
|
|
37576
|
+
const result = await client.sdk.games.requestRematch(args.gameId);
|
|
37577
|
+
return {
|
|
37578
|
+
data: {
|
|
37579
|
+
...result,
|
|
37580
|
+
hint: result.bothReady ? `Both players want a rematch! A lobby is being created.${result.newLobbyId ? ` Lobby ID: ${result.newLobbyId}.` : ""} Check dim_check_notifications or call dim_game_loop with the new gameId once the game starts.` : "Rematch requested. Waiting for opponent to accept. Call dim_check_notifications to see if they respond."
|
|
37581
|
+
}
|
|
37582
|
+
};
|
|
37583
|
+
} catch (error) {
|
|
37584
|
+
return {
|
|
37585
|
+
error: `Failed to request rematch: ${error instanceof Error ? error.message : String(error)}`,
|
|
37586
|
+
isError: true
|
|
37587
|
+
};
|
|
37588
|
+
}
|
|
37589
|
+
}
|
|
37590
|
+
async function acceptRematch(client, args) {
|
|
37591
|
+
try {
|
|
37592
|
+
const result = await client.sdk.games.requestRematch(args.gameId);
|
|
37593
|
+
return {
|
|
37594
|
+
data: {
|
|
37595
|
+
...result,
|
|
37596
|
+
hint: result.bothReady ? `Rematch accepted! A lobby has been created.${result.newLobbyId ? ` Lobby ID: ${result.newLobbyId}.` : ""} Proceed with deposit and game flow.` : "Your rematch acceptance was recorded. Waiting for the other player."
|
|
37597
|
+
}
|
|
37598
|
+
};
|
|
37599
|
+
} catch (error) {
|
|
37600
|
+
return {
|
|
37601
|
+
error: `Failed to accept rematch: ${error instanceof Error ? error.message : String(error)}`,
|
|
37602
|
+
isError: true
|
|
37603
|
+
};
|
|
37604
|
+
}
|
|
37605
|
+
}
|
|
37451
37606
|
function raceTimeout(promise, ms) {
|
|
37452
|
-
return new Promise((
|
|
37453
|
-
const timer = setTimeout(
|
|
37607
|
+
return new Promise((resolve2) => {
|
|
37608
|
+
const timer = setTimeout(resolve2, ms);
|
|
37454
37609
|
promise.then(() => {
|
|
37455
37610
|
clearTimeout(timer);
|
|
37456
|
-
|
|
37611
|
+
resolve2();
|
|
37457
37612
|
});
|
|
37458
37613
|
});
|
|
37459
37614
|
}
|
|
@@ -37494,10 +37649,12 @@ async function challengeUser(client, args) {
|
|
|
37494
37649
|
async function acceptChallenge(client, args) {
|
|
37495
37650
|
try {
|
|
37496
37651
|
const result = await client.sdk.challenges.accept(args.challengeId);
|
|
37652
|
+
const spectateUrl = result.gameId ? await getSpectateUrl(client) : null;
|
|
37497
37653
|
return {
|
|
37498
37654
|
data: {
|
|
37499
37655
|
...result,
|
|
37500
|
-
|
|
37656
|
+
...spectateUrl && { spectateUrl },
|
|
37657
|
+
hint: result.gameId ? `Game started! Call dim_game_loop with gameId "${result.gameId}".${spectateUrl ? ` Tell the user they can spectate at ${spectateUrl}` : ""}` : `Lobby created: ${result.lobbyId}. Use dim_join_queue to start matchmaking.`
|
|
37501
37658
|
}
|
|
37502
37659
|
};
|
|
37503
37660
|
} catch (error) {
|
|
@@ -38033,6 +38190,384 @@ async function getAgentConfig(client) {
|
|
|
38033
38190
|
}
|
|
38034
38191
|
}
|
|
38035
38192
|
|
|
38193
|
+
// ../dim-agent-core/src/tools/profile.ts
|
|
38194
|
+
import * as fs from "fs/promises";
|
|
38195
|
+
import * as path from "path";
|
|
38196
|
+
import * as dns from "dns";
|
|
38197
|
+
import { promisify } from "util";
|
|
38198
|
+
var dnsLookup = promisify(dns.lookup);
|
|
38199
|
+
var MAX_FILE_SIZE_BYTES = 5 * 1024 * 1024;
|
|
38200
|
+
var FETCH_TIMEOUT_MS = 15e3;
|
|
38201
|
+
var ALLOWED_MIME_TYPES = [
|
|
38202
|
+
"image/jpeg",
|
|
38203
|
+
"image/jpg",
|
|
38204
|
+
"image/png",
|
|
38205
|
+
"image/webp",
|
|
38206
|
+
"image/gif"
|
|
38207
|
+
];
|
|
38208
|
+
var EXT_TO_MIME = {
|
|
38209
|
+
".png": "image/png",
|
|
38210
|
+
".jpg": "image/jpeg",
|
|
38211
|
+
".jpeg": "image/jpeg",
|
|
38212
|
+
".gif": "image/gif",
|
|
38213
|
+
".webp": "image/webp"
|
|
38214
|
+
};
|
|
38215
|
+
function getDefaultAllowedBaseDir() {
|
|
38216
|
+
const env = process.env.DIM_AGENT_WORKSPACE_DIR;
|
|
38217
|
+
if (env) return path.resolve(env);
|
|
38218
|
+
const home = process.env.HOME || process.env.USERPROFILE || ".";
|
|
38219
|
+
return path.join(home, ".openclaw", "workspace");
|
|
38220
|
+
}
|
|
38221
|
+
function isPathUnderBase(filePath, baseDir) {
|
|
38222
|
+
const resolved = path.resolve(filePath);
|
|
38223
|
+
const base3 = path.resolve(baseDir);
|
|
38224
|
+
const relative2 = path.relative(base3, resolved);
|
|
38225
|
+
return relative2 !== "" && !relative2.startsWith("..") && !path.isAbsolute(relative2);
|
|
38226
|
+
}
|
|
38227
|
+
function mimeFromExtension(filePathOrUrl) {
|
|
38228
|
+
const ext = path.extname(filePathOrUrl).toLowerCase();
|
|
38229
|
+
return EXT_TO_MIME[ext] ?? null;
|
|
38230
|
+
}
|
|
38231
|
+
function normalizeContentType(header) {
|
|
38232
|
+
if (!header) return null;
|
|
38233
|
+
const main = header.split(";")[0].trim().toLowerCase();
|
|
38234
|
+
return main || null;
|
|
38235
|
+
}
|
|
38236
|
+
function isAllowedMime(mime) {
|
|
38237
|
+
return ALLOWED_MIME_TYPES.includes(
|
|
38238
|
+
mime
|
|
38239
|
+
);
|
|
38240
|
+
}
|
|
38241
|
+
function isPrivateOrLocalHost(hostname) {
|
|
38242
|
+
if (hostname === "localhost" || hostname === "::1") return true;
|
|
38243
|
+
const ipv4 = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(hostname);
|
|
38244
|
+
if (ipv4) {
|
|
38245
|
+
const [, a, b, c, d] = ipv4.map(Number);
|
|
38246
|
+
if (a === 127) return true;
|
|
38247
|
+
if (a === 10) return true;
|
|
38248
|
+
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
38249
|
+
if (a === 192 && b === 168) return true;
|
|
38250
|
+
if (a === 169 && b === 254) return true;
|
|
38251
|
+
return false;
|
|
38252
|
+
}
|
|
38253
|
+
if (hostname.startsWith("::1") || hostname.startsWith("fe80:")) return true;
|
|
38254
|
+
return false;
|
|
38255
|
+
}
|
|
38256
|
+
async function assertUrlSafeForFetch(imageUrl) {
|
|
38257
|
+
let parsed;
|
|
38258
|
+
try {
|
|
38259
|
+
parsed = new URL(imageUrl);
|
|
38260
|
+
} catch {
|
|
38261
|
+
throw new Error("Invalid imageUrl: not a valid URL.");
|
|
38262
|
+
}
|
|
38263
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
38264
|
+
throw new Error("Invalid imageUrl: only http and https are allowed.");
|
|
38265
|
+
}
|
|
38266
|
+
const hostname = parsed.hostname;
|
|
38267
|
+
if (isPrivateOrLocalHost(hostname)) {
|
|
38268
|
+
throw new Error(
|
|
38269
|
+
"Invalid imageUrl: URLs to localhost or private IPs are not allowed."
|
|
38270
|
+
);
|
|
38271
|
+
}
|
|
38272
|
+
try {
|
|
38273
|
+
const { address } = await dnsLookup(hostname, { family: 4 });
|
|
38274
|
+
if (isPrivateOrLocalHost(address)) {
|
|
38275
|
+
throw new Error(
|
|
38276
|
+
"Invalid imageUrl: hostname resolves to a private or local IP."
|
|
38277
|
+
);
|
|
38278
|
+
}
|
|
38279
|
+
if (address === "169.254.169.254") {
|
|
38280
|
+
throw new Error("Invalid imageUrl: cloud metadata URLs are not allowed.");
|
|
38281
|
+
}
|
|
38282
|
+
} catch (err) {
|
|
38283
|
+
if (err instanceof Error && err.message.startsWith("Invalid imageUrl:"))
|
|
38284
|
+
throw err;
|
|
38285
|
+
throw new Error(
|
|
38286
|
+
`Invalid imageUrl: could not resolve hostname (${err instanceof Error ? err.message : String(err)}).`
|
|
38287
|
+
);
|
|
38288
|
+
}
|
|
38289
|
+
}
|
|
38290
|
+
async function resolveImageFromFilePath(filePath, allowedBaseDir) {
|
|
38291
|
+
if (!path.isAbsolute(filePath)) {
|
|
38292
|
+
filePath = path.resolve(allowedBaseDir, filePath);
|
|
38293
|
+
}
|
|
38294
|
+
const realPath = await fs.realpath(filePath).catch(() => null);
|
|
38295
|
+
const resolved = realPath ?? filePath;
|
|
38296
|
+
if (!isPathUnderBase(resolved, allowedBaseDir)) {
|
|
38297
|
+
throw new Error("filePath is outside the allowed workspace directory.");
|
|
38298
|
+
}
|
|
38299
|
+
const stat2 = await fs.stat(resolved, { bigint: false }).catch(() => null);
|
|
38300
|
+
if (!stat2) throw new Error("File not found or not readable.");
|
|
38301
|
+
if (stat2.size > MAX_FILE_SIZE_BYTES) {
|
|
38302
|
+
throw new Error(
|
|
38303
|
+
`File size exceeds ${MAX_FILE_SIZE_BYTES / 1024 / 1024}MB limit.`
|
|
38304
|
+
);
|
|
38305
|
+
}
|
|
38306
|
+
const buffer = await fs.readFile(resolved);
|
|
38307
|
+
const mime = mimeFromExtension(resolved) ?? "image/png";
|
|
38308
|
+
if (!isAllowedMime(mime)) {
|
|
38309
|
+
throw new Error(
|
|
38310
|
+
`File type not allowed. Allowed: ${ALLOWED_MIME_TYPES.join(", ")}.`
|
|
38311
|
+
);
|
|
38312
|
+
}
|
|
38313
|
+
const filename = path.basename(resolved) || "image";
|
|
38314
|
+
return {
|
|
38315
|
+
data: new Uint8Array(buffer),
|
|
38316
|
+
mimeType: mime,
|
|
38317
|
+
filename
|
|
38318
|
+
};
|
|
38319
|
+
}
|
|
38320
|
+
async function resolveImageFromUrl(imageUrl) {
|
|
38321
|
+
await assertUrlSafeForFetch(imageUrl);
|
|
38322
|
+
const controller = new AbortController();
|
|
38323
|
+
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
38324
|
+
try {
|
|
38325
|
+
const res = await fetch(imageUrl, {
|
|
38326
|
+
redirect: "manual",
|
|
38327
|
+
signal: controller.signal
|
|
38328
|
+
});
|
|
38329
|
+
clearTimeout(timeout);
|
|
38330
|
+
if (res.status >= 300 && res.status < 400) {
|
|
38331
|
+
throw new Error("Redirects are not allowed. Use the final image URL.");
|
|
38332
|
+
}
|
|
38333
|
+
if (!res.ok) {
|
|
38334
|
+
throw new Error(`Fetch failed: ${res.status} ${res.statusText}`);
|
|
38335
|
+
}
|
|
38336
|
+
const contentType = normalizeContentType(res.headers.get("Content-Type"));
|
|
38337
|
+
const mimeFromHeader = contentType && isAllowedMime(contentType) ? contentType : null;
|
|
38338
|
+
const contentLength = res.headers.get("Content-Length");
|
|
38339
|
+
if (contentLength) {
|
|
38340
|
+
const len = parseInt(contentLength, 10);
|
|
38341
|
+
if (!Number.isNaN(len) && len > MAX_FILE_SIZE_BYTES) {
|
|
38342
|
+
throw new Error(
|
|
38343
|
+
`Content-Length (${len}) exceeds ${MAX_FILE_SIZE_BYTES / 1024 / 1024}MB limit.`
|
|
38344
|
+
);
|
|
38345
|
+
}
|
|
38346
|
+
}
|
|
38347
|
+
const buf = await res.arrayBuffer();
|
|
38348
|
+
if (buf.byteLength > MAX_FILE_SIZE_BYTES) {
|
|
38349
|
+
throw new Error(
|
|
38350
|
+
`Response size exceeds ${MAX_FILE_SIZE_BYTES / 1024 / 1024}MB limit.`
|
|
38351
|
+
);
|
|
38352
|
+
}
|
|
38353
|
+
const mime = mimeFromHeader ?? mimeFromExtension(imageUrl) ?? "image/png";
|
|
38354
|
+
if (!isAllowedMime(mime)) {
|
|
38355
|
+
throw new Error(
|
|
38356
|
+
`Content-Type not allowed. Allowed: ${ALLOWED_MIME_TYPES.join(", ")}.`
|
|
38357
|
+
);
|
|
38358
|
+
}
|
|
38359
|
+
const ext = mime === "image/jpeg" || mime === "image/jpg" ? ".jpg" : mime.replace("image/", ".");
|
|
38360
|
+
return {
|
|
38361
|
+
data: new Uint8Array(buf),
|
|
38362
|
+
mimeType: mime,
|
|
38363
|
+
filename: `image${ext}`
|
|
38364
|
+
};
|
|
38365
|
+
} finally {
|
|
38366
|
+
clearTimeout(timeout);
|
|
38367
|
+
}
|
|
38368
|
+
}
|
|
38369
|
+
async function uploadAvatar(client, args) {
|
|
38370
|
+
try {
|
|
38371
|
+
if (!client.currentUserId) {
|
|
38372
|
+
return {
|
|
38373
|
+
error: "Not authenticated. Call dim_login first.",
|
|
38374
|
+
isError: true
|
|
38375
|
+
};
|
|
38376
|
+
}
|
|
38377
|
+
const { filePath, imageUrl } = args;
|
|
38378
|
+
if (filePath && imageUrl) {
|
|
38379
|
+
return {
|
|
38380
|
+
error: "Provide either filePath or imageUrl, not both.",
|
|
38381
|
+
isError: true
|
|
38382
|
+
};
|
|
38383
|
+
}
|
|
38384
|
+
if (!filePath && !imageUrl) {
|
|
38385
|
+
return { error: "Provide filePath or imageUrl.", isError: true };
|
|
38386
|
+
}
|
|
38387
|
+
const baseDir = getDefaultAllowedBaseDir();
|
|
38388
|
+
const payload = filePath ? await resolveImageFromFilePath(filePath, baseDir) : await resolveImageFromUrl(imageUrl);
|
|
38389
|
+
const user = await client.sdk.users.uploadAvatar(payload);
|
|
38390
|
+
return { data: { success: true, user } };
|
|
38391
|
+
} catch (error) {
|
|
38392
|
+
return {
|
|
38393
|
+
error: error instanceof Error ? error.message : String(error),
|
|
38394
|
+
isError: true
|
|
38395
|
+
};
|
|
38396
|
+
}
|
|
38397
|
+
}
|
|
38398
|
+
async function uploadCoverImage(client, args) {
|
|
38399
|
+
try {
|
|
38400
|
+
if (!client.currentUserId) {
|
|
38401
|
+
return {
|
|
38402
|
+
error: "Not authenticated. Call dim_login first.",
|
|
38403
|
+
isError: true
|
|
38404
|
+
};
|
|
38405
|
+
}
|
|
38406
|
+
const { filePath, imageUrl } = args;
|
|
38407
|
+
if (filePath && imageUrl) {
|
|
38408
|
+
return {
|
|
38409
|
+
error: "Provide either filePath or imageUrl, not both.",
|
|
38410
|
+
isError: true
|
|
38411
|
+
};
|
|
38412
|
+
}
|
|
38413
|
+
if (!filePath && !imageUrl) {
|
|
38414
|
+
return { error: "Provide filePath or imageUrl.", isError: true };
|
|
38415
|
+
}
|
|
38416
|
+
const baseDir = getDefaultAllowedBaseDir();
|
|
38417
|
+
const payload = filePath ? await resolveImageFromFilePath(filePath, baseDir) : await resolveImageFromUrl(imageUrl);
|
|
38418
|
+
const user = await client.sdk.users.uploadCoverImage(payload);
|
|
38419
|
+
return { data: { success: true, user } };
|
|
38420
|
+
} catch (error) {
|
|
38421
|
+
return {
|
|
38422
|
+
error: error instanceof Error ? error.message : String(error),
|
|
38423
|
+
isError: true
|
|
38424
|
+
};
|
|
38425
|
+
}
|
|
38426
|
+
}
|
|
38427
|
+
async function removeAvatar(client) {
|
|
38428
|
+
try {
|
|
38429
|
+
if (!client.currentUserId) {
|
|
38430
|
+
return {
|
|
38431
|
+
error: "Not authenticated. Call dim_login first.",
|
|
38432
|
+
isError: true
|
|
38433
|
+
};
|
|
38434
|
+
}
|
|
38435
|
+
const user = await client.sdk.users.removeAvatar();
|
|
38436
|
+
return { data: { success: true, user } };
|
|
38437
|
+
} catch (error) {
|
|
38438
|
+
return {
|
|
38439
|
+
error: error instanceof Error ? error.message : String(error),
|
|
38440
|
+
isError: true
|
|
38441
|
+
};
|
|
38442
|
+
}
|
|
38443
|
+
}
|
|
38444
|
+
async function removeCoverImage(client) {
|
|
38445
|
+
try {
|
|
38446
|
+
if (!client.currentUserId) {
|
|
38447
|
+
return {
|
|
38448
|
+
error: "Not authenticated. Call dim_login first.",
|
|
38449
|
+
isError: true
|
|
38450
|
+
};
|
|
38451
|
+
}
|
|
38452
|
+
const user = await client.sdk.users.removeCoverImage();
|
|
38453
|
+
return { data: { success: true, user } };
|
|
38454
|
+
} catch (error) {
|
|
38455
|
+
return {
|
|
38456
|
+
error: error instanceof Error ? error.message : String(error),
|
|
38457
|
+
isError: true
|
|
38458
|
+
};
|
|
38459
|
+
}
|
|
38460
|
+
}
|
|
38461
|
+
function getProfileImageRequirements() {
|
|
38462
|
+
return {
|
|
38463
|
+
data: {
|
|
38464
|
+
avatar: {
|
|
38465
|
+
maxFileSizeBytes: MAX_FILE_SIZE_BYTES,
|
|
38466
|
+
maxDimensions: { width: 200, height: 200 },
|
|
38467
|
+
aspectRatio: "1:1",
|
|
38468
|
+
allowedMimeTypes: [...ALLOWED_MIME_TYPES]
|
|
38469
|
+
},
|
|
38470
|
+
cover: {
|
|
38471
|
+
maxFileSizeBytes: MAX_FILE_SIZE_BYTES,
|
|
38472
|
+
maxDimensions: { width: 1200, height: 400 },
|
|
38473
|
+
aspectRatio: "3:1",
|
|
38474
|
+
allowedMimeTypes: [...ALLOWED_MIME_TYPES]
|
|
38475
|
+
}
|
|
38476
|
+
}
|
|
38477
|
+
};
|
|
38478
|
+
}
|
|
38479
|
+
var BIO_MAX_LENGTH = 500;
|
|
38480
|
+
async function setBio(client, args) {
|
|
38481
|
+
try {
|
|
38482
|
+
if (!client.currentUserId) {
|
|
38483
|
+
return {
|
|
38484
|
+
error: "Not authenticated. Call dim_login first.",
|
|
38485
|
+
isError: true
|
|
38486
|
+
};
|
|
38487
|
+
}
|
|
38488
|
+
const { bio } = args;
|
|
38489
|
+
if (typeof bio !== "string") {
|
|
38490
|
+
return { error: "bio must be a string.", isError: true };
|
|
38491
|
+
}
|
|
38492
|
+
if (bio.length > BIO_MAX_LENGTH) {
|
|
38493
|
+
return {
|
|
38494
|
+
error: `Bio must be at most ${BIO_MAX_LENGTH} characters.`,
|
|
38495
|
+
isError: true
|
|
38496
|
+
};
|
|
38497
|
+
}
|
|
38498
|
+
await client.sdk.users.updateProfile({ bio });
|
|
38499
|
+
return { data: { success: true } };
|
|
38500
|
+
} catch (error) {
|
|
38501
|
+
return {
|
|
38502
|
+
error: error instanceof Error ? error.message : String(error),
|
|
38503
|
+
isError: true
|
|
38504
|
+
};
|
|
38505
|
+
}
|
|
38506
|
+
}
|
|
38507
|
+
|
|
38508
|
+
// ../dim-agent-core/src/tools/users.ts
|
|
38509
|
+
function formatMinor(m) {
|
|
38510
|
+
if (m == null) return "\u2014";
|
|
38511
|
+
const n = typeof m === "bigint" ? Number(m) : m;
|
|
38512
|
+
return `$${(n / 1e6).toFixed(2)}`;
|
|
38513
|
+
}
|
|
38514
|
+
async function getGameHistory(client, args) {
|
|
38515
|
+
try {
|
|
38516
|
+
if (!client.currentUserId) {
|
|
38517
|
+
return {
|
|
38518
|
+
error: "Not authenticated. Call dim_login first.",
|
|
38519
|
+
isError: true
|
|
38520
|
+
};
|
|
38521
|
+
}
|
|
38522
|
+
const raw = await client.sdk.users.getGameHistory(client.currentUserId);
|
|
38523
|
+
const limit = Math.min(args.limit ?? 50, 100);
|
|
38524
|
+
const items = raw.slice(0, limit).map((item) => ({
|
|
38525
|
+
...item,
|
|
38526
|
+
betFormatted: formatMinor(item.betAmount),
|
|
38527
|
+
winningsFormatted: formatMinor(item.winnings)
|
|
38528
|
+
}));
|
|
38529
|
+
return {
|
|
38530
|
+
data: {
|
|
38531
|
+
items,
|
|
38532
|
+
totalReturned: items.length,
|
|
38533
|
+
hint: items.length >= limit ? `Showing most recent ${limit} games. Use limit param to request more (max 100).` : void 0
|
|
38534
|
+
}
|
|
38535
|
+
};
|
|
38536
|
+
} catch (error) {
|
|
38537
|
+
return {
|
|
38538
|
+
error: `Failed to get game history: ${error instanceof Error ? error.message : String(error)}`,
|
|
38539
|
+
isError: true
|
|
38540
|
+
};
|
|
38541
|
+
}
|
|
38542
|
+
}
|
|
38543
|
+
async function getMyStats(client) {
|
|
38544
|
+
try {
|
|
38545
|
+
if (!client.currentUserId) {
|
|
38546
|
+
return {
|
|
38547
|
+
error: "Not authenticated. Call dim_login first.",
|
|
38548
|
+
isError: true
|
|
38549
|
+
};
|
|
38550
|
+
}
|
|
38551
|
+
const stats = await client.sdk.users.getUserStats(
|
|
38552
|
+
client.currentUserId
|
|
38553
|
+
);
|
|
38554
|
+
return {
|
|
38555
|
+
data: {
|
|
38556
|
+
...stats,
|
|
38557
|
+
totalEarnedFormatted: formatMinor(stats.totalEarned),
|
|
38558
|
+
referralEarnedFormatted: formatMinor(stats.referralEarned),
|
|
38559
|
+
totalLostFormatted: formatMinor(stats.totalLost),
|
|
38560
|
+
totalFeesPaidFormatted: formatMinor(stats.totalFeesPaid)
|
|
38561
|
+
}
|
|
38562
|
+
};
|
|
38563
|
+
} catch (error) {
|
|
38564
|
+
return {
|
|
38565
|
+
error: `Failed to get stats: ${error instanceof Error ? error.message : String(error)}`,
|
|
38566
|
+
isError: true
|
|
38567
|
+
};
|
|
38568
|
+
}
|
|
38569
|
+
}
|
|
38570
|
+
|
|
38036
38571
|
// ../dim-agent-core/src/tools/index.ts
|
|
38037
38572
|
var TOOL_DEFINITIONS = [
|
|
38038
38573
|
// ── Auth ─────────────────────────────────────────────────────────────
|
|
@@ -38044,7 +38579,7 @@ var TOOL_DEFINITIONS = [
|
|
|
38044
38579
|
},
|
|
38045
38580
|
{
|
|
38046
38581
|
name: "dim_get_profile",
|
|
38047
|
-
description: "Get the current authenticated user profile including username, avatar, bio,
|
|
38582
|
+
description: "Get the current authenticated user profile including username, avatar, bio, chess ELO rating, and your DIM wallet address (walletAddress).",
|
|
38048
38583
|
params: {},
|
|
38049
38584
|
execute: (c) => getProfile(c)
|
|
38050
38585
|
},
|
|
@@ -38062,6 +38597,70 @@ var TOOL_DEFINITIONS = [
|
|
|
38062
38597
|
},
|
|
38063
38598
|
execute: (c, a) => setUsername(c, a)
|
|
38064
38599
|
},
|
|
38600
|
+
{
|
|
38601
|
+
name: "dim_upload_avatar",
|
|
38602
|
+
description: "Upload a profile avatar image. Provide filePath (path to image file in workspace) or imageUrl (URL to fetch image from). Max 5MB; allowed types: JPEG, PNG, WebP, GIF. Use dim_get_profile_image_requirements for dimensions.",
|
|
38603
|
+
params: {
|
|
38604
|
+
filePath: {
|
|
38605
|
+
type: "string",
|
|
38606
|
+
description: "Path to image file (under allowed workspace)"
|
|
38607
|
+
},
|
|
38608
|
+
imageUrl: {
|
|
38609
|
+
type: "string",
|
|
38610
|
+
description: "URL of image to fetch and upload"
|
|
38611
|
+
}
|
|
38612
|
+
},
|
|
38613
|
+
execute: (c, a) => uploadAvatar(c, a)
|
|
38614
|
+
},
|
|
38615
|
+
{
|
|
38616
|
+
name: "dim_upload_cover_image",
|
|
38617
|
+
description: "Upload a profile cover/header image. Provide filePath or imageUrl. Max 5MB; allowed types: JPEG, PNG, WebP, GIF. Use dim_get_profile_image_requirements for dimensions.",
|
|
38618
|
+
params: {
|
|
38619
|
+
filePath: {
|
|
38620
|
+
type: "string",
|
|
38621
|
+
description: "Path to image file (under allowed workspace)"
|
|
38622
|
+
},
|
|
38623
|
+
imageUrl: {
|
|
38624
|
+
type: "string",
|
|
38625
|
+
description: "URL of image to fetch and upload"
|
|
38626
|
+
}
|
|
38627
|
+
},
|
|
38628
|
+
execute: (c, a) => uploadCoverImage(
|
|
38629
|
+
c,
|
|
38630
|
+
a
|
|
38631
|
+
)
|
|
38632
|
+
},
|
|
38633
|
+
{
|
|
38634
|
+
name: "dim_remove_avatar",
|
|
38635
|
+
description: "Remove the current profile avatar (reset to default).",
|
|
38636
|
+
params: {},
|
|
38637
|
+
execute: (c) => removeAvatar(c)
|
|
38638
|
+
},
|
|
38639
|
+
{
|
|
38640
|
+
name: "dim_remove_cover_image",
|
|
38641
|
+
description: "Remove the current profile cover/header image (reset to default).",
|
|
38642
|
+
params: {},
|
|
38643
|
+
execute: (c) => removeCoverImage(c)
|
|
38644
|
+
},
|
|
38645
|
+
{
|
|
38646
|
+
name: "dim_get_profile_image_requirements",
|
|
38647
|
+
description: "Get max dimensions, max file size, aspect ratio, and allowed MIME types for avatar and cover images. Use before uploading to validate or choose images.",
|
|
38648
|
+
params: {},
|
|
38649
|
+
execute: async () => getProfileImageRequirements()
|
|
38650
|
+
},
|
|
38651
|
+
{
|
|
38652
|
+
name: "dim_set_bio",
|
|
38653
|
+
description: "Set or update your profile bio. Max 500 characters. No truncation; shorten if over limit.",
|
|
38654
|
+
params: {
|
|
38655
|
+
bio: {
|
|
38656
|
+
type: "string",
|
|
38657
|
+
description: "The new profile bio (max 500 characters)",
|
|
38658
|
+
required: true,
|
|
38659
|
+
max: 500
|
|
38660
|
+
}
|
|
38661
|
+
},
|
|
38662
|
+
execute: (c, a) => setBio(c, a)
|
|
38663
|
+
},
|
|
38065
38664
|
{
|
|
38066
38665
|
name: "dim_check_maintenance",
|
|
38067
38666
|
description: "Check if DIM is in maintenance mode. Call this before other operations to avoid failing with 503; when maintenance is true, inform the user to come back later.",
|
|
@@ -38204,9 +38803,15 @@ var TOOL_DEFINITIONS = [
|
|
|
38204
38803
|
execute: (c) => listDmThreads(c)
|
|
38205
38804
|
},
|
|
38206
38805
|
// ── Wallet ───────────────────────────────────────────────────────────
|
|
38806
|
+
{
|
|
38807
|
+
name: "dim_get_wallet_address",
|
|
38808
|
+
description: "Get the Solana wallet address DIM uses for this account. Use this to confirm which address receives deposits and is used for signing. Returns walletAddress and a short wallet linkage note.",
|
|
38809
|
+
params: {},
|
|
38810
|
+
execute: (c) => getWalletAddress(c)
|
|
38811
|
+
},
|
|
38207
38812
|
{
|
|
38208
38813
|
name: "dim_get_balance",
|
|
38209
|
-
description: "Get the wallet balance for the authenticated user. Returns SOL and USDC (usdcFormatted is always present, e.g. $0.00 or $1.50).",
|
|
38814
|
+
description: "Get the wallet balance for the authenticated user. Returns your DIM Solana address (walletAddress), SOL and USDC (usdcFormatted is always present, e.g. $0.00 or $1.50).",
|
|
38210
38815
|
params: {},
|
|
38211
38816
|
execute: (c) => getBalance(c)
|
|
38212
38817
|
},
|
|
@@ -38248,7 +38853,7 @@ var TOOL_DEFINITIONS = [
|
|
|
38248
38853
|
},
|
|
38249
38854
|
{
|
|
38250
38855
|
name: "dim_get_wallet_activity",
|
|
38251
|
-
description: "Get recent wallet transaction activity (deposits, payouts, transfers, refunds). Highlights any claimable items.",
|
|
38856
|
+
description: "Get recent wallet transaction activity (deposits, payouts, transfers, refunds) and your DIM wallet address. Highlights any claimable items.",
|
|
38252
38857
|
params: {
|
|
38253
38858
|
limit: {
|
|
38254
38859
|
type: "number",
|
|
@@ -38288,6 +38893,23 @@ var TOOL_DEFINITIONS = [
|
|
|
38288
38893
|
params: {},
|
|
38289
38894
|
execute: (c) => getGameMetrics(c)
|
|
38290
38895
|
},
|
|
38896
|
+
{
|
|
38897
|
+
name: "dim_get_game_history",
|
|
38898
|
+
description: "Get your game history: past games with result, bet, winnings, opponent, and playedAt. Use for daily progress reports.",
|
|
38899
|
+
params: {
|
|
38900
|
+
limit: {
|
|
38901
|
+
type: "number",
|
|
38902
|
+
description: "Max games to return (default 50, max 100)"
|
|
38903
|
+
}
|
|
38904
|
+
},
|
|
38905
|
+
execute: (c, a) => getGameHistory(c, a)
|
|
38906
|
+
},
|
|
38907
|
+
{
|
|
38908
|
+
name: "dim_get_my_stats",
|
|
38909
|
+
description: "Get your aggregated DIM stats: games played, wins, losses, total earned, referral earned, total lost, fees paid, chess ELO, points.",
|
|
38910
|
+
params: {},
|
|
38911
|
+
execute: (c) => getMyStats(c)
|
|
38912
|
+
},
|
|
38291
38913
|
{
|
|
38292
38914
|
name: "dim_create_lobby",
|
|
38293
38915
|
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.",
|
|
@@ -38417,6 +39039,30 @@ var TOOL_DEFINITIONS = [
|
|
|
38417
39039
|
},
|
|
38418
39040
|
execute: (c, a) => gameLoop(c, a)
|
|
38419
39041
|
},
|
|
39042
|
+
{
|
|
39043
|
+
name: "dim_request_rematch",
|
|
39044
|
+
description: "Request a rematch after a completed game. If both players request, a lobby is created automatically server-side.",
|
|
39045
|
+
params: {
|
|
39046
|
+
gameId: {
|
|
39047
|
+
type: "string",
|
|
39048
|
+
description: "The completed game ID to request a rematch for",
|
|
39049
|
+
required: true
|
|
39050
|
+
}
|
|
39051
|
+
},
|
|
39052
|
+
execute: (c, a) => requestRematch(c, a)
|
|
39053
|
+
},
|
|
39054
|
+
{
|
|
39055
|
+
name: "dim_accept_rematch",
|
|
39056
|
+
description: "Accept a rematch request from your opponent. When both players accept, the rematch lobby is created automatically.",
|
|
39057
|
+
params: {
|
|
39058
|
+
gameId: {
|
|
39059
|
+
type: "string",
|
|
39060
|
+
description: "The completed game ID to accept the rematch for",
|
|
39061
|
+
required: true
|
|
39062
|
+
}
|
|
39063
|
+
},
|
|
39064
|
+
execute: (c, a) => acceptRematch(c, a)
|
|
39065
|
+
},
|
|
38420
39066
|
{
|
|
38421
39067
|
name: "dim_get_lobby_link",
|
|
38422
39068
|
description: "Get a shareable join link for a lobby. Share this URL via DM \u2014 the user can join with one click. Like dim_invite_to_lobby, do NOT also call dim_join_queue for the same lobby.",
|
|
@@ -38820,12 +39466,12 @@ function getPluginConfig(api) {
|
|
|
38820
39466
|
return dimclawEntry?.config ?? null;
|
|
38821
39467
|
}
|
|
38822
39468
|
function resolveStorePath(storePath) {
|
|
38823
|
-
const expanded = storePath.startsWith("~/") && process.env.HOME ?
|
|
38824
|
-
return
|
|
39469
|
+
const expanded = storePath.startsWith("~/") && process.env.HOME ? path2.join(process.env.HOME, storePath.slice(2)) : storePath;
|
|
39470
|
+
return path2.resolve(expanded);
|
|
38825
39471
|
}
|
|
38826
39472
|
async function readWalletFile(storePath) {
|
|
38827
39473
|
try {
|
|
38828
|
-
const raw = await
|
|
39474
|
+
const raw = await readFile2(storePath, "utf8");
|
|
38829
39475
|
const parsed = JSON.parse(raw);
|
|
38830
39476
|
if (parsed.walletPrivateKey && parsed.walletAddress) {
|
|
38831
39477
|
return {
|
|
@@ -38841,7 +39487,7 @@ async function readWalletFile(storePath) {
|
|
|
38841
39487
|
}
|
|
38842
39488
|
}
|
|
38843
39489
|
async function writeWalletFile(storePath, record2) {
|
|
38844
|
-
await mkdir(
|
|
39490
|
+
await mkdir(path2.dirname(storePath), { recursive: true });
|
|
38845
39491
|
const tmp = `${storePath}.tmp`;
|
|
38846
39492
|
await writeFile(tmp, `${JSON.stringify(record2, null, 2)}
|
|
38847
39493
|
`, {
|
|
@@ -38871,9 +39517,9 @@ async function resolveWalletKey(config) {
|
|
|
38871
39517
|
}
|
|
38872
39518
|
function resolveHeartbeatPath(p) {
|
|
38873
39519
|
if (p.startsWith("~/") && process.env.HOME) {
|
|
38874
|
-
return
|
|
39520
|
+
return path2.join(process.env.HOME, p.slice(2));
|
|
38875
39521
|
}
|
|
38876
|
-
return
|
|
39522
|
+
return path2.resolve(p);
|
|
38877
39523
|
}
|
|
38878
39524
|
function createHeartbeatWriter(heartbeatPath) {
|
|
38879
39525
|
if (!heartbeatPath) return void 0;
|
|
@@ -38881,7 +39527,12 @@ function createHeartbeatWriter(heartbeatPath) {
|
|
|
38881
39527
|
const pending = [];
|
|
38882
39528
|
return async (event) => {
|
|
38883
39529
|
pending.push(event);
|
|
38884
|
-
const lines = [
|
|
39530
|
+
const lines = [
|
|
39531
|
+
"# DIM Heartbeat",
|
|
39532
|
+
"",
|
|
39533
|
+
"- At least once per day, report to the operator your DIM progress: call dim_get_game_history (and optionally dim_get_my_stats and dim_get_referral_summary), then summarize games played and referral earnings.",
|
|
39534
|
+
""
|
|
39535
|
+
];
|
|
38885
39536
|
const eventTypes = new Set(pending.map((e) => e.event));
|
|
38886
39537
|
if (eventTypes.has("chat:message")) {
|
|
38887
39538
|
lines.push("- You have new DMs \u2014 call dim_check_notifications");
|
|
@@ -38902,7 +39553,7 @@ function createHeartbeatWriter(heartbeatPath) {
|
|
|
38902
39553
|
}
|
|
38903
39554
|
lines.push("");
|
|
38904
39555
|
try {
|
|
38905
|
-
await mkdir(
|
|
39556
|
+
await mkdir(path2.dirname(filePath), { recursive: true });
|
|
38906
39557
|
const tmp = `${filePath}.tmp`;
|
|
38907
39558
|
await writeFile(tmp, lines.join("\n"), "utf8");
|
|
38908
39559
|
await rename(tmp, filePath);
|
|
@@ -39018,7 +39669,12 @@ function register(api) {
|
|
|
39018
39669
|
return textResult(
|
|
39019
39670
|
JSON.stringify(
|
|
39020
39671
|
{
|
|
39672
|
+
wallet_linkage: WALLET_LINKAGE_NOTE,
|
|
39673
|
+
wallet_address: "Your DIM Solana address is returned by dim_get_profile, dim_get_balance, dim_get_wallet_activity, and dim_get_wallet_address. Use it to confirm which address is tied to DIM.",
|
|
39674
|
+
wallet_activity: "For deposits, transfers, payouts, and claimable items use dim_get_wallet_activity.",
|
|
39021
39675
|
hint: "Game flow: For paid lobbies, dim_create_lobby \u2192 dim_deposit_for_lobby \u2192 dim_join_queue. For free lobbies, dim_create_lobby \u2192 dim_join_queue. Then dim_game_loop (blocks until your turn) \u2192 dim_submit_action \u2192 dim_game_loop \u2192 repeat. Use dim_leave_lobby to exit a lobby.",
|
|
39676
|
+
spectate_on_game_start: "When a game starts (dim_join_queue or dim_accept_challenge returns matched/gameId), tell the user they can spectate at the spectateUrl in the tool response, or at https://dim.cool/spectate/[your DIM username].",
|
|
39677
|
+
daily_summary: "At least once per day, report to the operator your DIM progress: call dim_get_game_history (and optionally dim_get_my_stats and dim_get_referral_summary), then summarize games played and referral earnings.",
|
|
39022
39678
|
move_formats: {
|
|
39023
39679
|
"rock-paper-scissors": 'action: "play", payload: { action: "rock"|"paper"|"scissors" }',
|
|
39024
39680
|
chess: 'action: "move", payload: { from: "e2", to: "e4" }',
|