@tangle-network/blueprint-ui 0.3.1 → 0.5.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/chunk-ZKICSKZH.js +57 -0
- package/dist/chunk-ZKICSKZH.js.map +1 -0
- package/dist/detectParentOrigin-BYruoIdc.d.ts +26 -0
- package/dist/iframe/index.d.ts +145 -0
- package/dist/iframe/index.js +557 -0
- package/dist/iframe/index.js.map +1 -0
- package/dist/iframe/testing-index.d.ts +82 -0
- package/dist/iframe/testing-index.js +535 -0
- package/dist/iframe/testing-index.js.map +1 -0
- package/dist/parentBridgeProtocol-BS2zbIvX.d.ts +194 -0
- package/dist/styles.css +3 -0
- package/dist/tangleIframeClient-DES8FDF0.d.ts +121 -0
- package/dist/wallet/index.d.ts +10 -109
- package/dist/wallet/index.js +14 -47
- package/dist/wallet/index.js.map +1 -1
- package/package.json +11 -1
- package/src/iframe/TangleIframeProvider.tsx +172 -0
- package/src/iframe/hooks.ts +234 -0
- package/src/iframe/index.ts +77 -0
- package/src/iframe/tangleIframeClient.test.ts +317 -0
- package/src/iframe/tangleIframeClient.ts +483 -0
- package/src/iframe/testing-index.ts +15 -0
- package/src/iframe/testing.tsx +710 -0
- package/src/wallet/index.ts +11 -0
- package/src/wallet/parentBridgeProtocol.ts +150 -1
- package/src/wallet/parentBridgeProvider.ts +17 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { C as CallJobRequest, h as ServiceContextOperator, g as ServiceContextJob, b as ChainContext } from '../parentBridgeProtocol-BS2zbIvX.js';
|
|
2
|
+
import { FC, ReactNode } from 'react';
|
|
3
|
+
import { Address } from 'viem';
|
|
4
|
+
import { W as WalletSnapshot, S as ServiceSnapshot } from '../tangleIframeClient-DES8FDF0.js';
|
|
5
|
+
|
|
6
|
+
type MockWalletInput = Partial<{
|
|
7
|
+
address: Address | null;
|
|
8
|
+
chainId: number;
|
|
9
|
+
isConnected: boolean;
|
|
10
|
+
}>;
|
|
11
|
+
type MockServiceInput = Partial<{
|
|
12
|
+
blueprintId: string;
|
|
13
|
+
serviceId: string | null;
|
|
14
|
+
operators: readonly ServiceContextOperator[];
|
|
15
|
+
jobs: readonly ServiceContextJob[];
|
|
16
|
+
mode: string | null;
|
|
17
|
+
chain: ChainContext | null;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Construct a deterministic wallet snapshot for tests. Defaults:
|
|
21
|
+
* connected, vitalik.eth's address, Base Sepolia (84532).
|
|
22
|
+
*/
|
|
23
|
+
declare function mockWallet(input?: MockWalletInput): WalletSnapshot;
|
|
24
|
+
/**
|
|
25
|
+
* Construct a deterministic service snapshot for tests. Defaults: blueprint
|
|
26
|
+
* id `0`, no service deployed yet (serviceId null), single mock operator on
|
|
27
|
+
* the canonical local sidecar URL.
|
|
28
|
+
*/
|
|
29
|
+
declare function mockServiceContext(input?: MockServiceInput): ServiceSnapshot;
|
|
30
|
+
type CallJobHandler = (request: CallJobRequest) => Promise<{
|
|
31
|
+
status: 'success' | 'error';
|
|
32
|
+
data?: unknown;
|
|
33
|
+
error?: string;
|
|
34
|
+
/** Streaming chunks emitted in order before the terminal status. */
|
|
35
|
+
chunks?: readonly unknown[];
|
|
36
|
+
}>;
|
|
37
|
+
type HarnessProps = {
|
|
38
|
+
appId?: string;
|
|
39
|
+
wallet?: WalletSnapshot;
|
|
40
|
+
service?: ServiceSnapshot;
|
|
41
|
+
/** Override callJob behavior. Default: returns a static `{ ok: true }`. */
|
|
42
|
+
onCallJob?: CallJobHandler;
|
|
43
|
+
/** Surface a floating debug panel that lets the developer flip state at runtime. */
|
|
44
|
+
showDebugPanel?: boolean;
|
|
45
|
+
children: ReactNode;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Drop-in parent simulator for tests + storybook + standalone dev. Wraps
|
|
49
|
+
* children in a fake parent that:
|
|
50
|
+
*
|
|
51
|
+
* - Acks the iframe's handshake immediately
|
|
52
|
+
* - Broadcasts the configured wallet + service context on mount
|
|
53
|
+
* - Intercepts `callJob` requests and routes them through `onCallJob`
|
|
54
|
+
* - (Optional) Mounts a floating debug panel so the developer can
|
|
55
|
+
* mutate state at runtime: change account, switch chain, set
|
|
56
|
+
* serviceId, fire a custom job
|
|
57
|
+
*
|
|
58
|
+
* The harness runs in the same JS context as the iframe app — there's no
|
|
59
|
+
* cross-frame postMessage, just same-window event dispatch. That keeps it
|
|
60
|
+
* fully synchronous + assertable, but the messages still flow through the
|
|
61
|
+
* exact same protocol surface the production bridge uses.
|
|
62
|
+
*
|
|
63
|
+
* Usage:
|
|
64
|
+
*
|
|
65
|
+
* <TangleParentHarness wallet={mockWallet()} service={mockServiceContext()}>
|
|
66
|
+
* <TangleIframeProvider appId="my-app" mode="bridge" parentOrigin="harness://">
|
|
67
|
+
* <App />
|
|
68
|
+
* </TangleIframeProvider>
|
|
69
|
+
* </TangleParentHarness>
|
|
70
|
+
*
|
|
71
|
+
* Set `mode="bridge"` + `parentOrigin="harness://"` on the provider so it
|
|
72
|
+
* matches the harness's synthetic origin. In production, use `mode="auto"`
|
|
73
|
+
* (the default).
|
|
74
|
+
*/
|
|
75
|
+
declare const TangleParentHarness: FC<HarnessProps>;
|
|
76
|
+
/**
|
|
77
|
+
* Synthetic origin every harness instance uses. Stable across tests so the
|
|
78
|
+
* iframe SDK + the harness can pin to the same string.
|
|
79
|
+
*/
|
|
80
|
+
declare const HARNESS_ORIGIN = "harness://tangle.local";
|
|
81
|
+
|
|
82
|
+
export { type CallJobHandler, HARNESS_ORIGIN, type MockServiceInput, type MockWalletInput, TangleParentHarness, mockServiceContext, mockWallet };
|
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
// src/iframe/testing.tsx
|
|
2
|
+
import {
|
|
3
|
+
useCallback,
|
|
4
|
+
useEffect,
|
|
5
|
+
useMemo,
|
|
6
|
+
useRef,
|
|
7
|
+
useState
|
|
8
|
+
} from "react";
|
|
9
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
function mockWallet(input = {}) {
|
|
11
|
+
return {
|
|
12
|
+
address: input.address === void 0 ? "0xd8da6bf26964af9d7eed9e03e53415d37aa96045" : input.address,
|
|
13
|
+
chainId: input.chainId ?? 84532,
|
|
14
|
+
isConnected: input.isConnected ?? input.address !== null
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function mockServiceContext(input = {}) {
|
|
18
|
+
return {
|
|
19
|
+
blueprintId: input.blueprintId ?? "0",
|
|
20
|
+
serviceId: input.serviceId === void 0 ? null : input.serviceId,
|
|
21
|
+
operators: input.operators ?? [
|
|
22
|
+
{
|
|
23
|
+
address: "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
|
|
24
|
+
rpcAddress: "http://localhost:8545",
|
|
25
|
+
status: "active"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
jobs: input.jobs ?? [
|
|
29
|
+
{ index: 0, name: "invoke" }
|
|
30
|
+
],
|
|
31
|
+
mode: input.mode ?? null,
|
|
32
|
+
chain: input.chain === void 0 ? {
|
|
33
|
+
id: 84532,
|
|
34
|
+
name: "Base Sepolia",
|
|
35
|
+
rpcUrl: "https://sepolia.base.org",
|
|
36
|
+
blockExplorerUrl: "https://sepolia.basescan.org",
|
|
37
|
+
nativeCurrency: { name: "Sepolia Ether", symbol: "ETH", decimals: 18 }
|
|
38
|
+
} : input.chain
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
var TangleParentHarness = ({
|
|
42
|
+
appId = "harness",
|
|
43
|
+
wallet = mockWallet(),
|
|
44
|
+
service = mockServiceContext(),
|
|
45
|
+
onCallJob,
|
|
46
|
+
showDebugPanel = false,
|
|
47
|
+
children
|
|
48
|
+
}) => {
|
|
49
|
+
const [currentWallet, setCurrentWallet] = useState(wallet);
|
|
50
|
+
const [currentService, setCurrentService] = useState(service);
|
|
51
|
+
const [callLog, setCallLog] = useState([]);
|
|
52
|
+
const callJobHandler = useRef(onCallJob);
|
|
53
|
+
callJobHandler.current = onCallJob;
|
|
54
|
+
const seenHandshake = useRef(false);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
const reply = (message) => {
|
|
57
|
+
window.dispatchEvent(
|
|
58
|
+
new MessageEvent("message", {
|
|
59
|
+
data: message,
|
|
60
|
+
origin: HARNESS_ORIGIN
|
|
61
|
+
})
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
const broadcast = () => {
|
|
65
|
+
const broadcastMsg = {
|
|
66
|
+
kind: "tangle.app.serviceContext",
|
|
67
|
+
blueprintId: currentService.blueprintId ?? "0",
|
|
68
|
+
serviceId: currentService.serviceId,
|
|
69
|
+
operators: currentService.operators,
|
|
70
|
+
jobs: currentService.jobs,
|
|
71
|
+
mode: currentService.mode,
|
|
72
|
+
...currentService.chain !== null ? { chain: currentService.chain } : {}
|
|
73
|
+
};
|
|
74
|
+
reply(broadcastMsg);
|
|
75
|
+
reply({
|
|
76
|
+
kind: "tangle.app.accountChanged",
|
|
77
|
+
account: currentWallet.address
|
|
78
|
+
});
|
|
79
|
+
if (currentWallet.chainId !== null) {
|
|
80
|
+
reply({
|
|
81
|
+
kind: "tangle.app.chainChanged",
|
|
82
|
+
chainId: currentWallet.chainId
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const handler = async (event) => {
|
|
87
|
+
if (event.origin === HARNESS_ORIGIN) return;
|
|
88
|
+
const data = event.data;
|
|
89
|
+
if (typeof data !== "object" || data === null) return;
|
|
90
|
+
const message = data;
|
|
91
|
+
switch (message.kind) {
|
|
92
|
+
case "tangle.app.handshake": {
|
|
93
|
+
if (!seenHandshake.current) {
|
|
94
|
+
seenHandshake.current = true;
|
|
95
|
+
reply({
|
|
96
|
+
kind: "tangle.app.handshakeAck",
|
|
97
|
+
appId,
|
|
98
|
+
protocolVersion: "1"
|
|
99
|
+
});
|
|
100
|
+
broadcast();
|
|
101
|
+
}
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
case "tangle.app.readAccount": {
|
|
105
|
+
if (typeof message.correlationId !== "string") return;
|
|
106
|
+
reply({
|
|
107
|
+
kind: "tangle.app.readAccountResult",
|
|
108
|
+
correlationId: message.correlationId,
|
|
109
|
+
ok: true,
|
|
110
|
+
data: {
|
|
111
|
+
account: currentWallet.address ?? "0x0000000000000000000000000000000000000000",
|
|
112
|
+
chainId: currentWallet.chainId ?? 0
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
case "tangle.app.callJob": {
|
|
118
|
+
if (typeof message.correlationId !== "string") return;
|
|
119
|
+
const request = message;
|
|
120
|
+
setCallLog((prev) => [...prev, request]);
|
|
121
|
+
const handler2 = callJobHandler.current;
|
|
122
|
+
if (!handler2) {
|
|
123
|
+
const result = {
|
|
124
|
+
kind: "tangle.app.jobResult",
|
|
125
|
+
correlationId: request.correlationId,
|
|
126
|
+
status: "success",
|
|
127
|
+
data: { echo: request.inputs }
|
|
128
|
+
};
|
|
129
|
+
reply(result);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
const outcome = await handler2(request);
|
|
134
|
+
for (const chunk of outcome.chunks ?? []) {
|
|
135
|
+
reply({
|
|
136
|
+
kind: "tangle.app.jobResult",
|
|
137
|
+
correlationId: request.correlationId,
|
|
138
|
+
status: "streaming",
|
|
139
|
+
chunk
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
reply({
|
|
143
|
+
kind: "tangle.app.jobResult",
|
|
144
|
+
correlationId: request.correlationId,
|
|
145
|
+
status: outcome.status,
|
|
146
|
+
...outcome.data !== void 0 ? { data: outcome.data } : {},
|
|
147
|
+
...outcome.error !== void 0 ? { error: outcome.error } : {}
|
|
148
|
+
});
|
|
149
|
+
} catch (err) {
|
|
150
|
+
reply({
|
|
151
|
+
kind: "tangle.app.jobResult",
|
|
152
|
+
correlationId: request.correlationId,
|
|
153
|
+
status: "error",
|
|
154
|
+
error: err instanceof Error ? err.message : String(err)
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
// Wallet ops respond optimistically — tests that want to assert
|
|
160
|
+
// specific signatures should pre-set them via the dev handler.
|
|
161
|
+
case "tangle.app.signMessage": {
|
|
162
|
+
if (typeof message.correlationId !== "string") return;
|
|
163
|
+
reply({
|
|
164
|
+
kind: "tangle.app.signMessageResult",
|
|
165
|
+
correlationId: message.correlationId,
|
|
166
|
+
ok: true,
|
|
167
|
+
data: { signature: "0xdeadbeef" }
|
|
168
|
+
});
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
case "tangle.app.signTypedData": {
|
|
172
|
+
if (typeof message.correlationId !== "string") return;
|
|
173
|
+
reply({
|
|
174
|
+
kind: "tangle.app.signTypedDataResult",
|
|
175
|
+
correlationId: message.correlationId,
|
|
176
|
+
ok: true,
|
|
177
|
+
data: {
|
|
178
|
+
signature: "0x" + "11".repeat(65)
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
case "tangle.app.signTransaction": {
|
|
184
|
+
if (typeof message.correlationId !== "string") return;
|
|
185
|
+
reply({
|
|
186
|
+
kind: "tangle.app.signTransactionResult",
|
|
187
|
+
correlationId: message.correlationId,
|
|
188
|
+
ok: true,
|
|
189
|
+
data: { txHash: "0x" + "00".repeat(32) }
|
|
190
|
+
});
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
case "tangle.app.switchChain": {
|
|
194
|
+
if (typeof message.correlationId !== "string" || typeof message.chainId !== "number") {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const chainId = message.chainId;
|
|
198
|
+
setCurrentWallet((w) => ({ ...w, chainId }));
|
|
199
|
+
reply({
|
|
200
|
+
kind: "tangle.app.switchChainResult",
|
|
201
|
+
correlationId: message.correlationId,
|
|
202
|
+
ok: true,
|
|
203
|
+
data: { chainId }
|
|
204
|
+
});
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
window.addEventListener("message", handler);
|
|
210
|
+
return () => window.removeEventListener("message", handler);
|
|
211
|
+
}, [appId, currentWallet, currentService]);
|
|
212
|
+
useEffect(() => {
|
|
213
|
+
if (!seenHandshake.current) return;
|
|
214
|
+
window.dispatchEvent(
|
|
215
|
+
new MessageEvent("message", {
|
|
216
|
+
data: {
|
|
217
|
+
kind: "tangle.app.accountChanged",
|
|
218
|
+
account: currentWallet.address
|
|
219
|
+
},
|
|
220
|
+
origin: HARNESS_ORIGIN
|
|
221
|
+
})
|
|
222
|
+
);
|
|
223
|
+
}, [currentWallet.address]);
|
|
224
|
+
useEffect(() => {
|
|
225
|
+
if (!seenHandshake.current || currentWallet.chainId === null) return;
|
|
226
|
+
window.dispatchEvent(
|
|
227
|
+
new MessageEvent("message", {
|
|
228
|
+
data: {
|
|
229
|
+
kind: "tangle.app.chainChanged",
|
|
230
|
+
chainId: currentWallet.chainId
|
|
231
|
+
},
|
|
232
|
+
origin: HARNESS_ORIGIN
|
|
233
|
+
})
|
|
234
|
+
);
|
|
235
|
+
}, [currentWallet.chainId]);
|
|
236
|
+
useEffect(() => {
|
|
237
|
+
if (!seenHandshake.current) return;
|
|
238
|
+
window.dispatchEvent(
|
|
239
|
+
new MessageEvent("message", {
|
|
240
|
+
data: {
|
|
241
|
+
kind: "tangle.app.serviceContext",
|
|
242
|
+
blueprintId: currentService.blueprintId ?? "0",
|
|
243
|
+
serviceId: currentService.serviceId,
|
|
244
|
+
operators: currentService.operators,
|
|
245
|
+
jobs: currentService.jobs,
|
|
246
|
+
mode: currentService.mode,
|
|
247
|
+
...currentService.chain !== null ? { chain: currentService.chain } : {}
|
|
248
|
+
},
|
|
249
|
+
origin: HARNESS_ORIGIN
|
|
250
|
+
})
|
|
251
|
+
);
|
|
252
|
+
}, [currentService]);
|
|
253
|
+
const debugApi = useMemo(
|
|
254
|
+
() => ({
|
|
255
|
+
setWallet: setCurrentWallet,
|
|
256
|
+
setService: setCurrentService,
|
|
257
|
+
callLog
|
|
258
|
+
}),
|
|
259
|
+
[callLog]
|
|
260
|
+
);
|
|
261
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
262
|
+
children,
|
|
263
|
+
showDebugPanel && /* @__PURE__ */ jsx(DebugPanel, { api: debugApi })
|
|
264
|
+
] });
|
|
265
|
+
};
|
|
266
|
+
var HARNESS_ORIGIN = "harness://tangle.local";
|
|
267
|
+
var DebugPanel = ({ api }) => {
|
|
268
|
+
const [open, setOpen] = useState(true);
|
|
269
|
+
const [tab, setTab] = useState("wallet");
|
|
270
|
+
if (!open) {
|
|
271
|
+
return /* @__PURE__ */ jsx(
|
|
272
|
+
"button",
|
|
273
|
+
{
|
|
274
|
+
type: "button",
|
|
275
|
+
onClick: () => setOpen(true),
|
|
276
|
+
style: debugStyles.collapsedTrigger,
|
|
277
|
+
children: "Debug"
|
|
278
|
+
}
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
return /* @__PURE__ */ jsxs("div", { style: debugStyles.panel, children: [
|
|
282
|
+
/* @__PURE__ */ jsxs("header", { style: debugStyles.header, children: [
|
|
283
|
+
/* @__PURE__ */ jsx("strong", { style: { fontSize: 11 }, children: "TANGLE DEV HARNESS" }),
|
|
284
|
+
/* @__PURE__ */ jsx(
|
|
285
|
+
"button",
|
|
286
|
+
{
|
|
287
|
+
type: "button",
|
|
288
|
+
onClick: () => setOpen(false),
|
|
289
|
+
style: debugStyles.closeButton,
|
|
290
|
+
"aria-label": "Close debug panel",
|
|
291
|
+
children: "\xD7"
|
|
292
|
+
}
|
|
293
|
+
)
|
|
294
|
+
] }),
|
|
295
|
+
/* @__PURE__ */ jsx("nav", { style: debugStyles.tabs, children: ["wallet", "service", "log"].map((t) => /* @__PURE__ */ jsx(
|
|
296
|
+
"button",
|
|
297
|
+
{
|
|
298
|
+
type: "button",
|
|
299
|
+
onClick: () => setTab(t),
|
|
300
|
+
style: {
|
|
301
|
+
...debugStyles.tab,
|
|
302
|
+
...tab === t ? debugStyles.tabActive : {}
|
|
303
|
+
},
|
|
304
|
+
children: t
|
|
305
|
+
},
|
|
306
|
+
t
|
|
307
|
+
)) }),
|
|
308
|
+
/* @__PURE__ */ jsxs("div", { style: debugStyles.body, children: [
|
|
309
|
+
tab === "wallet" && /* @__PURE__ */ jsx(WalletTab, { api }),
|
|
310
|
+
tab === "service" && /* @__PURE__ */ jsx(ServiceTab, { api }),
|
|
311
|
+
tab === "log" && /* @__PURE__ */ jsx(CallLogTab, { callLog: api.callLog })
|
|
312
|
+
] })
|
|
313
|
+
] });
|
|
314
|
+
};
|
|
315
|
+
var WalletTab = ({ api }) => {
|
|
316
|
+
const [address, setAddressInput] = useState(
|
|
317
|
+
"0xd8da6bf26964af9d7eed9e03e53415d37aa96045"
|
|
318
|
+
);
|
|
319
|
+
const [chainId, setChainIdInput] = useState("84532");
|
|
320
|
+
const applyConnect = useCallback(() => {
|
|
321
|
+
api.setWallet({
|
|
322
|
+
address,
|
|
323
|
+
chainId: Number(chainId) || null,
|
|
324
|
+
isConnected: true
|
|
325
|
+
});
|
|
326
|
+
}, [address, chainId, api]);
|
|
327
|
+
const disconnect = useCallback(() => {
|
|
328
|
+
api.setWallet({ address: null, chainId: null, isConnected: false });
|
|
329
|
+
}, [api]);
|
|
330
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
331
|
+
/* @__PURE__ */ jsx("label", { style: debugStyles.label, children: "address" }),
|
|
332
|
+
/* @__PURE__ */ jsx(
|
|
333
|
+
"input",
|
|
334
|
+
{
|
|
335
|
+
value: address,
|
|
336
|
+
onChange: (e) => setAddressInput(e.target.value),
|
|
337
|
+
style: debugStyles.input
|
|
338
|
+
}
|
|
339
|
+
),
|
|
340
|
+
/* @__PURE__ */ jsx("label", { style: debugStyles.label, children: "chain id" }),
|
|
341
|
+
/* @__PURE__ */ jsx(
|
|
342
|
+
"input",
|
|
343
|
+
{
|
|
344
|
+
value: chainId,
|
|
345
|
+
onChange: (e) => setChainIdInput(e.target.value),
|
|
346
|
+
style: debugStyles.input
|
|
347
|
+
}
|
|
348
|
+
),
|
|
349
|
+
/* @__PURE__ */ jsxs("div", { style: debugStyles.buttonRow, children: [
|
|
350
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: applyConnect, style: debugStyles.primary, children: "Set connected" }),
|
|
351
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: disconnect, style: debugStyles.secondary, children: "Disconnect" })
|
|
352
|
+
] })
|
|
353
|
+
] });
|
|
354
|
+
};
|
|
355
|
+
var ServiceTab = ({ api }) => {
|
|
356
|
+
const [serviceId, setServiceIdInput] = useState("1");
|
|
357
|
+
const [blueprintId, setBlueprintIdInput] = useState("0");
|
|
358
|
+
const apply = useCallback(() => {
|
|
359
|
+
api.setService((prev) => ({
|
|
360
|
+
...prev,
|
|
361
|
+
serviceId: serviceId || null,
|
|
362
|
+
blueprintId
|
|
363
|
+
}));
|
|
364
|
+
}, [api, serviceId, blueprintId]);
|
|
365
|
+
const clearService = useCallback(() => {
|
|
366
|
+
api.setService((prev) => ({ ...prev, serviceId: null }));
|
|
367
|
+
}, [api]);
|
|
368
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
369
|
+
/* @__PURE__ */ jsx("label", { style: debugStyles.label, children: "blueprint id" }),
|
|
370
|
+
/* @__PURE__ */ jsx(
|
|
371
|
+
"input",
|
|
372
|
+
{
|
|
373
|
+
value: blueprintId,
|
|
374
|
+
onChange: (e) => setBlueprintIdInput(e.target.value),
|
|
375
|
+
style: debugStyles.input
|
|
376
|
+
}
|
|
377
|
+
),
|
|
378
|
+
/* @__PURE__ */ jsx("label", { style: debugStyles.label, children: "service id (empty = not deployed)" }),
|
|
379
|
+
/* @__PURE__ */ jsx(
|
|
380
|
+
"input",
|
|
381
|
+
{
|
|
382
|
+
value: serviceId,
|
|
383
|
+
onChange: (e) => setServiceIdInput(e.target.value),
|
|
384
|
+
style: debugStyles.input
|
|
385
|
+
}
|
|
386
|
+
),
|
|
387
|
+
/* @__PURE__ */ jsxs("div", { style: debugStyles.buttonRow, children: [
|
|
388
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: apply, style: debugStyles.primary, children: "Apply" }),
|
|
389
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: clearService, style: debugStyles.secondary, children: "Clear service" })
|
|
390
|
+
] })
|
|
391
|
+
] });
|
|
392
|
+
};
|
|
393
|
+
var CallLogTab = ({ callLog }) => {
|
|
394
|
+
if (callLog.length === 0) {
|
|
395
|
+
return /* @__PURE__ */ jsx("p", { style: debugStyles.empty, children: "No callJob requests yet." });
|
|
396
|
+
}
|
|
397
|
+
return /* @__PURE__ */ jsx("ol", { style: debugStyles.log, children: callLog.map((entry) => /* @__PURE__ */ jsxs("li", { style: debugStyles.logEntry, children: [
|
|
398
|
+
/* @__PURE__ */ jsxs("strong", { children: [
|
|
399
|
+
"job ",
|
|
400
|
+
entry.jobIndex
|
|
401
|
+
] }),
|
|
402
|
+
/* @__PURE__ */ jsx("pre", { style: debugStyles.pre, children: JSON.stringify(entry.inputs, null, 2) })
|
|
403
|
+
] }, entry.correlationId)) });
|
|
404
|
+
};
|
|
405
|
+
var debugStyles = {
|
|
406
|
+
panel: {
|
|
407
|
+
position: "fixed",
|
|
408
|
+
right: 12,
|
|
409
|
+
top: 12,
|
|
410
|
+
width: 280,
|
|
411
|
+
zIndex: 99999,
|
|
412
|
+
background: "#0b0b14",
|
|
413
|
+
color: "#fff",
|
|
414
|
+
border: "1px solid #3a3a52",
|
|
415
|
+
borderRadius: 10,
|
|
416
|
+
boxShadow: "0 14px 32px rgba(0,0,0,0.4)",
|
|
417
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Code", monospace',
|
|
418
|
+
fontSize: 12
|
|
419
|
+
},
|
|
420
|
+
header: {
|
|
421
|
+
display: "flex",
|
|
422
|
+
alignItems: "center",
|
|
423
|
+
justifyContent: "space-between",
|
|
424
|
+
padding: "8px 10px",
|
|
425
|
+
borderBottom: "1px solid #2a2a3e"
|
|
426
|
+
},
|
|
427
|
+
closeButton: {
|
|
428
|
+
background: "none",
|
|
429
|
+
border: "none",
|
|
430
|
+
color: "#fff",
|
|
431
|
+
fontSize: 18,
|
|
432
|
+
cursor: "pointer",
|
|
433
|
+
lineHeight: 1
|
|
434
|
+
},
|
|
435
|
+
tabs: {
|
|
436
|
+
display: "flex",
|
|
437
|
+
borderBottom: "1px solid #2a2a3e"
|
|
438
|
+
},
|
|
439
|
+
tab: {
|
|
440
|
+
flex: 1,
|
|
441
|
+
background: "none",
|
|
442
|
+
border: "none",
|
|
443
|
+
color: "#a0a0c0",
|
|
444
|
+
padding: "6px 8px",
|
|
445
|
+
cursor: "pointer",
|
|
446
|
+
fontSize: 11,
|
|
447
|
+
textTransform: "uppercase"
|
|
448
|
+
},
|
|
449
|
+
tabActive: {
|
|
450
|
+
color: "#fff",
|
|
451
|
+
borderBottom: "2px solid #818cf8"
|
|
452
|
+
},
|
|
453
|
+
body: {
|
|
454
|
+
padding: 10,
|
|
455
|
+
maxHeight: 320,
|
|
456
|
+
overflow: "auto"
|
|
457
|
+
},
|
|
458
|
+
label: {
|
|
459
|
+
display: "block",
|
|
460
|
+
color: "#a0a0c0",
|
|
461
|
+
fontSize: 10,
|
|
462
|
+
marginBottom: 4,
|
|
463
|
+
marginTop: 6,
|
|
464
|
+
textTransform: "uppercase"
|
|
465
|
+
},
|
|
466
|
+
input: {
|
|
467
|
+
width: "100%",
|
|
468
|
+
background: "#15152a",
|
|
469
|
+
border: "1px solid #2a2a3e",
|
|
470
|
+
color: "#fff",
|
|
471
|
+
padding: "6px 8px",
|
|
472
|
+
borderRadius: 4,
|
|
473
|
+
fontFamily: "inherit",
|
|
474
|
+
fontSize: 11,
|
|
475
|
+
boxSizing: "border-box"
|
|
476
|
+
},
|
|
477
|
+
buttonRow: { display: "flex", gap: 6, marginTop: 8 },
|
|
478
|
+
primary: {
|
|
479
|
+
flex: 1,
|
|
480
|
+
background: "#4f46e5",
|
|
481
|
+
color: "#fff",
|
|
482
|
+
border: "none",
|
|
483
|
+
padding: "6px 8px",
|
|
484
|
+
borderRadius: 4,
|
|
485
|
+
cursor: "pointer",
|
|
486
|
+
fontSize: 11,
|
|
487
|
+
fontFamily: "inherit"
|
|
488
|
+
},
|
|
489
|
+
secondary: {
|
|
490
|
+
flex: 1,
|
|
491
|
+
background: "transparent",
|
|
492
|
+
color: "#a0a0c0",
|
|
493
|
+
border: "1px solid #3a3a52",
|
|
494
|
+
padding: "6px 8px",
|
|
495
|
+
borderRadius: 4,
|
|
496
|
+
cursor: "pointer",
|
|
497
|
+
fontSize: 11,
|
|
498
|
+
fontFamily: "inherit"
|
|
499
|
+
},
|
|
500
|
+
collapsedTrigger: {
|
|
501
|
+
position: "fixed",
|
|
502
|
+
right: 12,
|
|
503
|
+
top: 12,
|
|
504
|
+
zIndex: 99999,
|
|
505
|
+
padding: "6px 10px",
|
|
506
|
+
background: "#0b0b14",
|
|
507
|
+
border: "1px solid #3a3a52",
|
|
508
|
+
color: "#fff",
|
|
509
|
+
borderRadius: 6,
|
|
510
|
+
fontFamily: "inherit",
|
|
511
|
+
fontSize: 11,
|
|
512
|
+
cursor: "pointer"
|
|
513
|
+
},
|
|
514
|
+
log: { listStyle: "none", padding: 0, margin: 0 },
|
|
515
|
+
logEntry: {
|
|
516
|
+
padding: 6,
|
|
517
|
+
borderBottom: "1px solid #2a2a3e",
|
|
518
|
+
fontSize: 11
|
|
519
|
+
},
|
|
520
|
+
pre: {
|
|
521
|
+
margin: "4px 0 0",
|
|
522
|
+
color: "#a0a0c0",
|
|
523
|
+
fontSize: 10,
|
|
524
|
+
whiteSpace: "pre-wrap",
|
|
525
|
+
wordBreak: "break-word"
|
|
526
|
+
},
|
|
527
|
+
empty: { color: "#a0a0c0", fontSize: 11, margin: 0 }
|
|
528
|
+
};
|
|
529
|
+
export {
|
|
530
|
+
HARNESS_ORIGIN,
|
|
531
|
+
TangleParentHarness,
|
|
532
|
+
mockServiceContext,
|
|
533
|
+
mockWallet
|
|
534
|
+
};
|
|
535
|
+
//# sourceMappingURL=testing-index.js.map
|