@cmdoss/suipay-mcp 0.2.1 → 0.2.2

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,13 +5,13 @@ 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.1` in MCP config. `1.0.1` remains on the
8
+ Pin `@cmdoss/suipay-mcp@0.2.2` in MCP config. `1.0.1` remains on the
9
9
  registry as a historical release; do not install it for new agents.
10
10
 
11
11
  ## Install
12
12
 
13
13
  ```bash
14
- claude mcp add --scope user suipay -- npx -y @cmdoss/suipay-mcp@0.2.1
14
+ claude mcp add --scope user suipay -- npx -y @cmdoss/suipay-mcp@0.2.2
15
15
  ```
16
16
 
17
17
  No wallet secret belongs in this command or MCP config. There is no
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  main
4
- } from "../chunk-TPW6S2K4.js";
5
- import "../chunk-XZQOOY66.js";
4
+ } from "../chunk-EM7PKWVL.js";
5
+ import "../chunk-26NKQ37M.js";
6
6
  import "../chunk-A3JIIDYT.js";
7
7
 
8
8
  // src/bin/suipay.ts
@@ -3650,7 +3650,7 @@ import {
3650
3650
  } from "fs";
3651
3651
  import { Ed25519Keypair as Ed25519Keypair2 } from "@mysten/sui/keypairs/ed25519";
3652
3652
  import { fromBase64 as fromBase643 } from "@mysten/sui/utils";
3653
- import { bytesToHex as bytesToHex2 } from "@noble/hashes/utils";
3653
+ import { bytesToHex as bytesToHex2 } from "@noble/hashes/utils.js";
3654
3654
 
3655
3655
  // src/config.ts
3656
3656
  import { homedir } from "os";
@@ -3686,8 +3686,8 @@ function loadMcpConfig(env = process.env) {
3686
3686
 
3687
3687
  // src/crypto.ts
3688
3688
  import { getPublicKeyAsync, utils } from "@noble/ed25519";
3689
- import { blake2b } from "@noble/hashes/blake2b";
3690
- import { bytesToHex } from "@noble/hashes/utils";
3689
+ import { blake2b } from "@noble/hashes/blake2.js";
3690
+ import { bytesToHex } from "@noble/hashes/utils.js";
3691
3691
  var ED25519_FLAG = 0;
3692
3692
  function deriveSuiAddress(publicKey) {
3693
3693
  const data = new Uint8Array(1 + publicKey.length);
@@ -3758,6 +3758,28 @@ function loadCreds() {
3758
3758
  }
3759
3759
  return parsed;
3760
3760
  }
3761
+ function writeCredentialsFile(payload) {
3762
+ const dir = credsDir();
3763
+ mkdirSync(dir, { recursive: true, mode: 448 });
3764
+ try {
3765
+ chmodSync(dir, 448);
3766
+ } catch {
3767
+ }
3768
+ const path = credsPath();
3769
+ const tmp = join2(dir, `.credentials.${process.pid}.tmp`);
3770
+ const fd = openSync(tmp, "w", 384);
3771
+ try {
3772
+ writeSync(fd, JSON.stringify(payload, null, 2));
3773
+ fsyncSync(fd);
3774
+ } finally {
3775
+ closeSync(fd);
3776
+ }
3777
+ renameSync(tmp, path);
3778
+ try {
3779
+ chmodSync(path, 384);
3780
+ } catch {
3781
+ }
3782
+ }
3761
3783
  function createCredentialsFileExclusive(payload) {
3762
3784
  const dir = credsDir();
3763
3785
  mkdirSync(dir, { recursive: true, mode: 448 });
@@ -3855,6 +3877,23 @@ function identityFromStored(privateKeyHex, publicKeyHex, address) {
3855
3877
  }
3856
3878
  return { delegateAddress: address, publicKeyHex };
3857
3879
  }
3880
+ function rewriteV1ToLocalSigningKey(creds, opts = {}) {
3881
+ const identity = identityFromStored(
3882
+ creds.delegatePrivateKey,
3883
+ creds.delegatePublicKeyHex,
3884
+ creds.delegateAddress
3885
+ );
3886
+ const record = {
3887
+ version: 2,
3888
+ delegatePrivateKey: creds.delegatePrivateKey,
3889
+ delegatePublicKeyHex: creds.delegatePublicKeyHex,
3890
+ delegateAddress: creds.delegateAddress,
3891
+ createdAt: creds.createdAt,
3892
+ ...opts.label?.trim() ? { label: opts.label.trim() } : creds.label?.trim() ? { label: creds.label.trim() } : {}
3893
+ };
3894
+ writeCredentialsFile(record);
3895
+ return identity;
3896
+ }
3858
3897
  async function ensureLocalSigningKey(opts = {}) {
3859
3898
  const parsed = readCredentialsJson();
3860
3899
  if (parsed !== null) {
@@ -3866,11 +3905,7 @@ async function ensureLocalSigningKey(opts = {}) {
3866
3905
  );
3867
3906
  }
3868
3907
  if (isValid(parsed)) {
3869
- return identityFromStored(
3870
- parsed.delegatePrivateKey,
3871
- parsed.delegatePublicKeyHex,
3872
- parsed.delegateAddress
3873
- );
3908
+ return rewriteV1ToLocalSigningKey(parsed, opts);
3874
3909
  }
3875
3910
  throw new Error(`credentials file at ${credsPath()} failed schema validation - refusing to continue`);
3876
3911
  }
@@ -3887,13 +3922,16 @@ async function ensureLocalSigningKey(opts = {}) {
3887
3922
  return { delegateAddress: kp.suiAddress, publicKeyHex: kp.publicKeyHex };
3888
3923
  }
3889
3924
  const winner = readCredentialsJson();
3890
- if (winner !== null && (isLocalSigningKeyRecord(winner) || isValid(winner))) {
3925
+ if (winner !== null && isLocalSigningKeyRecord(winner)) {
3891
3926
  return identityFromStored(
3892
3927
  winner.delegatePrivateKey,
3893
3928
  winner.delegatePublicKeyHex,
3894
3929
  winner.delegateAddress
3895
3930
  );
3896
3931
  }
3932
+ if (winner !== null && isValid(winner)) {
3933
+ return rewriteV1ToLocalSigningKey(winner, opts);
3934
+ }
3897
3935
  throw new Error(
3898
3936
  `credentials file at ${credsPath()} appeared during authorization but is unusable - refusing to continue`
3899
3937
  );
@@ -5313,8 +5351,18 @@ async function payStdioWithLocalKey(args) {
5313
5351
  });
5314
5352
  }
5315
5353
  const agentHeld = deps.agentHeld ?? settlementFromLocalSigner(cfg, local, packageId);
5354
+ const grantCeiling = resolved.value.binding.maxPerPayment;
5355
+ const maxAmount = intent.maxAmount !== void 0 ? intent.maxAmount.toString() : grantCeiling != null && grantCeiling !== "" ? grantCeiling : null;
5356
+ if (maxAmount === null) {
5357
+ return error({
5358
+ status: "failed",
5359
+ paid: false,
5360
+ code: "POLICY_REJECTED",
5361
+ detail: "stdio pay requires maxAmount or a grant maxPerPayment; refusing to default the ceiling to the offer"
5362
+ });
5363
+ }
5316
5364
  const spendIntent = {
5317
- maxAmount: intent.maxAmount !== void 0 ? intent.maxAmount.toString() : resolved.value.binding.maxPerPayment ?? result.signingRequest.amount,
5365
+ maxAmount,
5318
5366
  asset: resolved.value.binding.coinType,
5319
5367
  ...intent.recipient ? { recipient: intent.recipient } : {}
5320
5368
  };
@@ -2,7 +2,7 @@ import {
2
2
  createServer,
3
3
  loadMcpConfig,
4
4
  loadPaymentProfile
5
- } from "./chunk-XZQOOY66.js";
5
+ } from "./chunk-26NKQ37M.js";
6
6
 
7
7
  // src/index.ts
8
8
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
package/dist/http.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  handleSuipayMcpHttpRequest
3
- } from "./chunk-XZQOOY66.js";
3
+ } from "./chunk-26NKQ37M.js";
4
4
  import "./chunk-A3JIIDYT.js";
5
5
  export {
6
6
  handleSuipayMcpHttpRequest
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  loadBootProfile,
3
3
  main
4
- } from "./chunk-TPW6S2K4.js";
4
+ } from "./chunk-EM7PKWVL.js";
5
5
  import {
6
6
  PACKAGE_NAME,
7
7
  TOOLS,
@@ -20,7 +20,7 @@ import {
20
20
  settlePreparedMcpPayment,
21
21
  traceMcpHttpRequest,
22
22
  verifySpendAccountPayReconstructs
23
- } from "./chunk-XZQOOY66.js";
23
+ } from "./chunk-26NKQ37M.js";
24
24
  import "./chunk-A3JIIDYT.js";
25
25
  export {
26
26
  PACKAGE_NAME,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmdoss/suipay-mcp",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
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",
@@ -34,12 +34,12 @@
34
34
  "@modelcontextprotocol/sdk": "^1.29.0",
35
35
  "@mysten/sui": "2.24.0",
36
36
  "@noble/ed25519": "^2.1.0",
37
- "@noble/hashes": "^1.4.0",
37
+ "@noble/hashes": "^2.3.0",
38
38
  "open": "^11.0.0"
39
39
  },
40
40
  "devDependencies": {
41
41
  "tsup": "^8.0.0",
42
- "typescript": "^5.9.0",
42
+ "typescript": "^6.0.3",
43
43
  "vitest": "^3.0.0"
44
44
  }
45
45
  }