@toon-protocol/client-mcp 0.5.2 → 0.6.0
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/app/index.html +49 -49
- package/dist/{chunk-R75M6TK6.js → chunk-TDXKG3EI.js} +140 -23
- package/dist/chunk-TDXKG3EI.js.map +1 -0
- package/dist/{chunk-WLOJHGH2.js → chunk-V2SV6C3U.js} +7 -7
- package/dist/chunk-V2SV6C3U.js.map +1 -0
- package/dist/{chunk-APL3TRE6.js → chunk-XBD4J7XA.js} +29 -14
- package/dist/chunk-XBD4J7XA.js.map +1 -0
- package/dist/daemon.js +2 -2
- package/dist/e2e/run-journey.js +1 -1
- package/dist/e2e/run-journey.js.map +1 -1
- package/dist/index.d.ts +37 -8
- package/dist/index.js +3 -3
- package/dist/mcp.js +2 -2
- package/package.json +4 -3
- package/dist/chunk-APL3TRE6.js.map +0 -1
- package/dist/chunk-R75M6TK6.js.map +0 -1
- package/dist/chunk-WLOJHGH2.js.map +0 -1
|
@@ -6956,13 +6956,49 @@ function decodeUtf8(bytes) {
|
|
|
6956
6956
|
function isBase64(str) {
|
|
6957
6957
|
return /^[A-Za-z0-9+/]*={0,2}$/.test(str);
|
|
6958
6958
|
}
|
|
6959
|
-
var
|
|
6959
|
+
var DEFAULT_REQUEST_TARGET = "/write";
|
|
6960
6960
|
var HEADERS = ["Host: relay", "Content-Type: application/json"];
|
|
6961
|
-
function buildStoreWriteEnvelope(event) {
|
|
6961
|
+
function buildStoreWriteEnvelope(event, requestTarget = DEFAULT_REQUEST_TARGET) {
|
|
6962
6962
|
const body = JSON.stringify({ event });
|
|
6963
|
-
const head = [
|
|
6963
|
+
const head = [`POST ${requestTarget} HTTP/1.1`, ...HEADERS].join("\r\n");
|
|
6964
6964
|
return encodeUtf8(head + "\r\n\r\n" + body);
|
|
6965
6965
|
}
|
|
6966
|
+
var CRLF = "\r\n";
|
|
6967
|
+
function findHeaderEnd(bytes) {
|
|
6968
|
+
for (let i = 0; i + 3 < bytes.length; i++) {
|
|
6969
|
+
if (bytes[i] === 13 && bytes[i + 1] === 10 && bytes[i + 2] === 13 && bytes[i + 3] === 10) {
|
|
6970
|
+
return i + 4;
|
|
6971
|
+
}
|
|
6972
|
+
}
|
|
6973
|
+
return -1;
|
|
6974
|
+
}
|
|
6975
|
+
function parseFulfillHttpBytes(bytes) {
|
|
6976
|
+
const notHttp = {
|
|
6977
|
+
isHttp: false,
|
|
6978
|
+
status: 0,
|
|
6979
|
+
statusText: "",
|
|
6980
|
+
body: ""
|
|
6981
|
+
};
|
|
6982
|
+
const headerEnd = findHeaderEnd(bytes);
|
|
6983
|
+
const headBytes = headerEnd === -1 ? bytes : bytes.subarray(0, headerEnd - 2);
|
|
6984
|
+
const bodyBytes = headerEnd === -1 ? new Uint8Array(0) : bytes.subarray(headerEnd);
|
|
6985
|
+
const headText = decodeUtf8(headBytes);
|
|
6986
|
+
const lines = headText.split(CRLF).filter((l) => l.length > 0);
|
|
6987
|
+
const statusLine = lines.shift();
|
|
6988
|
+
if (!statusLine) return notHttp;
|
|
6989
|
+
if (!statusLine.trimStart().startsWith("HTTP/")) return notHttp;
|
|
6990
|
+
const match = /^HTTP\/\d\.\d\s+(\d{3})(?:\s+(.*))?$/.exec(statusLine.trim());
|
|
6991
|
+
if (!match) return notHttp;
|
|
6992
|
+
return {
|
|
6993
|
+
isHttp: true,
|
|
6994
|
+
status: parseInt(match[1], 10),
|
|
6995
|
+
statusText: match[2] ?? "",
|
|
6996
|
+
body: decodeUtf8(bodyBytes)
|
|
6997
|
+
};
|
|
6998
|
+
}
|
|
6999
|
+
function parseFulfillHttp(base64Data) {
|
|
7000
|
+
return parseFulfillHttpBytes(fromBase64(base64Data));
|
|
7001
|
+
}
|
|
6966
7002
|
async function withRetry(operation, options) {
|
|
6967
7003
|
const {
|
|
6968
7004
|
maxRetries,
|
|
@@ -8719,12 +8755,12 @@ var OnChainChannelClient = class {
|
|
|
8719
8755
|
*/
|
|
8720
8756
|
parseChainId(chain2) {
|
|
8721
8757
|
const parts = chain2.split(":");
|
|
8722
|
-
if (parts.length <
|
|
8758
|
+
if (parts.length < 2) {
|
|
8723
8759
|
throw new Error(
|
|
8724
|
-
`Invalid chain format: "${chain2}". Expected "evm:{network}:{chainId}".`
|
|
8760
|
+
`Invalid chain format: "${chain2}". Expected "evm:{network}:{chainId}" or "evm:{chainId}".`
|
|
8725
8761
|
);
|
|
8726
8762
|
}
|
|
8727
|
-
const chainIdStr = parts[2];
|
|
8763
|
+
const chainIdStr = parts.length >= 3 ? parts[2] : parts[1];
|
|
8728
8764
|
if (!chainIdStr) {
|
|
8729
8765
|
throw new Error(
|
|
8730
8766
|
`Invalid chain format: "${chain2}". Expected "evm:{network}:{chainId}".`
|
|
@@ -9921,7 +9957,9 @@ async function requestBlobStorage(client, secretKey, params) {
|
|
|
9921
9957
|
const result = await client.publishEvent(event, {
|
|
9922
9958
|
destination: params.destination,
|
|
9923
9959
|
claim: params.claim,
|
|
9924
|
-
ilpAmount: params.ilpAmount
|
|
9960
|
+
ilpAmount: params.ilpAmount,
|
|
9961
|
+
// The store/DVM backend serves POST /store (not the relay's /write).
|
|
9962
|
+
proxyPath: "/store"
|
|
9925
9963
|
});
|
|
9926
9964
|
if (!result.success) {
|
|
9927
9965
|
return {
|
|
@@ -9934,15 +9972,17 @@ async function requestBlobStorage(client, secretKey, params) {
|
|
|
9934
9972
|
return {
|
|
9935
9973
|
success: false,
|
|
9936
9974
|
eventId: event.id,
|
|
9937
|
-
error: "FULFILL contained no data; expected
|
|
9975
|
+
error: "FULFILL contained no data; expected an HTTP response with the Arweave tx ID"
|
|
9938
9976
|
};
|
|
9939
9977
|
}
|
|
9940
|
-
|
|
9941
|
-
|
|
9978
|
+
let txId;
|
|
9979
|
+
try {
|
|
9980
|
+
txId = extractArweaveTxId(result.data);
|
|
9981
|
+
} catch (error) {
|
|
9942
9982
|
return {
|
|
9943
9983
|
success: false,
|
|
9944
9984
|
eventId: event.id,
|
|
9945
|
-
error:
|
|
9985
|
+
error: error instanceof Error ? error.message : String(error)
|
|
9946
9986
|
};
|
|
9947
9987
|
}
|
|
9948
9988
|
return {
|
|
@@ -9951,6 +9991,49 @@ async function requestBlobStorage(client, secretKey, params) {
|
|
|
9951
9991
|
eventId: event.id
|
|
9952
9992
|
};
|
|
9953
9993
|
}
|
|
9994
|
+
function extractArweaveTxId(base64Data) {
|
|
9995
|
+
const http2 = parseFulfillHttp(base64Data);
|
|
9996
|
+
if (!http2.isHttp) {
|
|
9997
|
+
const legacy = decodeUtf8(fromBase64(base64Data));
|
|
9998
|
+
if (!ARWEAVE_TX_ID_REGEX.test(legacy)) {
|
|
9999
|
+
throw new Error(
|
|
10000
|
+
`Decoded FULFILL data is not a valid Arweave tx ID: "${legacy}"`
|
|
10001
|
+
);
|
|
10002
|
+
}
|
|
10003
|
+
return legacy;
|
|
10004
|
+
}
|
|
10005
|
+
if (http2.status < 200 || http2.status >= 300) {
|
|
10006
|
+
const detail = http2.body ? ` - ${http2.body}` : "";
|
|
10007
|
+
throw new Error(
|
|
10008
|
+
`Blob upload failed: DVM returned HTTP ${http2.status} ${http2.statusText}`.trimEnd() + detail
|
|
10009
|
+
);
|
|
10010
|
+
}
|
|
10011
|
+
let parsed;
|
|
10012
|
+
try {
|
|
10013
|
+
parsed = JSON.parse(http2.body);
|
|
10014
|
+
} catch {
|
|
10015
|
+
throw new Error(
|
|
10016
|
+
`Blob upload response body was not valid JSON: "${http2.body}"`
|
|
10017
|
+
);
|
|
10018
|
+
}
|
|
10019
|
+
const body = parsed;
|
|
10020
|
+
if (body.accept === false) {
|
|
10021
|
+
const reason = typeof body.error === "string" ? `: ${body.error}` : "";
|
|
10022
|
+
throw new Error(`Blob upload rejected by DVM (accept:false)${reason}`);
|
|
10023
|
+
}
|
|
10024
|
+
if (typeof body.txId === "string" && ARWEAVE_TX_ID_REGEX.test(body.txId)) {
|
|
10025
|
+
return body.txId;
|
|
10026
|
+
}
|
|
10027
|
+
if (typeof body.data === "string" && body.data.length > 0) {
|
|
10028
|
+
const decoded = decodeUtf8(fromBase64(body.data));
|
|
10029
|
+
if (ARWEAVE_TX_ID_REGEX.test(decoded)) {
|
|
10030
|
+
return decoded;
|
|
10031
|
+
}
|
|
10032
|
+
}
|
|
10033
|
+
throw new Error(
|
|
10034
|
+
`Blob upload response did not contain a valid Arweave tx ID: "${http2.body}"`
|
|
10035
|
+
);
|
|
10036
|
+
}
|
|
9954
10037
|
var Http402Client = class {
|
|
9955
10038
|
fetchImpl;
|
|
9956
10039
|
resolveClaim;
|
|
@@ -10123,7 +10206,7 @@ function parseX402Body(body) {
|
|
|
10123
10206
|
}
|
|
10124
10207
|
return version !== void 0 ? { x402Version: version } : {};
|
|
10125
10208
|
}
|
|
10126
|
-
var
|
|
10209
|
+
var CRLF2 = "\r\n";
|
|
10127
10210
|
function concatHeadAndBody(head, body) {
|
|
10128
10211
|
const headBytes = encodeUtf8(head);
|
|
10129
10212
|
const out = new Uint8Array(headBytes.length + body.length);
|
|
@@ -10153,10 +10236,10 @@ function serializeHttpRequest(req) {
|
|
|
10153
10236
|
`${req.method.toUpperCase()} ${target} HTTP/1.1`,
|
|
10154
10237
|
...headers.values()
|
|
10155
10238
|
];
|
|
10156
|
-
const head = lines.join(
|
|
10239
|
+
const head = lines.join(CRLF2) + CRLF2 + CRLF2;
|
|
10157
10240
|
return concatHeadAndBody(head, bodyBytes);
|
|
10158
10241
|
}
|
|
10159
|
-
function
|
|
10242
|
+
function findHeaderEnd2(bytes) {
|
|
10160
10243
|
for (let i = 0; i + 3 < bytes.length; i++) {
|
|
10161
10244
|
if (bytes[i] === 13 && bytes[i + 1] === 10 && bytes[i + 2] === 13 && bytes[i + 3] === 10) {
|
|
10162
10245
|
return i + 4;
|
|
@@ -10165,11 +10248,11 @@ function findHeaderEnd(bytes) {
|
|
|
10165
10248
|
return -1;
|
|
10166
10249
|
}
|
|
10167
10250
|
function parseHttpResponse(bytes) {
|
|
10168
|
-
const headerEnd =
|
|
10251
|
+
const headerEnd = findHeaderEnd2(bytes);
|
|
10169
10252
|
const headBytes = headerEnd === -1 ? bytes : bytes.subarray(0, headerEnd - 2);
|
|
10170
10253
|
const body = headerEnd === -1 ? new Uint8Array(0) : bytes.subarray(headerEnd);
|
|
10171
10254
|
const headText = decodeUtf8(headBytes);
|
|
10172
|
-
const lines = headText.split(
|
|
10255
|
+
const lines = headText.split(CRLF2).filter((l) => l.length > 0);
|
|
10173
10256
|
const statusLine = lines.shift();
|
|
10174
10257
|
if (!statusLine) {
|
|
10175
10258
|
throw new ConnectorError(
|
|
@@ -10376,7 +10459,7 @@ var ToonClient = class {
|
|
|
10376
10459
|
if (result.negotiatedChain && result.settlementAddress) {
|
|
10377
10460
|
const chainType = result.negotiatedChain.split(":")[0] ?? "evm";
|
|
10378
10461
|
const parts = result.negotiatedChain.split(":");
|
|
10379
|
-
const chainId = parts.length >= 3 ? parseInt(parts[2] ?? "0", 10) : 0;
|
|
10462
|
+
const chainId = parts.length >= 3 ? parseInt(parts[2] ?? "0", 10) : parts.length >= 2 ? parseInt(parts[1] ?? "0", 10) : 0;
|
|
10380
10463
|
const r = result;
|
|
10381
10464
|
this.peerNegotiations.set(result.registeredPeerId, {
|
|
10382
10465
|
chain: result.negotiatedChain,
|
|
@@ -10394,7 +10477,7 @@ var ToonClient = class {
|
|
|
10394
10477
|
if (matchedChain) {
|
|
10395
10478
|
const peerAddr = peerInfo.settlementAddresses?.[matchedChain];
|
|
10396
10479
|
const parts = matchedChain.split(":");
|
|
10397
|
-
const chainId = parts.length >= 3 ? parseInt(parts[2] ?? "0", 10) : 0;
|
|
10480
|
+
const chainId = parts.length >= 3 ? parseInt(parts[2] ?? "0", 10) : parts.length >= 2 ? parseInt(parts[1] ?? "0", 10) : 0;
|
|
10398
10481
|
if (peerAddr) {
|
|
10399
10482
|
this.peerNegotiations.set(result.registeredPeerId, {
|
|
10400
10483
|
chain: matchedChain,
|
|
@@ -10479,7 +10562,7 @@ var ToonClient = class {
|
|
|
10479
10562
|
const toonData = this.config.toonEncoder(event);
|
|
10480
10563
|
const basePricePerByte = 10n;
|
|
10481
10564
|
const amount = options?.ilpAmount !== void 0 ? String(options.ilpAmount) : String(BigInt(toonData.length) * basePricePerByte);
|
|
10482
|
-
const writeData = buildStoreWriteEnvelope(event);
|
|
10565
|
+
const writeData = buildStoreWriteEnvelope(event, options?.proxyPath);
|
|
10483
10566
|
const destination = options?.destination ?? this.config.destinationAddress;
|
|
10484
10567
|
const transport = this.getClaimTransport();
|
|
10485
10568
|
let claimMessage;
|
|
@@ -10524,6 +10607,16 @@ var ToonClient = class {
|
|
|
10524
10607
|
error: `Event rejected: ${response.code} - ${response.message}`
|
|
10525
10608
|
};
|
|
10526
10609
|
}
|
|
10610
|
+
if (response.data) {
|
|
10611
|
+
const httpResult = parseFulfillHttp(response.data);
|
|
10612
|
+
if (httpResult.isHttp && (httpResult.status < 200 || httpResult.status >= 300)) {
|
|
10613
|
+
const detail = httpResult.body ? ` - ${httpResult.body}` : "";
|
|
10614
|
+
return {
|
|
10615
|
+
success: false,
|
|
10616
|
+
error: `Write failed: relay returned HTTP ${httpResult.status} ${httpResult.statusText}`.trimEnd() + detail
|
|
10617
|
+
};
|
|
10618
|
+
}
|
|
10619
|
+
}
|
|
10527
10620
|
return {
|
|
10528
10621
|
success: true,
|
|
10529
10622
|
eventId: event.id,
|
|
@@ -10841,7 +10934,7 @@ var ToonClient = class {
|
|
|
10841
10934
|
getChainContext(negotiatedChain) {
|
|
10842
10935
|
if (!negotiatedChain) return void 0;
|
|
10843
10936
|
const parts = negotiatedChain.split(":");
|
|
10844
|
-
const chainIdPart = parts.length >= 3 ? parts[2] : void 0;
|
|
10937
|
+
const chainIdPart = parts.length >= 3 ? parts[2] : parts.length >= 2 ? parts[1] : void 0;
|
|
10845
10938
|
const numericChainId = chainIdPart !== void 0 ? parseInt(chainIdPart, 10) : NaN;
|
|
10846
10939
|
if (isNaN(numericChainId)) return void 0;
|
|
10847
10940
|
const tokenNetworkAddress = this.config.tokenNetworks?.[negotiatedChain];
|
|
@@ -11611,6 +11704,18 @@ function buildIlpPrepare(params) {
|
|
|
11611
11704
|
};
|
|
11612
11705
|
}
|
|
11613
11706
|
|
|
11707
|
+
// ../arweave/dist/gateways.js
|
|
11708
|
+
var ARWEAVE_GATEWAYS = [
|
|
11709
|
+
"https://ar-io.dev",
|
|
11710
|
+
"https://arweave.net",
|
|
11711
|
+
"https://permagate.io"
|
|
11712
|
+
];
|
|
11713
|
+
function arweaveUrls(txId, gateways = ARWEAVE_GATEWAYS) {
|
|
11714
|
+
const all = (gateways.length ? gateways : ARWEAVE_GATEWAYS).map((g) => `${g}/${txId}`);
|
|
11715
|
+
const [url, ...fallbacks] = all;
|
|
11716
|
+
return { url: url ?? `${ARWEAVE_GATEWAYS[0]}/${txId}`, fallbacks };
|
|
11717
|
+
}
|
|
11718
|
+
|
|
11614
11719
|
// src/daemon/config.ts
|
|
11615
11720
|
var DEFAULT_KEYSTORE_PASSWORD = "toon-client-default";
|
|
11616
11721
|
function configDir() {
|
|
@@ -11646,6 +11751,11 @@ function resolveMnemonic(file) {
|
|
|
11646
11751
|
"No mnemonic configured. Set TOON_CLIENT_MNEMONIC, configure a keystorePath (+ TOON_CLIENT_KEYSTORE_PASSWORD), or add `mnemonic` to the config file."
|
|
11647
11752
|
);
|
|
11648
11753
|
}
|
|
11754
|
+
function parseCsvEnv(value) {
|
|
11755
|
+
if (!value) return void 0;
|
|
11756
|
+
const items = value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
11757
|
+
return items.length ? items : void 0;
|
|
11758
|
+
}
|
|
11649
11759
|
function resolveConfig(file) {
|
|
11650
11760
|
const mnemonic = resolveMnemonic(file);
|
|
11651
11761
|
const proxyUrl = process.env["TOON_CLIENT_PROXY_URL"] ?? file.proxyUrl;
|
|
@@ -11657,7 +11767,10 @@ function resolveConfig(file) {
|
|
|
11657
11767
|
process.env["TOON_CLIENT_HTTP_PORT"] ?? file.httpPort ?? 8787
|
|
11658
11768
|
);
|
|
11659
11769
|
const destination = process.env["TOON_CLIENT_DESTINATION"] ?? file.destination ?? "g.townhouse.town";
|
|
11770
|
+
const publishDestination = process.env["TOON_CLIENT_PUBLISH_DESTINATION"] ?? file.publishDestination ?? destination;
|
|
11771
|
+
const storeDestination = process.env["TOON_CLIENT_STORE_DESTINATION"] ?? file.storeDestination ?? destination;
|
|
11660
11772
|
const feePerEvent = BigInt(file.feePerEvent ?? "1");
|
|
11773
|
+
const arweaveGateways = parseCsvEnv(process.env["TOON_CLIENT_ARWEAVE_GATEWAYS"]) ?? file.arweaveGateways ?? [...ARWEAVE_GATEWAYS];
|
|
11661
11774
|
const network = process.env["TOON_CLIENT_NETWORK"] ?? file.network;
|
|
11662
11775
|
const chain2 = process.env["TOON_CLIENT_CHAIN"] ?? file.chain ?? "evm";
|
|
11663
11776
|
const apex = file.apexChains?.[chain2] ?? file.apex ?? buildProxyApexNegotiation(file, chain2, destination);
|
|
@@ -11703,13 +11816,16 @@ function resolveConfig(file) {
|
|
|
11703
11816
|
...proxyUrl ? { proxyUrl } : {},
|
|
11704
11817
|
...faucetUrl ? { faucetUrl } : {},
|
|
11705
11818
|
destination,
|
|
11819
|
+
publishDestination,
|
|
11820
|
+
storeDestination,
|
|
11706
11821
|
feePerEvent,
|
|
11707
11822
|
...apex ? { apex } : {},
|
|
11708
11823
|
...file.apexChildPeers ? { apexChildPeers: file.apexChildPeers } : {},
|
|
11709
11824
|
chain: chain2,
|
|
11710
11825
|
apexChannelStorePath,
|
|
11711
11826
|
toonClientConfig,
|
|
11712
|
-
network
|
|
11827
|
+
network,
|
|
11828
|
+
arweaveGateways
|
|
11713
11829
|
};
|
|
11714
11830
|
}
|
|
11715
11831
|
function defaultChainKey(chain2, chainId) {
|
|
@@ -11732,7 +11848,7 @@ function buildProxyApexNegotiation(file, chain2, destination) {
|
|
|
11732
11848
|
const settlementAddress = settlementAddresses[chainKey];
|
|
11733
11849
|
if (!settlementAddress) return void 0;
|
|
11734
11850
|
const parts = chainKey.split(":");
|
|
11735
|
-
const chainId = chain2 === "evm" && parts.length >=
|
|
11851
|
+
const chainId = chain2 === "evm" && parts.length >= 2 ? Number(parts[2] ?? parts[1] ?? 0) : 0;
|
|
11736
11852
|
const peerId = destination.split(".").at(-1) ?? destination;
|
|
11737
11853
|
return {
|
|
11738
11854
|
destination,
|
|
@@ -11989,6 +12105,7 @@ export {
|
|
|
11989
12105
|
parseIlpPeerInfo2 as parseIlpPeerInfo,
|
|
11990
12106
|
isEventExpired,
|
|
11991
12107
|
buildIlpPrepare,
|
|
12108
|
+
arweaveUrls,
|
|
11992
12109
|
DEFAULT_KEYSTORE_PASSWORD,
|
|
11993
12110
|
configDir,
|
|
11994
12111
|
defaultConfigPath,
|
|
@@ -12025,4 +12142,4 @@ export {
|
|
|
12025
12142
|
@scure/bip32/lib/esm/index.js:
|
|
12026
12143
|
(*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) *)
|
|
12027
12144
|
*/
|
|
12028
|
-
//# sourceMappingURL=chunk-
|
|
12145
|
+
//# sourceMappingURL=chunk-TDXKG3EI.js.map
|