@toon-protocol/client-mcp 0.18.0 → 0.19.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/README.md +5 -7
- package/dist/{chunk-56TTQYS7.js → chunk-3PGURFAM.js} +2 -2
- package/dist/{chunk-FXPDLGDN.js → chunk-ITONR5ML.js} +124 -28
- package/dist/chunk-ITONR5ML.js.map +1 -0
- package/dist/{chunk-LSPAGZXL.js → chunk-OGMD7Z2F.js} +409 -33
- package/dist/chunk-OGMD7Z2F.js.map +1 -0
- package/dist/daemon.js +2 -2
- package/dist/index.d.ts +11 -8
- package/dist/index.js +3 -3
- package/dist/mcp.js +2 -2
- package/package.json +5 -5
- package/dist/chunk-FXPDLGDN.js.map +0 -1
- package/dist/chunk-LSPAGZXL.js.map +0 -1
- /package/dist/{chunk-56TTQYS7.js.map → chunk-3PGURFAM.js.map} +0 -0
package/README.md
CHANGED
|
@@ -288,11 +288,11 @@ The integration suite lives in `src/__integration__/`.
|
|
|
288
288
|
|
|
289
289
|
## Publishing
|
|
290
290
|
|
|
291
|
-
This package is **published to npm automatically by CI/CD
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
291
|
+
This package is **published to npm automatically by CI/CD** via
|
|
292
|
+
[changesets](https://github.com/changesets/changesets): `.github/workflows/release.yml`
|
|
293
|
+
runs `pnpm changeset publish` on every push to `main`, using the org `NPM_TOKEN`
|
|
294
|
+
secret. It ships whenever a changeset targeting it lands — independently of any
|
|
295
|
+
other repo's release cadence. Never run `npm publish` manually.
|
|
296
296
|
|
|
297
297
|
It is **self-contained**: its `@toon-protocol/*` workspace deps (`client`, `core`)
|
|
298
298
|
are **bundled into `dist`** at build time (tsup `noExternal`), so the published
|
|
@@ -302,5 +302,3 @@ packages (`fastify`, `@modelcontextprotocol/sdk`, `nostr-tools`, `viem`, `ws`,
|
|
|
302
302
|
`@solana/web3.js`) installed only when you use those chains.
|
|
303
303
|
A guard test (`src/package-structure.test.ts`) fails the build if a
|
|
304
304
|
`@toon-protocol/*` runtime dep ever leaks in.
|
|
305
|
-
|
|
306
|
-
To publish manually: `pnpm --filter @toon-protocol/client-mcp build && pnpm --filter @toon-protocol/client-mcp publish --access public`.
|
|
@@ -2,7 +2,7 @@ import { createRequire as __cr } from 'module'; const require = __cr(import.meta
|
|
|
2
2
|
import {
|
|
3
3
|
ControlApiError,
|
|
4
4
|
DaemonUnreachableError
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-OGMD7Z2F.js";
|
|
6
6
|
|
|
7
7
|
// ../views/dist/tool-names.js
|
|
8
8
|
var PUBLISH_TOOL = "toon_publish_unsigned";
|
|
@@ -1870,4 +1870,4 @@ export {
|
|
|
1870
1870
|
TOOL_DEFINITIONS,
|
|
1871
1871
|
dispatchTool
|
|
1872
1872
|
};
|
|
1873
|
-
//# sourceMappingURL=chunk-
|
|
1873
|
+
//# sourceMappingURL=chunk-3PGURFAM.js.map
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
AdaptiveDeltaController,
|
|
4
4
|
DEFAULT_KEYSTORE_PASSWORD,
|
|
5
5
|
ILP_PEER_INFO_KIND,
|
|
6
|
+
InMemoryPreimageRetentionStore,
|
|
6
7
|
InMemoryReceivedClaimStore,
|
|
7
8
|
JsonFileReceivedClaimStore,
|
|
8
9
|
JsonFileSwapControllerStateStore,
|
|
@@ -15,14 +16,14 @@ import {
|
|
|
15
16
|
extractArweaveTxId,
|
|
16
17
|
fundWallet,
|
|
17
18
|
generateKeystore,
|
|
18
|
-
|
|
19
|
+
ingestAndReveal,
|
|
19
20
|
isEventExpired,
|
|
20
21
|
loadMinaSignerClient,
|
|
21
22
|
mintExecutionCondition,
|
|
22
23
|
parseIlpPeerInfo,
|
|
23
24
|
readConfigFile,
|
|
24
25
|
streamSwap
|
|
25
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-OGMD7Z2F.js";
|
|
26
27
|
|
|
27
28
|
// src/daemon/first-run.ts
|
|
28
29
|
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
@@ -835,7 +836,7 @@ async function fetchRemoteState(options) {
|
|
|
835
836
|
};
|
|
836
837
|
}
|
|
837
838
|
|
|
838
|
-
// ../rig/dist/chunk-
|
|
839
|
+
// ../rig/dist/chunk-PG5PUKDR.js
|
|
839
840
|
import { execFile, spawn } from "child_process";
|
|
840
841
|
import { promisify } from "util";
|
|
841
842
|
import { execFile as execFile2, spawn as spawn2 } from "child_process";
|
|
@@ -1033,6 +1034,42 @@ var GitRepoReader = class {
|
|
|
1033
1034
|
}
|
|
1034
1035
|
return objects;
|
|
1035
1036
|
}
|
|
1037
|
+
/**
|
|
1038
|
+
* List every blob (file) reachable from a ref's root tree, recursively,
|
|
1039
|
+
* with the path it is served at (#368: the ar.io site manifest join key).
|
|
1040
|
+
* Uses `git ls-tree -r -z` — NUL-terminated records so binary/spaced paths
|
|
1041
|
+
* survive verbatim, and no path quoting to undo. Submodule (`commit`)
|
|
1042
|
+
* gitlink entries and directories are excluded; only real file blobs remain.
|
|
1043
|
+
*/
|
|
1044
|
+
async listBlobs(rev) {
|
|
1045
|
+
assertRevision(rev, "ref");
|
|
1046
|
+
const { stdout } = await this.git(["ls-tree", "-r", "-z", rev, "--"]);
|
|
1047
|
+
const blobs = [];
|
|
1048
|
+
for (const record of stdout.split("\0")) {
|
|
1049
|
+
if (!record) continue;
|
|
1050
|
+
const tab = record.indexOf(" ");
|
|
1051
|
+
if (tab === -1) {
|
|
1052
|
+
throw new GitError(
|
|
1053
|
+
`unexpected ls-tree record: ${JSON.stringify(record)}`,
|
|
1054
|
+
void 0,
|
|
1055
|
+
""
|
|
1056
|
+
);
|
|
1057
|
+
}
|
|
1058
|
+
const meta = record.slice(0, tab);
|
|
1059
|
+
const path = record.slice(tab + 1);
|
|
1060
|
+
const [, type, sha] = meta.split(" ");
|
|
1061
|
+
if (type !== "blob") continue;
|
|
1062
|
+
if (!sha || !FULL_SHA_RE.test(sha)) {
|
|
1063
|
+
throw new GitError(
|
|
1064
|
+
`unexpected ls-tree object id: ${JSON.stringify(record)}`,
|
|
1065
|
+
void 0,
|
|
1066
|
+
""
|
|
1067
|
+
);
|
|
1068
|
+
}
|
|
1069
|
+
blobs.push({ path, sha });
|
|
1070
|
+
}
|
|
1071
|
+
return blobs;
|
|
1072
|
+
}
|
|
1036
1073
|
/** Run git feeding `input` on stdin; resolves collected stdout bytes. */
|
|
1037
1074
|
runWithStdin(args, input) {
|
|
1038
1075
|
return new Promise((resolve2, reject) => {
|
|
@@ -1432,7 +1469,10 @@ async function executePush(options) {
|
|
|
1432
1469
|
sha: object.sha,
|
|
1433
1470
|
type: object.type,
|
|
1434
1471
|
body,
|
|
1435
|
-
repoId: plan.repoId
|
|
1472
|
+
repoId: plan.repoId,
|
|
1473
|
+
// #368: the path the blob was reached by drives its Content-Type; a
|
|
1474
|
+
// non-blob object (no path) uploads as octet-stream.
|
|
1475
|
+
...object.path ? { path: object.path } : {}
|
|
1436
1476
|
});
|
|
1437
1477
|
merged.set(object.sha, receipt.txId);
|
|
1438
1478
|
totalFeePaid += receipt.feePaid;
|
|
@@ -2695,7 +2735,8 @@ var ClientRunner = class {
|
|
|
2695
2735
|
}
|
|
2696
2736
|
};
|
|
2697
2737
|
const senderSecretKey = generateSecretKey();
|
|
2698
|
-
const
|
|
2738
|
+
const preimages = new InMemoryPreimageRetentionStore();
|
|
2739
|
+
const swapClient = req.senderConditions ? this.withSenderConditions(apex.client, preimages) : apex.client;
|
|
2699
2740
|
const result = await streamSwap({
|
|
2700
2741
|
client: swapClient,
|
|
2701
2742
|
swapPubkey: req.swapPubkey,
|
|
@@ -2714,15 +2755,19 @@ var ClientRunner = class {
|
|
|
2714
2755
|
const firstReject = result.rejections[0];
|
|
2715
2756
|
const expectedChain = req.pair.to.chain;
|
|
2716
2757
|
const minaSignerClient = expectedChain.startsWith("mina") ? await loadMinaSignerClient() : void 0;
|
|
2717
|
-
const
|
|
2758
|
+
const reveal = () => ({ decision: "revealed" });
|
|
2759
|
+
const ingest = await ingestAndReveal({
|
|
2718
2760
|
claims: result.claims,
|
|
2719
2761
|
expectedChain,
|
|
2720
2762
|
chainRecipient: req.chainRecipient,
|
|
2721
2763
|
...req.swapSignerAddress ? { expectedSignerAddress: req.swapSignerAddress } : {},
|
|
2722
2764
|
store: this.receivedClaimStore,
|
|
2723
|
-
...minaSignerClient ? { minaSignerClient } : {}
|
|
2765
|
+
...minaSignerClient ? { minaSignerClient } : {},
|
|
2766
|
+
preimages,
|
|
2767
|
+
reveal
|
|
2724
2768
|
});
|
|
2725
|
-
|
|
2769
|
+
preimages.clear();
|
|
2770
|
+
const verifiedSet = new Set(ingest.revealed.map((v) => v.claim));
|
|
2726
2771
|
const rejectionByClaim = new Map(
|
|
2727
2772
|
ingest.rejected.map((r) => [r.claim, r])
|
|
2728
2773
|
);
|
|
@@ -2776,12 +2821,13 @@ var ClientRunner = class {
|
|
|
2776
2821
|
`${ingest.rejected.length} received claim(s) FAILED verification and were NOT counted as value received (first: ${firstRejected.code} \u2014 ${firstRejected.message}). See per-claim verificationError.`
|
|
2777
2822
|
);
|
|
2778
2823
|
}
|
|
2779
|
-
const hadIngestibleClaims = ingest.
|
|
2824
|
+
const hadIngestibleClaims = ingest.revealed.length + ingest.rejected.length > 0;
|
|
2780
2825
|
return {
|
|
2781
|
-
// A swap only counts as accepted when it yielded a VERIFIED
|
|
2782
|
-
// legacy no-metadata claim, whose path is unchanged).
|
|
2783
|
-
// whose claims all failed verification are a failed
|
|
2784
|
-
|
|
2826
|
+
// A swap only counts as accepted when it yielded a VERIFIED+REVEALED
|
|
2827
|
+
// claim (or a legacy no-metadata claim, whose path is unchanged).
|
|
2828
|
+
// FULFILLed packets whose claims all failed verification are a failed
|
|
2829
|
+
// swap, loudly.
|
|
2830
|
+
accepted: ingest.revealed.length + ingest.legacy.length > 0,
|
|
2785
2831
|
packetsAccepted: result.claims.length,
|
|
2786
2832
|
claims,
|
|
2787
2833
|
cumulativeSource: result.cumulativeSource.toString(),
|
|
@@ -2803,9 +2849,9 @@ var ClientRunner = class {
|
|
|
2803
2849
|
...firstReject ? { code: firstReject.code, message: firstReject.message } : {},
|
|
2804
2850
|
...warnings.length > 0 ? { warning: warnings.join("\n") } : {},
|
|
2805
2851
|
...hadIngestibleClaims ? {
|
|
2806
|
-
claimsVerified: ingest.
|
|
2852
|
+
claimsVerified: ingest.revealed.length,
|
|
2807
2853
|
claimsRejected: ingest.rejected.length,
|
|
2808
|
-
valueReceived: ingest.
|
|
2854
|
+
valueReceived: ingest.valueRevealed.toString()
|
|
2809
2855
|
} : {}
|
|
2810
2856
|
};
|
|
2811
2857
|
}
|
|
@@ -2883,16 +2929,56 @@ var ClientRunner = class {
|
|
|
2883
2929
|
results.push(base);
|
|
2884
2930
|
continue;
|
|
2885
2931
|
}
|
|
2886
|
-
if (bundle.chainKind
|
|
2932
|
+
if (bundle.chainKind === "solana") {
|
|
2887
2933
|
results.push({
|
|
2888
2934
|
...base,
|
|
2889
2935
|
error: {
|
|
2890
2936
|
code: "SUBMISSION_UNSUPPORTED",
|
|
2891
|
-
message:
|
|
2937
|
+
message: "Solana settlement submission is not wired yet (bundle carries a serialized Message; follow-up under toon-meta#145)."
|
|
2892
2938
|
}
|
|
2893
2939
|
});
|
|
2894
2940
|
continue;
|
|
2895
2941
|
}
|
|
2942
|
+
if (bundle.chainKind === "mina") {
|
|
2943
|
+
if (!this.identityClient.settleSwapBundle) {
|
|
2944
|
+
results.push({
|
|
2945
|
+
...base,
|
|
2946
|
+
error: {
|
|
2947
|
+
code: "SUBMISSION_UNAVAILABLE",
|
|
2948
|
+
message: "The active client does not implement settleSwapBundle."
|
|
2949
|
+
}
|
|
2950
|
+
});
|
|
2951
|
+
continue;
|
|
2952
|
+
}
|
|
2953
|
+
try {
|
|
2954
|
+
const submitted = await this.identityClient.settleSwapBundle(bundle);
|
|
2955
|
+
const latest = this.receivedClaimStore.load(entry.chain, entry.channelId) ?? entry;
|
|
2956
|
+
this.receivedClaimStore.save({
|
|
2957
|
+
...latest,
|
|
2958
|
+
settledAt: Date.now(),
|
|
2959
|
+
settledNonce: BigInt(bundle.nonce),
|
|
2960
|
+
settleTxHash: submitted.txHash
|
|
2961
|
+
});
|
|
2962
|
+
this.log(
|
|
2963
|
+
`[runner] swap settle: submitted ${bundle.chain}/${bundle.channelId} nonce ${bundle.nonce} cumulative ${bundle.cumulativeAmount} \u2192 ${submitted.txHash}`
|
|
2964
|
+
);
|
|
2965
|
+
results.push({
|
|
2966
|
+
...base,
|
|
2967
|
+
submitted: true,
|
|
2968
|
+
txHash: submitted.txHash,
|
|
2969
|
+
...submitted.status ? { txStatus: submitted.status } : {}
|
|
2970
|
+
});
|
|
2971
|
+
} catch (err) {
|
|
2972
|
+
results.push({
|
|
2973
|
+
...base,
|
|
2974
|
+
error: {
|
|
2975
|
+
code: "SUBMISSION_FAILED",
|
|
2976
|
+
message: err instanceof Error ? err.message : String(err)
|
|
2977
|
+
}
|
|
2978
|
+
});
|
|
2979
|
+
}
|
|
2980
|
+
continue;
|
|
2981
|
+
}
|
|
2896
2982
|
const rpcUrl = this.config.toonClientConfig.chainRpcUrls?.[bundle.chain];
|
|
2897
2983
|
if (!rpcUrl) {
|
|
2898
2984
|
results.push({
|
|
@@ -2948,20 +3034,30 @@ var ClientRunner = class {
|
|
|
2948
3034
|
* Wrap an apex client so each `sendSwapPacket` call carries a freshly
|
|
2949
3035
|
* minted sender-chosen execution condition (one preimage per packet, spec
|
|
2950
3036
|
* R1 — reuse would let an observer of packet *i* fulfill packet *i+1*).
|
|
2951
|
-
* `streamSwap` calls `sendSwapPacket` once per packet,
|
|
2952
|
-
*
|
|
2953
|
-
*
|
|
3037
|
+
* `streamSwap` calls `sendSwapPacket` once per packet, in strictly
|
|
3038
|
+
* increasing `packetIndex` order, so minting here yields exactly one
|
|
3039
|
+
* condition per packet and the local counter tracks `packetIndex`. The
|
|
3040
|
+
* transports verify each FULFILL's preimage against the condition and fail
|
|
3041
|
+
* the packet on mismatch.
|
|
2954
3042
|
*
|
|
2955
|
-
*
|
|
2956
|
-
*
|
|
2957
|
-
*
|
|
2958
|
-
*
|
|
2959
|
-
*
|
|
3043
|
+
* Preimage retention (toon-client#360, spec §3.2 leg-B reveal): every minted
|
|
3044
|
+
* `P_i` is retained in `preimages`, keyed by `packetIndex` — the identifier
|
|
3045
|
+
* shared with `AccumulatedClaim.packetIndex` — so the receive-side reveal
|
|
3046
|
+
* step (`ingestAndReveal`) can correlate and consume the preimage for the
|
|
3047
|
+
* claim it commits. Retention is session-scoped (one store per `swap()`
|
|
3048
|
+
* call); a fresh stream mints fresh preimages.
|
|
2960
3049
|
*/
|
|
2961
|
-
withSenderConditions(client) {
|
|
3050
|
+
withSenderConditions(client, preimages) {
|
|
2962
3051
|
const wrapped = Object.create(client);
|
|
3052
|
+
let packetIndex = 0;
|
|
2963
3053
|
wrapped.sendSwapPacket = (params) => {
|
|
2964
|
-
const { condition } = mintExecutionCondition();
|
|
3054
|
+
const { preimage, condition } = mintExecutionCondition();
|
|
3055
|
+
preimages.retain({
|
|
3056
|
+
packetIndex: packetIndex++,
|
|
3057
|
+
preimage,
|
|
3058
|
+
condition,
|
|
3059
|
+
retainedAt: Date.now()
|
|
3060
|
+
});
|
|
2965
3061
|
return client.sendSwapPacket({
|
|
2966
3062
|
...params,
|
|
2967
3063
|
executionCondition: condition
|
|
@@ -3932,4 +4028,4 @@ export {
|
|
|
3932
4028
|
PublishRejectedError,
|
|
3933
4029
|
registerRoutes
|
|
3934
4030
|
};
|
|
3935
|
-
//# sourceMappingURL=chunk-
|
|
4031
|
+
//# sourceMappingURL=chunk-ITONR5ML.js.map
|