mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-10 22:36:24 +00:00
17c7e46917
Requires the specific status-go changes that brings WCChangePairingState Process delete session and update internal pairing history state Updated testing while fighting for the issue of not deleting the session Found out that the client requests a different topic in the delete session request. Also: - update debugging UX to support session events - update storybook to support mocking session events - fix go test utility to account for refactoring Updates #12858
384 lines
15 KiB
HTML
384 lines
15 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<title>Wallet Connect status-go test</title>
|
|
<style></style>
|
|
</head>
|
|
<body>
|
|
<div id="log"></div>
|
|
<script src="bundle.js" type="module"></script>
|
|
<script>
|
|
// Helper functions
|
|
//
|
|
function goEcho(message) {
|
|
window.echo(message);
|
|
}
|
|
|
|
// If not null add to it
|
|
var logEntries = null;
|
|
|
|
var newSessionButton;
|
|
var hashedPasswordInput;
|
|
|
|
function addHtmlEntry(htmlContent, color = null, entry = null) {
|
|
const logDiv = document.getElementById("log");
|
|
if (entry) {
|
|
entry.remove();
|
|
}
|
|
entry = document.createElement("div");
|
|
logDiv.appendChild(entry);
|
|
entry.innerHTML = htmlContent;
|
|
if (color) {
|
|
entry.style.color = color;
|
|
}
|
|
entry.scrollIntoView();
|
|
if (logEntries) {
|
|
logEntries.push(entry);
|
|
}
|
|
return entry;
|
|
}
|
|
|
|
function addLogEntry(message, color = "black", entry = null) {
|
|
return addHtmlEntry(`${message}`, color, entry);
|
|
}
|
|
|
|
function logComponentStatusChange(componentName, statusMessage, color = "black", entry = null) {
|
|
const componentHtml = `<span style="color: fuchsia;">${componentName}</span>: `;
|
|
const statusHtml = `<span style="color: ${color};">${statusMessage}</span>`;
|
|
return addHtmlEntry(`${componentHtml}${statusHtml}`, null, entry);
|
|
}
|
|
|
|
// SDK initialization
|
|
//
|
|
const statusGoEntry = logComponentStatusChange("status-go", "Initializing...");
|
|
var initEventCount = 0;
|
|
var eventCount = 0;
|
|
const readyToPairEventName = "readyToPair";
|
|
async function initializeSDK() {
|
|
try {
|
|
const sdkEntry = logComponentStatusChange("SDK", "Initializing...");
|
|
const conf = await window.getConfiguration();
|
|
await window.wc.init(conf.projectId);
|
|
logComponentStatusChange("SDK", "Initialized", "green", sdkEntry);
|
|
initEventCount++;
|
|
} catch (error) {
|
|
goEcho(`SDK init error: ${error}`);
|
|
logComponentStatusChange("SDK", "FAIL initializing ${error}", "red", sdkEntry);
|
|
}
|
|
}
|
|
|
|
// Simulate statusObject
|
|
window.statusq = {
|
|
channel: {
|
|
objects: {
|
|
statusObject: {
|
|
sdkInitialized: function (error) {
|
|
window.statusObject_sdkInitialized(error);
|
|
},
|
|
onSessionProposal: function (sessionProposal) {
|
|
window.statusObject_onSessionProposal(JSON.stringify(sessionProposal)).then((success) => {
|
|
if (!success) {
|
|
goEcho(`statusObject: onSessionProposal call failed ${sessionProposal.id}`);
|
|
return;
|
|
}
|
|
});
|
|
},
|
|
onSessionRequest: function (sessionRequest) {
|
|
eventCount++;
|
|
|
|
logComponentStatusChange("SDK", `received "session_request" event`, "green");
|
|
addLogEntry(`Data: ${JSON.stringify(sessionRequest)}`);
|
|
|
|
addHtmlEntry(
|
|
`<button id="acceptSessionButton${eventCount}">Accept</button> <button id="rejectSessionButton${eventCount}">Reject</button>`
|
|
);
|
|
|
|
const acceptSessionButton = document.getElementById(`acceptSessionButton${eventCount}`);
|
|
const rejectSessionButton = document.getElementById(`rejectSessionButton${eventCount}`);
|
|
acceptSessionButton.addEventListener("click", function () {
|
|
const sessionReqEntry = logComponentStatusChange("status-go", `sessionRequest called`, "orange");
|
|
window.sessionRequest(JSON.stringify(sessionRequest), hashedPasswordInput.value).then((success) => {
|
|
acceptSessionButton.disabled = true;
|
|
rejectSessionButton.disabled = true;
|
|
|
|
if (success) {
|
|
logComponentStatusChange("status-go", `sessionRequest OK`, "green", sessionReqEntry);
|
|
// waiting for "sessionRequestResult" event
|
|
} else {
|
|
logComponentStatusChange(
|
|
"status-go",
|
|
`sessionRequest call failed for topic ${sessionRequest.topic}`,
|
|
"red",
|
|
sessionReqEntry
|
|
);
|
|
window.wc.rejectSessionRequest(sessionRequest.topic, sessionRequest.id, true);
|
|
setStatus(`Session ${sessionRequest.id} rejected, internal error`, "purple");
|
|
}
|
|
});
|
|
});
|
|
|
|
rejectSessionButton.addEventListener("click", function () {
|
|
acceptSessionButton.disabled = true;
|
|
rejectSessionButton.disabled = true;
|
|
window.wc.rejectSessionRequest(sessionRequest.topic, sessionRequest.id).then(
|
|
() => {
|
|
addLogEntry(`Session ${sessionRequest.id} rejected`);
|
|
},
|
|
(err) => {
|
|
addLogEntry(`Session ${sessionRequest.id} reject error: ${err.message}`, "red");
|
|
}
|
|
);
|
|
});
|
|
},
|
|
onSessionDelete: function (deletePayload) {
|
|
goEcho(`statusObject: onSessionDelete ${JSON.stringify(deletePayload)}`);
|
|
},
|
|
onSessionExpire: function (expirePayload) {
|
|
goEcho(`statusObject: onSessionExpire ${JSON.stringify(expirePayload)}`);
|
|
},
|
|
onSessionUpdate: function (updatePayload) {
|
|
goEcho(`statusObject: onSessionUpdate ${JSON.stringify(updatePayload)}`);
|
|
},
|
|
onSessionExtend: function (extendPayload) {
|
|
goEcho(`statusObject: onSessionExtend ${JSON.stringify(extendPayload)}`);
|
|
},
|
|
onSessionPing: function (pingPayload) {
|
|
goEcho(`statusObject: onSessionPing ${JSON.stringify(pingPayload)}`);
|
|
},
|
|
onSessionEvent: function (eventPayload) {
|
|
goEcho(`statusObject: onSessionEvent ${JSON.stringify(eventPayload)}`);
|
|
},
|
|
onSessionRequest: function (sessionRequestPayload) {
|
|
goEcho(`statusObject: onSessionRequest ${JSON.stringify(sessionRequestPayload)}`);
|
|
},
|
|
onSessionRequestSent: function (sessionRequestSentPayload) {
|
|
goEcho(`statusObject: onSessionRequestSent ${JSON.stringify(sessionRequestSentPayload)}`);
|
|
},
|
|
onProposalExpire: function (proposalExpirePayload) {
|
|
goEcho(`statusObject: onProposalExpire ${JSON.stringify(proposalExpirePayload)}`);
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
var pairLinkInput = null;
|
|
var pairButton = null;
|
|
function newPairWorkflow() {
|
|
// Remove all the previous entries
|
|
if (logEntries) {
|
|
for (let i = 0; i < logEntries.length; i++) {
|
|
logEntries[i].remove();
|
|
}
|
|
}
|
|
logEntries = [];
|
|
eventCount++;
|
|
|
|
// Add session reset and password input
|
|
addHtmlEntry(`<button id="newSessionButton" style="display: none;">New Session</button>`);
|
|
newSessionButton = document.getElementById("newSessionButton");
|
|
newSessionButton.addEventListener("click", function () {
|
|
newPairWorkflow();
|
|
});
|
|
addHtmlEntry(
|
|
`<input type="text" id="hashedPasswordInput" placeholder="Insert hashed password" value="0x38301fb0b5fcf3aaa4b97c4771bb6c75546e313b4ce7057c51a8cc6a3ace9d7e"/>`
|
|
);
|
|
hashedPasswordInput = document.getElementById(`hashedPasswordInput`);
|
|
|
|
addHtmlEntry(
|
|
`<input type="text" id="pairLinkInput" placeholder="Insert pair link" /><button id="pairButton" disabled>Pair</button>`
|
|
);
|
|
|
|
// List existing pairing sessions
|
|
const pairingsRes = window.wc.getPairings();
|
|
let pairings = [];
|
|
if (pairingsRes) {
|
|
if (!!pairingsRes.error) {
|
|
goEcho(`getPairings() error: ${pairingsRes.error}`);
|
|
return;
|
|
} else if (pairingsRes.result) {
|
|
pairings = pairingsRes.result;
|
|
}
|
|
}
|
|
if (pairings.length > 0) {
|
|
addHtmlEntry(`Existing pairings:`, "fuchsia");
|
|
}
|
|
for (let i = 0; i < pairings.length; i++) {
|
|
const p = pairings[i];
|
|
const disconnectEntry = addHtmlEntry(
|
|
`[${i + 1}] <span style="color: ${p.active ? "green" : "orange"};">${
|
|
p.active ? "ACTIVE" : "INACTIVE"
|
|
}</span> <span class="elide-text">${p.topic}</span>; Expires: ${timestampToStr(
|
|
p.expiry
|
|
)} <button id="unpairButton${i}">Disconnect</button>`
|
|
);
|
|
const unpairButton = document.getElementById(`unpairButton${i}`);
|
|
unpairButton.addEventListener("click", function () {
|
|
const res = window.wc.disconnect(p.topic);
|
|
if (res && !!res.error) {
|
|
addLogEntry(`Pairing ${p.topic} disconnect error: ${err.message}`, "red", disconnectEntry);
|
|
return;
|
|
}
|
|
addLogEntry(`Pairing ${p.topic} disconnected`, "green", disconnectEntry);
|
|
unpairButton.remove();
|
|
});
|
|
}
|
|
|
|
// Add pairing options
|
|
pairLinkInput = document.getElementById(`pairLinkInput`);
|
|
pairButton = document.getElementById(`pairButton`);
|
|
pairLinkInput.addEventListener("input", function () {
|
|
pairButton.disabled = !(pairLinkInput.value.length > 0);
|
|
});
|
|
pairButton.addEventListener("click", function () {
|
|
newSessionButton.style.display = "inline";
|
|
pairButton.disabled = true;
|
|
pairLinkInput.disabled = true;
|
|
|
|
const sdkEntry = logComponentStatusChange("SDK", "Pairing...");
|
|
const result = window.wc.pair(pairLinkInput.value);
|
|
if (result && !!result.error) {
|
|
goEcho("pair() error: ", result.error);
|
|
logComponentStatusChange("SDK", `Pairing error ${error.message}`, "red", sdkEntry);
|
|
return;
|
|
}
|
|
|
|
logComponentStatusChange("SDK", "got Pair session proposal", "green", sdkEntry);
|
|
const goSessionEntry = logComponentStatusChange("GO.pairSessionProposal", "waiting status-go", "pink");
|
|
});
|
|
}
|
|
|
|
document.addEventListener(`proposeUserPair`, function (event) {
|
|
logComponentStatusChange("GO.proposeUserPair", `received "proposeUserPair"`, "green");
|
|
addLogEntry(JSON.stringify(event.detail.supportedNamespaces));
|
|
if (!document.getElementById(`acceptPairButton`)) {
|
|
addHtmlEntry(`<button id="acceptPairButton">Accept</button><button id="rejectPairButton">Reject</button>`);
|
|
}
|
|
const acceptPairButton = document.getElementById(`acceptPairButton`);
|
|
const rejectPairButton = document.getElementById(`rejectPairButton`);
|
|
const sessionProposal = event.detail.sessionProposal;
|
|
acceptPairButton.addEventListener("click", function () {
|
|
const result = window.wc.approvePairSession(sessionProposal, event.detail.supportedNamespaces);
|
|
if (result && !!result.error) {
|
|
logComponentStatusChange(
|
|
"GO.pairSessionProposal",
|
|
`Pair session ${sessionProposal.id} approve error: ${result.error}`,
|
|
"red",
|
|
goSessionEntry
|
|
);
|
|
return;
|
|
}
|
|
acceptPairButton.remove();
|
|
rejectPairButton.remove();
|
|
|
|
root.controller_recordSuccessfulPairing(JSON.stringify(sessionProposal));
|
|
|
|
logComponentStatusChange(
|
|
"GO.pairSessionProposal",
|
|
`Pair session ${sessionProposal.id} approved`,
|
|
"green",
|
|
goSessionEntry
|
|
);
|
|
});
|
|
rejectPairButton.addEventListener("click", function () {
|
|
const result = window.wc.rejectPairSession(sessionProposal.id);
|
|
if (result && !!result.error) {
|
|
logComponentStatusChange(
|
|
"GO.pairSessionProposal",
|
|
`Pair session ${sessionProposal.id} reject error: ${result.error}`,
|
|
"red",
|
|
goSessionEntry
|
|
);
|
|
return;
|
|
}
|
|
|
|
acceptPairButton.remove();
|
|
rejectPairButton.remove();
|
|
|
|
logComponentStatusChange(
|
|
"GO.pairSessionProposal",
|
|
`Pair session ${sessionProposal.id} rejected`,
|
|
"green",
|
|
goSessionEntry
|
|
);
|
|
});
|
|
});
|
|
|
|
document.addEventListener("sessionRequestResult", function (event) {
|
|
let req = event.detail.sessionRequest;
|
|
const res = window.wc.respondSessionRequest(req.topic, req.id, event.detail.signed);
|
|
addLogEntry(`Session ${req.topic} approval accepted`);
|
|
addHtmlEntry(
|
|
`</br><a href="https://goerli.etherscan.io/tx/${event.detail.signed}" target="_blank">${event.detail.signed}</a>`
|
|
);
|
|
});
|
|
|
|
// Add start from scratch option
|
|
document.addEventListener(readyToPairEventName, function () {
|
|
newPairWorkflow();
|
|
});
|
|
|
|
async function processGoEvents() {
|
|
while (true) {
|
|
try {
|
|
const event = await window.popNextEvent();
|
|
switch (event.name) {
|
|
case "nodeReady":
|
|
logComponentStatusChange("status-go", "Ready", "green", statusGoEntry);
|
|
initEventCount++;
|
|
break;
|
|
default:
|
|
// Handle status-go and SDK bootstrap events
|
|
if (initEventCount == 2) {
|
|
initEventCount++;
|
|
document.dispatchEvent(new CustomEvent(readyToPairEventName, {}));
|
|
} else if (event.name != "") {
|
|
goEcho(`GO event: ${event.name}`);
|
|
document.dispatchEvent(new CustomEvent(event.name, { detail: event.payload }));
|
|
} else {
|
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
}
|
|
break;
|
|
}
|
|
} catch (err) {
|
|
goEcho(`GO event error: ${err.message}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
processGoEvents();
|
|
|
|
// Call the initializeSDK function on page load
|
|
window.addEventListener("DOMContentLoaded", (event) => {
|
|
initializeSDK();
|
|
});
|
|
|
|
function timestampToStr(timestamp) {
|
|
const date = new Date(timestamp * 1000);
|
|
const readableDate = date.toLocaleDateString();
|
|
const readableTime = date.toLocaleTimeString();
|
|
|
|
return `${readableDate} - ${readableTime}`;
|
|
}
|
|
</script>
|
|
</body>
|
|
<style>
|
|
.elide-text {
|
|
max-width: 100px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
display: inline-block;
|
|
transition: max-width 0.3s ease;
|
|
vertical-align: middle;
|
|
}
|
|
.elide-text:hover {
|
|
max-width: none;
|
|
background-color: #f0f0f0;
|
|
z-index: 1;
|
|
position: relative;
|
|
}
|
|
</style>
|
|
</html>
|