@cmdoss/suipay-mcp 0.2.2-dev.17 → 0.2.2-dev.19
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,7 +5,7 @@ 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.
|
|
8
|
+
Pin `@cmdoss/suipay-mcp@0.2.2-dev.19` in MCP config for the `latest` dist-tag.
|
|
9
9
|
`npx -y @cmdoss/suipay-mcp@dev` tracks the `dev` prerelease line.
|
|
10
10
|
`1.0.1` remains on the registry as a historical release; do not install it
|
|
11
11
|
for new agents.
|
|
@@ -13,7 +13,7 @@ for new agents.
|
|
|
13
13
|
## Install
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
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.19
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
`@dev` installs the Railway-dev gateway/console defaults. A workspace
|
|
@@ -118,10 +118,10 @@ Default is Railway **suipay-dev**. `--local` / `target: "local"` is laptop-only.
|
|
|
118
118
|
|
|
119
119
|
```bash
|
|
120
120
|
# Railway suipay-dev (default)
|
|
121
|
-
npx @cmdoss/suipay-mcp@0.2.2-dev.
|
|
121
|
+
npx @cmdoss/suipay-mcp@0.2.2-dev.19
|
|
122
122
|
|
|
123
123
|
# Laptop stack
|
|
124
|
-
npx @cmdoss/suipay-mcp@0.2.2-dev.
|
|
124
|
+
npx @cmdoss/suipay-mcp@0.2.2-dev.19 --local
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
`SUIPAY_MCP_TARGET=local|dev` selects the same preset. Explicit
|
package/dist/bin/suipay.js
CHANGED
|
@@ -1812,6 +1812,33 @@ function decodeSponsorGasPayment(encoded) {
|
|
|
1812
1812
|
return { objectId: bits[0], version: bits[1], digest: bits[2] };
|
|
1813
1813
|
});
|
|
1814
1814
|
}
|
|
1815
|
+
var SPONSOR_GAS_ADDRESS_BALANCE = "address-balance";
|
|
1816
|
+
function decodeSponsorGasPin(encoded) {
|
|
1817
|
+
if (encoded === SPONSOR_GAS_ADDRESS_BALANCE)
|
|
1818
|
+
return [];
|
|
1819
|
+
return decodeSponsorGasPayment(encoded);
|
|
1820
|
+
}
|
|
1821
|
+
var ADDRESS_BALANCE_VALIDITY_EPOCHS = 1n;
|
|
1822
|
+
function addressBalanceGasExpiration(input) {
|
|
1823
|
+
const chain = input.chainIdentifier.trim();
|
|
1824
|
+
if (!chain)
|
|
1825
|
+
throw new Error("address-balance gas needs a chain identifier");
|
|
1826
|
+
if (input.epoch < 0n)
|
|
1827
|
+
throw new Error("address-balance gas needs a non-negative epoch");
|
|
1828
|
+
if (!Number.isInteger(input.nonce) || input.nonce < 0 || input.nonce > 4294967295) {
|
|
1829
|
+
throw new Error("address-balance gas nonce must be a u32");
|
|
1830
|
+
}
|
|
1831
|
+
return {
|
|
1832
|
+
ValidDuring: {
|
|
1833
|
+
minEpoch: String(input.epoch),
|
|
1834
|
+
maxEpoch: String(input.epoch + ADDRESS_BALANCE_VALIDITY_EPOCHS),
|
|
1835
|
+
minTimestamp: null,
|
|
1836
|
+
maxTimestamp: null,
|
|
1837
|
+
chain,
|
|
1838
|
+
nonce: input.nonce
|
|
1839
|
+
}
|
|
1840
|
+
};
|
|
1841
|
+
}
|
|
1815
1842
|
|
|
1816
1843
|
// ../sdk/dist/protocol/mpp.js
|
|
1817
1844
|
function offerToBase64Url(offer) {
|
|
@@ -4125,7 +4152,7 @@ function readX402GasPin(offer) {
|
|
|
4125
4152
|
owner,
|
|
4126
4153
|
budget,
|
|
4127
4154
|
price,
|
|
4128
|
-
payment:
|
|
4155
|
+
payment: decodeSponsorGasPin(offer.sponsorGasPayment ?? "")
|
|
4129
4156
|
};
|
|
4130
4157
|
} catch {
|
|
4131
4158
|
return null;
|
|
@@ -4139,16 +4166,33 @@ async function buildSpendAccountX402PayTx(input) {
|
|
|
4139
4166
|
tx.setGasBudget(input.gas.budget);
|
|
4140
4167
|
tx.setGasPrice(input.gas.price);
|
|
4141
4168
|
tx.setGasPayment(input.gas.payment);
|
|
4142
|
-
|
|
4169
|
+
if (input.gas.payment.length === 0) {
|
|
4170
|
+
if (!input.chainIdentifier) {
|
|
4171
|
+
throw new Error("address-balance sponsor gas needs a chain identifier");
|
|
4172
|
+
}
|
|
4173
|
+
tx.setExpiration(addressBalanceGasExpiration({
|
|
4174
|
+
epoch: input.currentEpoch,
|
|
4175
|
+
chainIdentifier: input.chainIdentifier,
|
|
4176
|
+
nonce: input.nonce ?? randomU32()
|
|
4177
|
+
}));
|
|
4178
|
+
} else {
|
|
4179
|
+
tx.setExpiration({ Epoch: String(input.currentEpoch + X402_EXPIRATION_EPOCHS) });
|
|
4180
|
+
}
|
|
4143
4181
|
const txBytes = toBase645(await tx.build());
|
|
4144
4182
|
return { txBytes, kindBytes };
|
|
4145
4183
|
}
|
|
4184
|
+
function randomU32() {
|
|
4185
|
+
return globalThis.crypto.getRandomValues(new Uint32Array(1))[0];
|
|
4186
|
+
}
|
|
4146
4187
|
function currentEpochReader(client) {
|
|
4147
4188
|
return async () => {
|
|
4148
4189
|
const { systemState } = await client.core.getCurrentSystemState();
|
|
4149
4190
|
return BigInt(systemState.epoch);
|
|
4150
4191
|
};
|
|
4151
4192
|
}
|
|
4193
|
+
function chainIdentifierReader(client) {
|
|
4194
|
+
return async () => (await client.core.getChainIdentifier()).chainIdentifier;
|
|
4195
|
+
}
|
|
4152
4196
|
function assertPayTransaction(txBytes, expected) {
|
|
4153
4197
|
let data;
|
|
4154
4198
|
try {
|
|
@@ -4609,6 +4653,10 @@ async function payDelegatedSpendAccount(args) {
|
|
|
4609
4653
|
return { status: "ok", paid: false, body: resolution.body };
|
|
4610
4654
|
}
|
|
4611
4655
|
if (resolution.status === "failed") {
|
|
4656
|
+
logInternal(logError, "resolve payment failed", {
|
|
4657
|
+
code: resolution.code,
|
|
4658
|
+
detail: resolution.detail
|
|
4659
|
+
});
|
|
4612
4660
|
const mapped = mapPayOpErrorToDelegated(resolution.code, resolution.detail);
|
|
4613
4661
|
return failed2(mapped.code, mapped.detail, {
|
|
4614
4662
|
paymentId: resolution.paymentId
|
|
@@ -4733,7 +4781,8 @@ async function payDelegatedSpendAccount(args) {
|
|
|
4733
4781
|
buildInput: {
|
|
4734
4782
|
...kindBuildInput,
|
|
4735
4783
|
gas: x402Terms.gas,
|
|
4736
|
-
currentEpoch: x402Terms.currentEpoch
|
|
4784
|
+
currentEpoch: x402Terms.currentEpoch,
|
|
4785
|
+
...x402Terms.chainIdentifier !== void 0 ? { chainIdentifier: x402Terms.chainIdentifier } : {}
|
|
4737
4786
|
},
|
|
4738
4787
|
settlement: {
|
|
4739
4788
|
status: "success",
|
|
@@ -5110,12 +5159,28 @@ async function x402Preflight(dialect, offer, deps, logError) {
|
|
|
5110
5159
|
logInternal(logError, "x402 needs a current-epoch reader");
|
|
5111
5160
|
return null;
|
|
5112
5161
|
}
|
|
5162
|
+
let currentEpoch;
|
|
5113
5163
|
try {
|
|
5114
|
-
|
|
5164
|
+
currentEpoch = BigInt(await deps.getCurrentEpoch());
|
|
5115
5165
|
} catch (err) {
|
|
5116
5166
|
logInternal(logError, "read current epoch failed", err);
|
|
5117
5167
|
return null;
|
|
5118
5168
|
}
|
|
5169
|
+
if (gas.payment.length > 0)
|
|
5170
|
+
return { gas, currentEpoch };
|
|
5171
|
+
if (typeof deps.getChainIdentifier !== "function") {
|
|
5172
|
+
logInternal(logError, "address-balance x402 gas needs a chain-identifier reader");
|
|
5173
|
+
return null;
|
|
5174
|
+
}
|
|
5175
|
+
try {
|
|
5176
|
+
const chainIdentifier = await deps.getChainIdentifier();
|
|
5177
|
+
if (!chainIdentifier.trim())
|
|
5178
|
+
throw new Error("chain identifier is blank");
|
|
5179
|
+
return { gas, currentEpoch, chainIdentifier };
|
|
5180
|
+
} catch (err) {
|
|
5181
|
+
logInternal(logError, "read chain identifier failed", err);
|
|
5182
|
+
return null;
|
|
5183
|
+
}
|
|
5119
5184
|
}
|
|
5120
5185
|
function emitX402Progress(ctx, event) {
|
|
5121
5186
|
if (!ctx.onProgress)
|
|
@@ -7422,6 +7487,8 @@ async function createPayer(options) {
|
|
|
7422
7487
|
// x402 bounds the transaction's expiration by the current epoch, read from
|
|
7423
7488
|
// the same client as every other chain read here.
|
|
7424
7489
|
getCurrentEpoch: currentEpochReader(chain.client),
|
|
7490
|
+
// Address-balance gas (ADR-0055) binds the expiration to the chain.
|
|
7491
|
+
getChainIdentifier: chainIdentifierReader(chain.client),
|
|
7425
7492
|
...options.offerSecret ? { offerSecret: options.offerSecret } : {},
|
|
7426
7493
|
...options.fetchImpl ? { fetchImpl: options.fetchImpl } : {},
|
|
7427
7494
|
...options.logError ? { logError: options.logError } : {}
|
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-IBRMIXCG.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-6VFKI2BY.js";
|
|
30
30
|
export {
|
|
31
31
|
MCP_TARGET_PRESETS,
|
|
32
32
|
PACKAGE_NAME,
|
package/package.json
CHANGED