Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/__tests__/storageKeys.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { fingerprint, expiryNotifiedStorageKey } from '../lib/storageKeys';

const WALLET_A = 'GBRPYHIL2CI3FNQ4BXLFMNDLFJUNPU2HY3ZMFSHONUCEOASW7QC7OX2H';
const WALLET_B = 'GCKFBEIYTKP5RDBQMTVVALONAOPBXICILMAFL6ANEHMIYX7XFBZ7ZMGT';

describe('storageKeys (#548)', () => {
it('does not include the raw wallet address in the expiry storage key', () => {
const key = expiryNotifiedStorageKey(WALLET_A);
expect(key.startsWith('ps_expiry_notified_')).toBe(true);
expect(key).not.toContain(WALLET_A);
expect(key).not.toContain(WALLET_A.slice(0, 8));
});

it('is deterministic per wallet so notifications persist across renders', () => {
expect(expiryNotifiedStorageKey(WALLET_A)).toBe(expiryNotifiedStorageKey(WALLET_A));
});

it('gives different wallets different keys', () => {
expect(expiryNotifiedStorageKey(WALLET_A)).not.toBe(expiryNotifiedStorageKey(WALLET_B));
expect(fingerprint('a')).not.toBe(fingerprint('b'));
});
});
24 changes: 24 additions & 0 deletions src/lib/storageKeys.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Non-reversible, deterministic fingerprint of a string (cyrb53, 53-bit).
* Used to scope browser-storage keys per wallet without writing the raw
* address into the key name, where it is visible to anyone inspecting
* DevTools > Application > Storage (#548). Not a cryptographic hash -- it only
* needs to be stable and collision-resistant across a handful of wallets.
*/
export function fingerprint(value: string): string {
let h1 = 0xdeadbeef;
let h2 = 0x41c6ce57;
for (let i = 0; i < value.length; i++) {
const ch = value.charCodeAt(i);
h1 = Math.imul(h1 ^ ch, 2654435761);
h2 = Math.imul(h2 ^ ch, 1597334677);
}
h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);
return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(36);
}

/** sessionStorage key for the policy IDs already warned about for a wallet. */
export function expiryNotifiedStorageKey(address: string): string {
return `ps_expiry_notified_${fingerprint(address)}`;
}