diff --git a/__tests__/utils/starknetId.test.ts b/__tests__/utils/starknetId.test.ts index 24f969a64..3b678328d 100644 --- a/__tests__/utils/starknetId.test.ts +++ b/__tests__/utils/starknetId.test.ts @@ -1,27 +1,42 @@ +import { BN } from 'bn.js'; + import { StarknetChainId } from '../../src/constants'; import { getStarknetIdContract, useDecoded, useEncoded } from '../../src/utils/starknetId'; -const characters = 'abcdefghijklmnopqrstuvwxyz0123456789-这来'; +function randomWithSeed(seed: number) { + const x = Math.sin(seed) * 10000; + return x - Math.floor(x); +} + +function generateString(length: number, seed: number): string { + const characters = 'abcdefghijklmnopqrstuvwxyz0123456789-这来'; -function generateString(length: number): string { let result = ''; const charactersLength = characters.length; for (let i = 0; i < length; i += 1) { - result += characters.charAt(Math.floor(Math.random() * charactersLength)); + result += characters.charAt(Math.floor(randomWithSeed(seed + i) * charactersLength)); } return result; } describe('Should tets StarknetId utils', () => { - test('Should test useEncoded and useDecoded hook with 100 random strings', () => { - for (let index = 0; index < 100; index += 1) { - const randomString = generateString(10); - + test('Should test useEncoded and useDecoded hook with a random string', () => { + for (let index = 0; index < 2500; index += 1) { + const randomString = generateString(10, index); expect(useDecoded([useEncoded(randomString)])).toBe(randomString.concat('.stark')); } }); + test('Should test useDecoded and useEncoded hook with an encoded number', () => { + for (let index = 0; index < 2500; index += 1) { + const decoded = useDecoded([new BN(index)]); + expect(useEncoded(decoded.substring(0, decoded.length - 6)).toString()).toBe( + index.toString() + ); + } + }); + test('Should test getStarknetIdContract', () => { expect(getStarknetIdContract(StarknetChainId.TESTNET)).toBe( '0x05cf267a0af6101667013fc6bd3f6c11116a14cda9b8c4b1198520d59f900b17' diff --git a/src/utils/starknetId.ts b/src/utils/starknetId.ts index 15180b7a7..bdbc6c89a 100644 --- a/src/utils/starknetId.ts +++ b/src/utils/starknetId.ts @@ -10,8 +10,18 @@ const basicAlphabetSize = new BN(basicAlphabet.length); const bigAlphabetSize = new BN(bigAlphabet.length); const bigAlphabetSizePlusOne = new BN(bigAlphabet.length + 1); +function extractStars(str: string): [string, number] { + let k = 0; + while (str.endsWith(bigAlphabet[bigAlphabet.length - 1])) { + str = str.substring(0, str.length - 1); + k += 1; + } + return [str, k]; +} + export function useDecoded(encoded: BN[]): string { let decoded = ''; + encoded.forEach((subdomain) => { while (!subdomain.isZero()) { const code = subdomain.mod(basicSizePlusOne).toNumber(); @@ -30,9 +40,18 @@ export function useDecoded(encoded: BN[]): string { } } else decoded += basicAlphabet[code]; } + + const [str, k] = extractStars(decoded); + if (k) + decoded = + str + + (k % 2 === 0 + ? bigAlphabet[bigAlphabet.length - 1].repeat(k / 2 - 1) + + bigAlphabet[0] + + basicAlphabet[1] + : bigAlphabet[bigAlphabet.length - 1].repeat((k - 1) / 2 + 1)); decoded += '.'; }); - return decoded.concat('stark'); } @@ -40,6 +59,14 @@ export function useEncoded(decoded: string): BN { let encoded = new BN(0); let multiplier = new BN(1); + if (decoded.endsWith(bigAlphabet[0] + basicAlphabet[1])) { + const [str, k] = extractStars(decoded.substring(0, decoded.length - 2)); + decoded = str + bigAlphabet[bigAlphabet.length - 1].repeat(2 * (k + 1)); + } else { + const [str, k] = extractStars(decoded); + if (k) decoded = str + bigAlphabet[bigAlphabet.length - 1].repeat(1 + 2 * (k - 1)); + } + for (let i = 0; i < decoded.length; i += 1) { const char = decoded[i]; const index = basicAlphabet.indexOf(char);