Skip to content

Commit 08b9740

Browse files
committed
chore(demo): obfuscate addresses
1 parent f02abf3 commit 08b9740

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

src/lib/Demo.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ function setupSingleMutationObserver() {
153153
setupVisualCues(processedElements);
154154
disableSwapTriggers(processedElements);
155155
enableSellAndSwapModals(processedElements);
156+
obfuscateAddresses(processedElements);
156157
};
157158

158159
// Create one mutation observer for all DOM modifications
@@ -1117,6 +1118,17 @@ const demoCSS = `
11171118
display: none;
11181119
}
11191120
1121+
/* Demo address tooltip styling */
1122+
.tooltip.demo-tooltip {
1123+
width: max-content;
1124+
background: var(--nimiq-orange-bg);
1125+
margin-left: -7rem;
1126+
}
1127+
1128+
.tooltip.demo-tooltip::after {
1129+
background: #fc750c; /* Match the red theme for the demo warning */
1130+
}
1131+
11201132
.demo-highlight-badge {
11211133
position: absolute;
11221134
width: 34px;
@@ -1843,3 +1855,78 @@ export class DemoHubApi extends HubApi {
18431855
});
18441856
}
18451857
}
1858+
1859+
/**
1860+
* Obfuscates addresses in the UI by:
1861+
* - Showing only first 3 chunks of addresses (rest are XXXX) for NIM addresses
1862+
* - Showing only the first few characters for BTC and polygon addresses
1863+
* - Changing the copy tooltip message
1864+
* - Changing the copy functionality to provide a demo disclaimer
1865+
*/
1866+
function obfuscateAddresses(processedElements: WeakSet<HTMLElement>) {
1867+
// Adds the common clipboard click handler to an element.
1868+
function addDemoClickHandler(el: HTMLElement) {
1869+
el.addEventListener('click', (e: MouseEvent) => {
1870+
e.preventDefault();
1871+
e.stopPropagation();
1872+
el.classList.add('copied');
1873+
setTimeout(() => el.classList.remove('copied'), 1500);
1874+
navigator.clipboard.writeText('This is a demo address - not for actual use');
1875+
}, true);
1876+
}
1877+
1878+
// Updates the tooltip for an element.
1879+
function updateTooltip(el: HTMLElement) {
1880+
const tooltip = el.querySelector('.tooltip') as HTMLElement;
1881+
if (tooltip && !processedElements.has(tooltip)) {
1882+
processedElements.add(tooltip);
1883+
tooltip.textContent = 'Demo address';
1884+
tooltip.classList.add('demo-tooltip');
1885+
addDemoClickHandler(tooltip);
1886+
}
1887+
}
1888+
1889+
// Processes an element: marks it as processed, applies any extra changes, updates tooltip, and adds a click handler.
1890+
function processElement(el: HTMLElement, extraProcess: ((el: HTMLElement) => void) | null = null) {
1891+
if (processedElements.has(el)) return;
1892+
processedElements.add(el);
1893+
if (extraProcess) extraProcess(el);
1894+
updateTooltip(el);
1895+
addDemoClickHandler(el);
1896+
}
1897+
1898+
// Process NIM address displays: obfuscate address chunks beyond the first three.
1899+
const nimAddressElements = document.querySelectorAll('.copyable.address-display') as NodeListOf<HTMLElement>;
1900+
nimAddressElements.forEach(el =>
1901+
processElement(el, (element) => {
1902+
const chunks = element.querySelectorAll('.chunk');
1903+
for (let i = 3; i < chunks.length; i++) {
1904+
const chunk = chunks[i];
1905+
const space = chunk.querySelector('.space');
1906+
chunk.textContent = 'XXXX';
1907+
if (space) chunk.appendChild(space);
1908+
}
1909+
})
1910+
);
1911+
1912+
// Process short address displays: change the last chunk of the short address.
1913+
const shortAddressElements = document.querySelectorAll('.tooltip.interactive-short-address.is-copyable') as NodeListOf<HTMLElement>;
1914+
shortAddressElements.forEach(el =>
1915+
processElement(el, (element) => {
1916+
const lastChunk = element.querySelector('.short-address .address:last-child');
1917+
if (lastChunk) {
1918+
lastChunk.textContent = 'xxxx';
1919+
}
1920+
})
1921+
);
1922+
1923+
// Process tooltip boxes inside short address displays.
1924+
const tooltipBoxElements = document.querySelectorAll('.tooltip.interactive-short-address.is-copyable .tooltip-box') as NodeListOf<HTMLElement>;
1925+
tooltipBoxElements.forEach(el => {
1926+
if (processedElements.has(el)) return;
1927+
processedElements.add(el);
1928+
el.textContent = 'Demo address';
1929+
el.classList.add('demo-tooltip');
1930+
addDemoClickHandler(el);
1931+
});
1932+
}

0 commit comments

Comments
 (0)