Lint - also gonna leave this branch and probably drop it. Dagur has a design plan.
This commit is contained in:
parent
cdd357cb08
commit
52d710dbb5
6 changed files with 179 additions and 39 deletions
|
|
@ -4,7 +4,10 @@
|
||||||
|
|
||||||
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
||||||
import { ChunkAssembler, CHUNK_TIMEOUT_MS } from "./chunk-assembler.js";
|
import { ChunkAssembler, CHUNK_TIMEOUT_MS } from "./chunk-assembler.js";
|
||||||
import { type ChunkRelayMessage, RelayMsgAction } from "./protocols/hdwalletv1.js";
|
import {
|
||||||
|
type ChunkRelayMessage,
|
||||||
|
RelayMsgAction,
|
||||||
|
} from "./protocols/hdwalletv1.js";
|
||||||
|
|
||||||
function makeChunk(
|
function makeChunk(
|
||||||
chunk_id: string,
|
chunk_id: string,
|
||||||
|
|
@ -22,12 +25,23 @@ function makeChunk(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function splitMessage(message: object, chunkSize: number, chunk_id: string): ChunkRelayMessage[] {
|
function splitMessage(
|
||||||
|
message: object,
|
||||||
|
chunkSize: number,
|
||||||
|
chunk_id: string,
|
||||||
|
): ChunkRelayMessage[] {
|
||||||
const json = JSON.stringify(message);
|
const json = JSON.stringify(message);
|
||||||
const chunks: ChunkRelayMessage[] = [];
|
const chunks: ChunkRelayMessage[] = [];
|
||||||
const total = Math.ceil(json.length / chunkSize);
|
const total = Math.ceil(json.length / chunkSize);
|
||||||
for (let i = 0; i < total; i++) {
|
for (let i = 0; i < total; i++) {
|
||||||
chunks.push(makeChunk(chunk_id, i, total, json.slice(i * chunkSize, (i + 1) * chunkSize)));
|
chunks.push(
|
||||||
|
makeChunk(
|
||||||
|
chunk_id,
|
||||||
|
i,
|
||||||
|
total,
|
||||||
|
json.slice(i * chunkSize, (i + 1) * chunkSize),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return chunks;
|
return chunks;
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +60,11 @@ describe("ChunkAssembler", () => {
|
||||||
|
|
||||||
describe("single-fragment messages", () => {
|
describe("single-fragment messages", () => {
|
||||||
it("reassembles a single-fragment message immediately", () => {
|
it("reassembles a single-fragment message immediately", () => {
|
||||||
const original = { action: RelayMsgAction.SignCancel, sequence: 1, time: 1000 };
|
const original = {
|
||||||
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 1,
|
||||||
|
time: 1000,
|
||||||
|
};
|
||||||
const [chunk] = splitMessage(original, 10000, "id1");
|
const [chunk] = splitMessage(original, 10000, "id1");
|
||||||
|
|
||||||
const result = assembler.addChunk(chunk);
|
const result = assembler.addChunk(chunk);
|
||||||
|
|
@ -55,7 +73,11 @@ describe("ChunkAssembler", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("clears the pending buffer after assembly", () => {
|
it("clears the pending buffer after assembly", () => {
|
||||||
const original = { action: RelayMsgAction.SignCancel, sequence: 1, time: 1000 };
|
const original = {
|
||||||
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 1,
|
||||||
|
time: 1000,
|
||||||
|
};
|
||||||
const [chunk] = splitMessage(original, 10000, "id1");
|
const [chunk] = splitMessage(original, 10000, "id1");
|
||||||
|
|
||||||
assembler.addChunk(chunk);
|
assembler.addChunk(chunk);
|
||||||
|
|
@ -66,7 +88,11 @@ describe("ChunkAssembler", () => {
|
||||||
|
|
||||||
describe("multi-fragment messages", () => {
|
describe("multi-fragment messages", () => {
|
||||||
it("returns null for each fragment until the last", () => {
|
it("returns null for each fragment until the last", () => {
|
||||||
const original = { action: RelayMsgAction.SignCancel, sequence: 7, time: 1000 };
|
const original = {
|
||||||
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 7,
|
||||||
|
time: 1000,
|
||||||
|
};
|
||||||
const chunks = splitMessage(original, 5, "id2");
|
const chunks = splitMessage(original, 5, "id2");
|
||||||
expect(chunks.length).toBeGreaterThan(1);
|
expect(chunks.length).toBeGreaterThan(1);
|
||||||
|
|
||||||
|
|
@ -76,7 +102,11 @@ describe("ChunkAssembler", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns the reassembled message on the last fragment", () => {
|
it("returns the reassembled message on the last fragment", () => {
|
||||||
const original = { action: RelayMsgAction.SignCancel, sequence: 7, time: 1000 };
|
const original = {
|
||||||
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 7,
|
||||||
|
time: 1000,
|
||||||
|
};
|
||||||
const chunks = splitMessage(original, 5, "id3");
|
const chunks = splitMessage(original, 5, "id3");
|
||||||
|
|
||||||
let result = null;
|
let result = null;
|
||||||
|
|
@ -88,7 +118,11 @@ describe("ChunkAssembler", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("reassembles correctly when fragments arrive out of order", () => {
|
it("reassembles correctly when fragments arrive out of order", () => {
|
||||||
const original = { action: RelayMsgAction.SignCancel, sequence: 42, time: 2000 };
|
const original = {
|
||||||
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 42,
|
||||||
|
time: 2000,
|
||||||
|
};
|
||||||
const chunks = splitMessage(original, 3, "id4");
|
const chunks = splitMessage(original, 3, "id4");
|
||||||
expect(chunks.length).toBeGreaterThan(1);
|
expect(chunks.length).toBeGreaterThan(1);
|
||||||
|
|
||||||
|
|
@ -146,8 +180,16 @@ describe("ChunkAssembler", () => {
|
||||||
|
|
||||||
describe("independent chunk_ids", () => {
|
describe("independent chunk_ids", () => {
|
||||||
it("tracks multiple concurrent assemblies independently", () => {
|
it("tracks multiple concurrent assemblies independently", () => {
|
||||||
const msgA = { action: RelayMsgAction.SignCancel, sequence: 1, time: 1000 };
|
const msgA = {
|
||||||
const msgB = { action: RelayMsgAction.SignCancel, sequence: 2, time: 2000 };
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 1,
|
||||||
|
time: 1000,
|
||||||
|
};
|
||||||
|
const msgB = {
|
||||||
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 2,
|
||||||
|
time: 2000,
|
||||||
|
};
|
||||||
const chunksA = splitMessage(msgA, 5, "idA");
|
const chunksA = splitMessage(msgA, 5, "idA");
|
||||||
const chunksB = splitMessage(msgB, 5, "idB");
|
const chunksB = splitMessage(msgB, 5, "idB");
|
||||||
|
|
||||||
|
|
@ -165,8 +207,16 @@ describe("ChunkAssembler", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("completing one assembly does not affect pending assemblies", () => {
|
it("completing one assembly does not affect pending assemblies", () => {
|
||||||
const msgA = { action: RelayMsgAction.SignCancel, sequence: 1, time: 1000 };
|
const msgA = {
|
||||||
const msgB = { action: RelayMsgAction.SignCancel, sequence: 2, time: 2000 };
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 1,
|
||||||
|
time: 1000,
|
||||||
|
};
|
||||||
|
const msgB = {
|
||||||
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 2,
|
||||||
|
time: 2000,
|
||||||
|
};
|
||||||
const [chunkA] = splitMessage(msgA, 10000, "idA");
|
const [chunkA] = splitMessage(msgA, 10000, "idA");
|
||||||
const chunksB = splitMessage(msgB, 5, "idB");
|
const chunksB = splitMessage(msgB, 5, "idB");
|
||||||
|
|
||||||
|
|
@ -224,7 +274,11 @@ describe("ChunkAssembler", () => {
|
||||||
|
|
||||||
describe("timeout cleanup", () => {
|
describe("timeout cleanup", () => {
|
||||||
it("discards incomplete assembly after timeout", () => {
|
it("discards incomplete assembly after timeout", () => {
|
||||||
const msgA = { action: RelayMsgAction.SignCancel, sequence: 1, time: 1000 };
|
const msgA = {
|
||||||
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 1,
|
||||||
|
time: 1000,
|
||||||
|
};
|
||||||
const chunks = splitMessage(msgA, 5, "idTimeout");
|
const chunks = splitMessage(msgA, 5, "idTimeout");
|
||||||
expect(chunks.length).toBeGreaterThan(1);
|
expect(chunks.length).toBeGreaterThan(1);
|
||||||
|
|
||||||
|
|
@ -240,7 +294,11 @@ describe("ChunkAssembler", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("does not timeout before CHUNK_TIMEOUT_MS", () => {
|
it("does not timeout before CHUNK_TIMEOUT_MS", () => {
|
||||||
const msgA = { action: RelayMsgAction.SignCancel, sequence: 1, time: 1000 };
|
const msgA = {
|
||||||
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 1,
|
||||||
|
time: 1000,
|
||||||
|
};
|
||||||
const chunks = splitMessage(msgA, 5, "idTimeout2");
|
const chunks = splitMessage(msgA, 5, "idTimeout2");
|
||||||
|
|
||||||
for (let i = 0; i < chunks.length - 1; i++) {
|
for (let i = 0; i < chunks.length - 1; i++) {
|
||||||
|
|
@ -253,7 +311,11 @@ describe("ChunkAssembler", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("clears timeout when assembly completes before timeout", () => {
|
it("clears timeout when assembly completes before timeout", () => {
|
||||||
const msgA = { action: RelayMsgAction.SignCancel, sequence: 1, time: 1000 };
|
const msgA = {
|
||||||
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 1,
|
||||||
|
time: 1000,
|
||||||
|
};
|
||||||
const chunks = splitMessage(msgA, 5, "idTimeout3");
|
const chunks = splitMessage(msgA, 5, "idTimeout3");
|
||||||
|
|
||||||
for (const chunk of chunks) {
|
for (const chunk of chunks) {
|
||||||
|
|
@ -266,7 +328,11 @@ describe("ChunkAssembler", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("after timeout, late arriving fragments start a fresh assembly", () => {
|
it("after timeout, late arriving fragments start a fresh assembly", () => {
|
||||||
const original = { action: RelayMsgAction.SignCancel, sequence: 1, time: 1000 };
|
const original = {
|
||||||
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 1,
|
||||||
|
time: 1000,
|
||||||
|
};
|
||||||
const chunks = splitMessage(original, 5, "idReuse");
|
const chunks = splitMessage(original, 5, "idReuse");
|
||||||
|
|
||||||
// Send first fragment, let it time out
|
// Send first fragment, let it time out
|
||||||
|
|
@ -285,7 +351,11 @@ describe("ChunkAssembler", () => {
|
||||||
|
|
||||||
describe("duplicate fragment index", () => {
|
describe("duplicate fragment index", () => {
|
||||||
it("last write wins for duplicate index — still assembles correctly if content is the same", () => {
|
it("last write wins for duplicate index — still assembles correctly if content is the same", () => {
|
||||||
const original = { action: RelayMsgAction.SignCancel, sequence: 1, time: 1000 };
|
const original = {
|
||||||
|
action: RelayMsgAction.SignCancel,
|
||||||
|
sequence: 1,
|
||||||
|
time: 1000,
|
||||||
|
};
|
||||||
const chunks = splitMessage(original, 5, "idDup");
|
const chunks = splitMessage(original, 5, "idDup");
|
||||||
expect(chunks.length).toBeGreaterThan(1);
|
expect(chunks.length).toBeGreaterThan(1);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,10 @@ export class ChunkAssembler {
|
||||||
const { chunk_id, chunk_index, chunk_total, chunk_data } = chunk;
|
const { chunk_id, chunk_index, chunk_total, chunk_data } = chunk;
|
||||||
|
|
||||||
if (chunk_total < 1) {
|
if (chunk_total < 1) {
|
||||||
logError(Scope.Relay, `Invalid chunk_total ${chunk_total} for chunk_id ${chunk_id}`);
|
logError(
|
||||||
|
Scope.Relay,
|
||||||
|
`Invalid chunk_total ${chunk_total} for chunk_id ${chunk_id}`,
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,14 +84,20 @@ export class ChunkAssembler {
|
||||||
return this.pending.size;
|
return this.pending.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
private assemble(chunk_id: string, assembly: PendingAssembly): ProtocolMessage | null {
|
private assemble(
|
||||||
|
chunk_id: string,
|
||||||
|
assembly: PendingAssembly,
|
||||||
|
): ProtocolMessage | null {
|
||||||
this.discard(chunk_id);
|
this.discard(chunk_id);
|
||||||
|
|
||||||
const parts: string[] = [];
|
const parts: string[] = [];
|
||||||
for (let i = 0; i < assembly.total; i++) {
|
for (let i = 0; i < assembly.total; i++) {
|
||||||
const part = assembly.fragments.get(i);
|
const part = assembly.fragments.get(i);
|
||||||
if (part === undefined) {
|
if (part === undefined) {
|
||||||
logError(Scope.Relay, `Missing fragment index ${i} for chunk_id ${chunk_id}`);
|
logError(
|
||||||
|
Scope.Relay,
|
||||||
|
`Missing fragment index ${i} for chunk_id ${chunk_id}`,
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
parts.push(part);
|
parts.push(part);
|
||||||
|
|
@ -99,12 +108,18 @@ export class ChunkAssembler {
|
||||||
try {
|
try {
|
||||||
parsed = JSON.parse(json);
|
parsed = JSON.parse(json);
|
||||||
} catch {
|
} catch {
|
||||||
logError(Scope.Relay, `Failed to parse assembled message for chunk_id ${chunk_id}`);
|
logError(
|
||||||
|
Scope.Relay,
|
||||||
|
`Failed to parse assembled message for chunk_id ${chunk_id}`,
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isProtocolMessage(parsed)) {
|
if (!isProtocolMessage(parsed)) {
|
||||||
logError(Scope.Relay, `Assembled message for chunk_id ${chunk_id} is not a ProtocolMessage`);
|
logError(
|
||||||
|
Scope.Relay,
|
||||||
|
`Assembled message for chunk_id ${chunk_id} is not a ProtocolMessage`,
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -259,7 +259,10 @@ export class RelayClient extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageJson = JSON.stringify(message);
|
const messageJson = JSON.stringify(message);
|
||||||
if (messageJson.length > MAX_SAFE_MESSAGE_SIZE && this.peerSupportsChunking) {
|
if (
|
||||||
|
messageJson.length > MAX_SAFE_MESSAGE_SIZE &&
|
||||||
|
this.peerSupportsChunking
|
||||||
|
) {
|
||||||
return this.relayChunked(message.action, messageJson);
|
return this.relayChunked(message.action, messageJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -270,12 +273,18 @@ export class RelayClient extends EventEmitter {
|
||||||
return this.publishMessage(message);
|
return this.publishMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async relayChunked(originalAction: string, messageJson: string): Promise<void> {
|
private async relayChunked(
|
||||||
|
originalAction: string,
|
||||||
|
messageJson: string,
|
||||||
|
): Promise<void> {
|
||||||
const chunkId = Math.random().toString(36).slice(2, 14);
|
const chunkId = Math.random().toString(36).slice(2, 14);
|
||||||
const chunkTotal = Math.ceil(messageJson.length / CHUNK_SIZE);
|
const chunkTotal = Math.ceil(messageJson.length / CHUNK_SIZE);
|
||||||
const now = Math.floor(Date.now() / 1000);
|
const now = Math.floor(Date.now() / 1000);
|
||||||
|
|
||||||
debug(Scope.Relay, `Chunking ${originalAction} into ${chunkTotal} fragments (${messageJson.length} chars)`);
|
debug(
|
||||||
|
Scope.Relay,
|
||||||
|
`Chunking ${originalAction} into ${chunkTotal} fragments (${messageJson.length} chars)`,
|
||||||
|
);
|
||||||
|
|
||||||
for (let i = 0; i < chunkTotal; i++) {
|
for (let i = 0; i < chunkTotal; i++) {
|
||||||
const chunk: ChunkRelayMessage = {
|
const chunk: ChunkRelayMessage = {
|
||||||
|
|
@ -457,7 +466,10 @@ export class RelayClient extends EventEmitter {
|
||||||
if (isChunkRelayMessage(message)) {
|
if (isChunkRelayMessage(message)) {
|
||||||
const assembled = this.chunkAssembler.addChunk(message);
|
const assembled = this.chunkAssembler.addChunk(message);
|
||||||
if (assembled !== null) {
|
if (assembled !== null) {
|
||||||
this.netlog("recv", `${assembled.action} [reassembled from ${message.chunk_total} chunks]`);
|
this.netlog(
|
||||||
|
"recv",
|
||||||
|
`${assembled.action} [reassembled from ${message.chunk_total} chunks]`,
|
||||||
|
);
|
||||||
this.emit("message", assembled);
|
this.emit("message", assembled);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -474,7 +474,9 @@ export class DappConnectionManager extends EventEmitter<DappConnectionManagerEve
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable chunked sends if the wallet advertises the transport extension
|
// Enable chunked sends if the wallet advertises the transport extension
|
||||||
this.conn?.setPeerSupportsChunking(!!sessionData.extensions?.[EXTENSION_CHUNKED_MESSAGES]);
|
this.conn?.setPeerSupportsChunking(
|
||||||
|
!!sessionData.extensions?.[EXTENSION_CHUNKED_MESSAGES],
|
||||||
|
);
|
||||||
|
|
||||||
// Store raw paths for getSessionPaths() and xpub nodes for derivation
|
// Store raw paths for getSessionPaths() and xpub nodes for derivation
|
||||||
this.sessionPaths = [...sessionData.paths];
|
this.sessionPaths = [...sessionData.paths];
|
||||||
|
|
|
||||||
|
|
@ -124,8 +124,21 @@ async function sendLargeSignRequest(
|
||||||
contractName: "CauldronV4",
|
contractName: "CauldronV4",
|
||||||
constructorInputs: [{ name: "ownerPkh", type: "bytes20" }],
|
constructorInputs: [{ name: "ownerPkh", type: "bytes20" }],
|
||||||
abi: [
|
abi: [
|
||||||
{ name: "trade", inputs: [{ name: "isAdd", type: "bool" }, { name: "tokenAmount", type: "uint64" }, { name: "satoshiAmount", type: "uint64" }] },
|
{
|
||||||
{ name: "withdraw", inputs: [{ name: "sig", type: "datasig" }, { name: "pk", type: "pubkey" }] },
|
name: "trade",
|
||||||
|
inputs: [
|
||||||
|
{ name: "isAdd", type: "bool" },
|
||||||
|
{ name: "tokenAmount", type: "uint64" },
|
||||||
|
{ name: "satoshiAmount", type: "uint64" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "withdraw",
|
||||||
|
inputs: [
|
||||||
|
{ name: "sig", type: "datasig" },
|
||||||
|
{ name: "pk", type: "pubkey" },
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
bytecode: "d".repeat(500),
|
bytecode: "d".repeat(500),
|
||||||
source: "// CASL source\n" + "e".repeat(800),
|
source: "// CASL source\n" + "e".repeat(800),
|
||||||
|
|
@ -163,12 +176,18 @@ async function sendLargeSignRequest(
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
chalk.yellow(`→ sign_transaction_request (LARGE)`) +
|
chalk.yellow(`→ sign_transaction_request (LARGE)`) +
|
||||||
chalk.dim(` seq=${sequence} ${json.length} chars → ${chunkCount} chunk${chunkCount !== 1 ? "s" : ""}`),
|
chalk.dim(
|
||||||
|
` seq=${sequence} ${json.length} chars → ${chunkCount} chunk${chunkCount !== 1 ? "s" : ""}`,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await (client as any).relay(msg);
|
await (client as any).relay(msg);
|
||||||
console.log(chalk.green(` ✓ sent — if wallet receives seq=${sequence} with all ${sourceOutputs.length} sourceOutputs, chunking works`));
|
console.log(
|
||||||
|
chalk.green(
|
||||||
|
` ✓ sent — if wallet receives seq=${sequence} with all ${sourceOutputs.length} sourceOutputs, chunking works`,
|
||||||
|
),
|
||||||
|
);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.error(chalk.red(" ✗ send error:"), err.message);
|
console.error(chalk.red(" ✗ send error:"), err.message);
|
||||||
}
|
}
|
||||||
|
|
@ -197,7 +216,8 @@ function handleMessage(
|
||||||
| Hdwalletv1Session
|
| Hdwalletv1Session
|
||||||
| undefined;
|
| undefined;
|
||||||
const pathsSummary = hdwv1?.paths?.map((p) => p.name).join(",") ?? "none";
|
const pathsSummary = hdwv1?.paths?.map((p) => p.name).join(",") ?? "none";
|
||||||
const supportsChunking = hdwv1?.extensions?.[EXTENSION_CHUNKED_MESSAGES] !== undefined;
|
const supportsChunking =
|
||||||
|
hdwv1?.extensions?.[EXTENSION_CHUNKED_MESSAGES] !== undefined;
|
||||||
|
|
||||||
if (supportsChunking) {
|
if (supportsChunking) {
|
||||||
client.setPeerSupportsChunking(true);
|
client.setPeerSupportsChunking(true);
|
||||||
|
|
@ -210,7 +230,9 @@ function handleMessage(
|
||||||
` dapp_discovered=${msg.dapp_discovered}` +
|
` dapp_discovered=${msg.dapp_discovered}` +
|
||||||
` protocols=[${msg.supported_protocols.join(",")}]` +
|
` protocols=[${msg.supported_protocols.join(",")}]` +
|
||||||
` paths=[${pathsSummary}]` +
|
` paths=[${pathsSummary}]` +
|
||||||
(supportsChunking ? chalk.cyan(" chunking=✓") : chalk.dim(" chunking=✗")),
|
(supportsChunking
|
||||||
|
? chalk.cyan(" chunking=✓")
|
||||||
|
: chalk.dim(" chunking=✗")),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!msg.dapp_discovered) {
|
if (!msg.dapp_discovered) {
|
||||||
|
|
@ -230,7 +252,9 @@ function handleMessage(
|
||||||
|
|
||||||
if (sendLargeSign && state.walletReady) {
|
if (sendLargeSign && state.walletReady) {
|
||||||
console.log(
|
console.log(
|
||||||
chalk.dim(" (--large-sign: scheduling large sign request in 500ms...)"),
|
chalk.dim(
|
||||||
|
" (--large-sign: scheduling large sign request in 500ms...)",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
sendLargeSignRequest(client, state).catch(() => {});
|
sendLargeSignRequest(client, state).catch(() => {});
|
||||||
|
|
@ -279,9 +303,17 @@ export async function runDappMode(options: {
|
||||||
console.log(chalk.bold("\nwiz-test dapp mode"));
|
console.log(chalk.bold("\nwiz-test dapp mode"));
|
||||||
console.log(chalk.dim(`relay: ${options.relay}`));
|
console.log(chalk.dim(`relay: ${options.relay}`));
|
||||||
if (options.sign)
|
if (options.sign)
|
||||||
console.log(chalk.yellow("--sign: will send dummy sign request after wallet is ready"));
|
console.log(
|
||||||
|
chalk.yellow(
|
||||||
|
"--sign: will send dummy sign request after wallet is ready",
|
||||||
|
),
|
||||||
|
);
|
||||||
if (options.largeSign)
|
if (options.largeSign)
|
||||||
console.log(chalk.yellow("--large-sign: will send 30-contract-input sign request (chunking smoke test)"));
|
console.log(
|
||||||
|
chalk.yellow(
|
||||||
|
"--large-sign: will send 30-contract-input sign request (chunking smoke test)",
|
||||||
|
),
|
||||||
|
);
|
||||||
console.log();
|
console.log();
|
||||||
|
|
||||||
let connected = false;
|
let connected = false;
|
||||||
|
|
@ -361,7 +393,13 @@ export async function runDappMode(options: {
|
||||||
|
|
||||||
// Register message handler
|
// Register message handler
|
||||||
client.on("message", (message: ProtocolMessage) => {
|
client.on("message", (message: ProtocolMessage) => {
|
||||||
handleMessage(message, client, state, options.sign ?? false, options.largeSign ?? false);
|
handleMessage(
|
||||||
|
message,
|
||||||
|
client,
|
||||||
|
state,
|
||||||
|
options.sign ?? false,
|
||||||
|
options.largeSign ?? false,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send initial dapp_ready
|
// Send initial dapp_ready
|
||||||
|
|
|
||||||
|
|
@ -120,11 +120,14 @@ export async function runWalletMode(options: {
|
||||||
});
|
});
|
||||||
|
|
||||||
manager.on("pendingSignRequest", (request) => {
|
manager.on("pendingSignRequest", (request) => {
|
||||||
const sourceCount = (request.request.transaction as any)?.sourceOutputs?.length ?? "?";
|
const sourceCount =
|
||||||
|
(request.request.transaction as any)?.sourceOutputs?.length ?? "?";
|
||||||
const jsonSize = JSON.stringify(request.request).length;
|
const jsonSize = JSON.stringify(request.request).length;
|
||||||
console.log(
|
console.log(
|
||||||
chalk.yellow("← sign_request") +
|
chalk.yellow("← sign_request") +
|
||||||
chalk.dim(` conn=${request.connectionId} seq=${request.request.sequence}`) +
|
chalk.dim(
|
||||||
|
` conn=${request.connectionId} seq=${request.request.sequence}`,
|
||||||
|
) +
|
||||||
chalk.dim(` ${jsonSize} chars sourceOutputs=${sourceCount}`),
|
chalk.dim(` ${jsonSize} chars sourceOutputs=${sourceCount}`),
|
||||||
);
|
);
|
||||||
console.log(chalk.dim(" (auto-rejecting — test wallet does not sign)"));
|
console.log(chalk.dim(" (auto-rejecting — test wallet does not sign)"));
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue