@cmdoss/suipay-mcp 0.2.2-dev.10 → 0.2.2-dev.12
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/README.md
CHANGED
|
@@ -5,15 +5,21 @@ buyer-funded spend account. The buyer owns the account. The agent holds the
|
|
|
5
5
|
delegate key and can spend only under the on-chain grant (recipient bind,
|
|
6
6
|
per-payment cap, budget).
|
|
7
7
|
|
|
8
|
-
Pin `@cmdoss/suipay-mcp@0.2.2-dev.
|
|
9
|
-
|
|
8
|
+
Pin `@cmdoss/suipay-mcp@0.2.2-dev.12` in MCP config for the `latest` dist-tag.
|
|
9
|
+
`npx -y @cmdoss/suipay-mcp@dev` tracks the `dev` prerelease line.
|
|
10
|
+
`1.0.1` remains on the registry as a historical release; do not install it
|
|
11
|
+
for new agents.
|
|
10
12
|
|
|
11
13
|
## Install
|
|
12
14
|
|
|
13
15
|
```bash
|
|
14
|
-
claude mcp add --scope user suipay -- npx -y @cmdoss/suipay-mcp@0.2.2-dev.
|
|
16
|
+
claude mcp add --scope user suipay -- npx -y @cmdoss/suipay-mcp@0.2.2-dev.12
|
|
15
17
|
```
|
|
16
18
|
|
|
19
|
+
`@dev` installs the Railway-dev gateway/console defaults. A workspace
|
|
20
|
+
checkout still defaults to localhost. `SUIPAY_GATEWAY_URL` and
|
|
21
|
+
`SUIPAY_CONSOLE_URL` always override.
|
|
22
|
+
|
|
17
23
|
No wallet secret belongs in this command or MCP config. There is no
|
|
18
24
|
Sign-In With Sui (SIWS) step. To reuse an existing delegate seed locally,
|
|
19
25
|
set `SUIPAY_MCP_KEY` (64-hex or `suiprivkey1…`) in the MCP env — never in
|
|
@@ -112,10 +118,10 @@ Default is Railway **suipay-dev**. `--local` / `target: "local"` is laptop-only.
|
|
|
112
118
|
|
|
113
119
|
```bash
|
|
114
120
|
# Railway suipay-dev (default)
|
|
115
|
-
npx @cmdoss/suipay-mcp@0.2.2-dev.
|
|
121
|
+
npx @cmdoss/suipay-mcp@0.2.2-dev.12
|
|
116
122
|
|
|
117
123
|
# Laptop stack
|
|
118
|
-
npx @cmdoss/suipay-mcp@0.2.2-dev.
|
|
124
|
+
npx @cmdoss/suipay-mcp@0.2.2-dev.12 --local
|
|
119
125
|
```
|
|
120
126
|
|
|
121
127
|
`SUIPAY_MCP_TARGET=local|dev` selects the same preset. Explicit
|
|
@@ -175,4 +181,8 @@ node packages/mcp/dist/bin/suipay.js
|
|
|
175
181
|
Binary writes status banner to stderr only. Stdout stays reserved for
|
|
176
182
|
MCP protocol.
|
|
177
183
|
|
|
178
|
-
|
|
184
|
+
Publishing is the `release-npm` workflow: merge to `dev` publishes
|
|
185
|
+
`@cmdoss/suipay-mcp@<version>-dev.N` with dist-tag `dev` (OIDC, pack gate,
|
|
186
|
+
provenance). `latest` is a gated dispatch from `main` (`dry_run` default
|
|
187
|
+
true). Do not `npm publish` from a laptop. See
|
|
188
|
+
[`docs/guide/npm-release.md`](../../docs/guide/npm-release.md).
|
package/dist/bin/suipay.js
CHANGED
|
@@ -5547,10 +5547,10 @@ function createMemoryLedger() {
|
|
|
5547
5547
|
}
|
|
5548
5548
|
|
|
5549
5549
|
// src/auth.ts
|
|
5550
|
-
import { dirname, join as
|
|
5550
|
+
import { dirname as dirname2, join as join3 } from "path";
|
|
5551
5551
|
import {
|
|
5552
5552
|
mkdirSync,
|
|
5553
|
-
readFileSync,
|
|
5553
|
+
readFileSync as readFileSync2,
|
|
5554
5554
|
renameSync,
|
|
5555
5555
|
chmodSync,
|
|
5556
5556
|
unlinkSync,
|
|
@@ -5567,12 +5567,70 @@ import { bytesToHex as bytesToHex4 } from "@noble/hashes/utils.js";
|
|
|
5567
5567
|
|
|
5568
5568
|
// src/config.ts
|
|
5569
5569
|
import { homedir } from "os";
|
|
5570
|
-
import { join } from "path";
|
|
5570
|
+
import { join as join2 } from "path";
|
|
5571
5571
|
import { SuiGrpcClient as SuiGrpcClient2 } from "@mysten/sui/grpc";
|
|
5572
5572
|
import { normalizeSuiAddress as normalizeSuiAddress7 } from "@mysten/sui/utils";
|
|
5573
|
+
|
|
5574
|
+
// src/hosted-defaults.ts
|
|
5575
|
+
import { existsSync, readFileSync } from "fs";
|
|
5576
|
+
import { dirname, join } from "path";
|
|
5577
|
+
import { fileURLToPath } from "url";
|
|
5578
|
+
var MCP_LOCAL_GATEWAY_URL = "https://gateway-dev-ba84.up.railway.app";
|
|
5579
|
+
var MCP_LOCAL_CONSOLE_URL = "https://suipay-dev.up.railway.app";
|
|
5580
|
+
var MCP_DEV_GATEWAY_URL = "https://gateway-dev-ba84.up.railway.app";
|
|
5581
|
+
var MCP_DEV_CONSOLE_URL = "https://suipay-dev.up.railway.app";
|
|
5582
|
+
var MCP_PROD_GATEWAY_URL = "https://gateway.suipay.dev";
|
|
5583
|
+
var MCP_PROD_CONSOLE_URL = "https://www.sui.io/agentpayments";
|
|
5584
|
+
var MCP_CHANNEL_DEFAULTS = {
|
|
5585
|
+
local: { gatewayUrl: MCP_LOCAL_GATEWAY_URL, consoleUrl: MCP_LOCAL_CONSOLE_URL },
|
|
5586
|
+
dev: { gatewayUrl: MCP_DEV_GATEWAY_URL, consoleUrl: MCP_DEV_CONSOLE_URL },
|
|
5587
|
+
prod: { gatewayUrl: MCP_PROD_GATEWAY_URL, consoleUrl: MCP_PROD_CONSOLE_URL }
|
|
5588
|
+
};
|
|
5589
|
+
function isNodeModulesInstall(moduleUrl) {
|
|
5590
|
+
const text2 = moduleUrl.replace(/\\/g, "/");
|
|
5591
|
+
if (text2.includes("/packages/mcp/")) return false;
|
|
5592
|
+
return text2.includes("/node_modules/");
|
|
5593
|
+
}
|
|
5594
|
+
function detectMcpDefaultChannel(opts) {
|
|
5595
|
+
if (!isNodeModulesInstall(opts.moduleUrl)) return "local";
|
|
5596
|
+
if (typeof opts.version === "string" && opts.version.includes("-dev.")) return "dev";
|
|
5597
|
+
if (!opts.version) return "local";
|
|
5598
|
+
return "prod";
|
|
5599
|
+
}
|
|
5600
|
+
function readOwnPackageVersion(moduleUrl = import.meta.url) {
|
|
5601
|
+
let dir = dirname(fileURLToPath(moduleUrl));
|
|
5602
|
+
for (let i = 0; i < 6; i += 1) {
|
|
5603
|
+
const candidate = join(dir, "package.json");
|
|
5604
|
+
if (existsSync(candidate)) {
|
|
5605
|
+
try {
|
|
5606
|
+
const pkg = JSON.parse(readFileSync(candidate, "utf8"));
|
|
5607
|
+
if (pkg.name === "@cmdoss/suipay-mcp" && typeof pkg.version === "string") {
|
|
5608
|
+
return pkg.version;
|
|
5609
|
+
}
|
|
5610
|
+
} catch {
|
|
5611
|
+
}
|
|
5612
|
+
}
|
|
5613
|
+
const parent = dirname(dir);
|
|
5614
|
+
if (parent === dir) break;
|
|
5615
|
+
dir = parent;
|
|
5616
|
+
}
|
|
5617
|
+
return "";
|
|
5618
|
+
}
|
|
5619
|
+
function resolveMcpHostedDefaults(opts = {}) {
|
|
5620
|
+
const env = opts.env ?? process.env;
|
|
5621
|
+
const moduleUrl = opts.moduleUrl ?? import.meta.url;
|
|
5622
|
+
const version = opts.version ?? readOwnPackageVersion(moduleUrl);
|
|
5623
|
+
const defaults = MCP_CHANNEL_DEFAULTS[detectMcpDefaultChannel({ moduleUrl, version })];
|
|
5624
|
+
return {
|
|
5625
|
+
gatewayUrl: env.SUIPAY_GATEWAY_URL ?? defaults.gatewayUrl,
|
|
5626
|
+
consoleUrl: env.SUIPAY_CONSOLE_URL ?? defaults.consoleUrl
|
|
5627
|
+
};
|
|
5628
|
+
}
|
|
5629
|
+
|
|
5630
|
+
// src/config.ts
|
|
5573
5631
|
function mcpCredentialsPath() {
|
|
5574
5632
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? homedir();
|
|
5575
|
-
return
|
|
5633
|
+
return join2(home, ".suipay", "credentials.json");
|
|
5576
5634
|
}
|
|
5577
5635
|
var MCP_TARGET_PRESETS = {
|
|
5578
5636
|
dev: {
|
|
@@ -5670,14 +5728,15 @@ function sameMcpGateway(a, b) {
|
|
|
5670
5728
|
}
|
|
5671
5729
|
function loadMcpConfig(env = process.env, argv = []) {
|
|
5672
5730
|
const network = env.SUIPAY_NETWORK ?? "testnet";
|
|
5673
|
-
const
|
|
5674
|
-
const
|
|
5675
|
-
const
|
|
5676
|
-
const
|
|
5731
|
+
const explicit = parseMcpTargetFlag(argv) ?? parseMcpTargetName(env.SUIPAY_MCP_TARGET);
|
|
5732
|
+
const hosted = resolveMcpHostedDefaults({ env });
|
|
5733
|
+
const preset = explicit ? MCP_TARGET_PRESETS[explicit] : null;
|
|
5734
|
+
const gatewayUrl = preset ? env.SUIPAY_GATEWAY_URL?.trim() || preset.gatewayUrl : hosted.gatewayUrl;
|
|
5735
|
+
const consoleUrl = preset ? env.SUIPAY_CONSOLE_URL?.trim() || preset.consoleUrl : hosted.consoleUrl;
|
|
5677
5736
|
const rawDir = env.SUIPAY_EXCLUSION_DIRECTORY_OBJECT_ID?.trim();
|
|
5678
5737
|
if (rawDir) assertValidPackageId("SUIPAY_EXCLUSION_DIRECTORY_OBJECT_ID", rawDir);
|
|
5679
5738
|
return {
|
|
5680
|
-
target,
|
|
5739
|
+
...explicit ? { target: explicit } : {},
|
|
5681
5740
|
consoleUrl,
|
|
5682
5741
|
gatewayUrl,
|
|
5683
5742
|
rpcUrl: env.SUIPAY_RPC_URL ?? GRPC_URLS[network],
|
|
@@ -5751,7 +5810,7 @@ function credsPath() {
|
|
|
5751
5810
|
return mcpCredentialsPath();
|
|
5752
5811
|
}
|
|
5753
5812
|
function credsDir() {
|
|
5754
|
-
return
|
|
5813
|
+
return dirname2(credsPath());
|
|
5755
5814
|
}
|
|
5756
5815
|
var HEX64 = /^[0-9a-fA-F]{64}$/;
|
|
5757
5816
|
var ADDR = /^0x[0-9a-fA-F]{64}$/;
|
|
@@ -5782,7 +5841,7 @@ function readCredentialsJson() {
|
|
|
5782
5841
|
const path = credsPath();
|
|
5783
5842
|
let raw;
|
|
5784
5843
|
try {
|
|
5785
|
-
raw =
|
|
5844
|
+
raw = readFileSync2(path, "utf8");
|
|
5786
5845
|
} catch (error2) {
|
|
5787
5846
|
const code = error2.code;
|
|
5788
5847
|
if (code === "ENOENT" || code === "ENOTDIR") return null;
|
|
@@ -5824,7 +5883,7 @@ function fsyncDir(dir) {
|
|
|
5824
5883
|
}
|
|
5825
5884
|
}
|
|
5826
5885
|
function writeTmpCredentials(dir, payload) {
|
|
5827
|
-
const tmp =
|
|
5886
|
+
const tmp = join3(dir, `.credentials.${process.pid}.${randomSuffix()}.tmp`);
|
|
5828
5887
|
const fd = openSync(tmp, "w", 384);
|
|
5829
5888
|
try {
|
|
5830
5889
|
writeSync(fd, JSON.stringify(payload, null, 2));
|
|
@@ -8360,9 +8419,9 @@ import { pathToFileURL } from "url";
|
|
|
8360
8419
|
|
|
8361
8420
|
// src/delivery-file.ts
|
|
8362
8421
|
import { mkdirSync as mkdirSync2, writeFileSync, chmodSync as chmodSync2 } from "fs";
|
|
8363
|
-
import { dirname as
|
|
8422
|
+
import { dirname as dirname3, join as join4 } from "path";
|
|
8364
8423
|
function mcpDeliveriesDir() {
|
|
8365
|
-
return
|
|
8424
|
+
return join4(dirname3(mcpCredentialsPath()), "deliveries");
|
|
8366
8425
|
}
|
|
8367
8426
|
var EXT = {
|
|
8368
8427
|
"image/png": ".png",
|
|
@@ -8396,7 +8455,7 @@ function saveDeliveredBody(input) {
|
|
|
8396
8455
|
chmodSync2(dir, 448);
|
|
8397
8456
|
} catch {
|
|
8398
8457
|
}
|
|
8399
|
-
const path =
|
|
8458
|
+
const path = join4(
|
|
8400
8459
|
dir,
|
|
8401
8460
|
`${fileStem(input.digest, input.challengeId)}${extensionFor(input.contentType)}`
|
|
8402
8461
|
);
|
|
@@ -8486,12 +8545,12 @@ function settlePayResult(result) {
|
|
|
8486
8545
|
}
|
|
8487
8546
|
|
|
8488
8547
|
// src/pay-file.ts
|
|
8489
|
-
import { isAbsolute, dirname as
|
|
8548
|
+
import { isAbsolute, dirname as dirname4, sep } from "path";
|
|
8490
8549
|
import {
|
|
8491
8550
|
openSync as openSync2,
|
|
8492
8551
|
closeSync as closeSync2,
|
|
8493
8552
|
fstatSync,
|
|
8494
|
-
readFileSync as
|
|
8553
|
+
readFileSync as readFileSync3,
|
|
8495
8554
|
realpathSync,
|
|
8496
8555
|
constants
|
|
8497
8556
|
} from "fs";
|
|
@@ -8574,7 +8633,7 @@ function resolveContainedPath(raw) {
|
|
|
8574
8633
|
if (!inside(rootReal, fileReal)) {
|
|
8575
8634
|
return fail2("FILE_OUTSIDE_ROOT", "file must be under SUIPAY_MCP_FILE_ROOT");
|
|
8576
8635
|
}
|
|
8577
|
-
const credsDir2 =
|
|
8636
|
+
const credsDir2 = dirname4(mcpCredentialsPath());
|
|
8578
8637
|
let credsReal = credsDir2;
|
|
8579
8638
|
try {
|
|
8580
8639
|
credsReal = realpathSync(credsDir2);
|
|
@@ -8603,7 +8662,7 @@ function readRegularFile(path) {
|
|
|
8603
8662
|
`file is ${st.size} bytes; exceeds ${MCP_MAX_FILE_FIELD_BYTES} decoded bytes`
|
|
8604
8663
|
);
|
|
8605
8664
|
}
|
|
8606
|
-
const bytes =
|
|
8665
|
+
const bytes = readFileSync3(fd);
|
|
8607
8666
|
if (bytes.byteLength === 0) {
|
|
8608
8667
|
return fail2("EMPTY_FILE", "file is empty");
|
|
8609
8668
|
}
|
package/dist/http.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadBootProfile,
|
|
3
3
|
main
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6GJ7IGYM.js";
|
|
5
5
|
import {
|
|
6
6
|
MCP_TARGET_PRESETS,
|
|
7
7
|
PACKAGE_NAME,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
settlePreparedMcpPayment,
|
|
27
27
|
traceMcpHttpRequest,
|
|
28
28
|
verifySpendAccountPayReconstructs
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-WRN7FRUI.js";
|
|
30
30
|
export {
|
|
31
31
|
MCP_TARGET_PRESETS,
|
|
32
32
|
PACKAGE_NAME,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cmdoss/suipay-mcp",
|
|
3
|
-
"version": "0.2.2-dev.
|
|
3
|
+
"version": "0.2.2-dev.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "SuiPay MCP — pay MPP-gated APIs from a spend-account grant with an agent-held delegate key.",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"tsup": "^8.0.0",
|
|
38
38
|
"typescript": "^6.0.3",
|
|
39
39
|
"vitest": "^4.1.10",
|
|
40
|
-
"@cmdoss/suipay-
|
|
41
|
-
"@cmdoss/suipay-
|
|
40
|
+
"@cmdoss/suipay-core": "0.1.0",
|
|
41
|
+
"@cmdoss/suipay-sdk": "0.1.0"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build": "tsup",
|