From 28b167849ca08e1b484f69f53660a8c28660119d Mon Sep 17 00:00:00 2001 From: DR497 <47689875+dr497@users.noreply.github.com> Date: Mon, 29 Jan 2024 13:26:43 +0800 Subject: [PATCH] fix: deserialization for records v1 CNAME and TXT --- js/src/record.ts | 8 +++-- js/tests/records-v2.test.ts | 65 ++++++++++++++++++++++++++++--------- js/tests/records.test.ts | 49 +++++++++++++++++++++++++++- 3 files changed, 103 insertions(+), 19 deletions(-) diff --git a/js/src/record.ts b/js/src/record.ts index 3a458757..87edc7ed 100644 --- a/js/src/record.ts +++ b/js/src/record.ts @@ -9,7 +9,7 @@ import { fromByteArray as ipFromByteArray, parse as parseIp, } from "ipaddr.js"; -import { encode as encodePunycode } from "punycode"; +import { encode as encodePunycode, decode as decodePunnyCode } from "punycode"; import { check } from "./utils"; import { ErrorType, SNSError } from "./error"; import { ed25519 } from "@noble/curves/ed25519"; @@ -396,7 +396,11 @@ export const deserializeRecord = ( const idx = trimNullPaddingIdx(buffer); if (!size) { - return buffer.slice(0, idx).toString("utf-8"); + const str = buffer.slice(0, idx).toString("utf-8"); + if (record === Record.CNAME || record === Record.TXT) { + return decodePunnyCode(str); + } + return str; } // Handle SOL record first whether it's over allocated or not diff --git a/js/tests/records-v2.test.ts b/js/tests/records-v2.test.ts index 9ecb1fc6..e678c38b 100644 --- a/js/tests/records-v2.test.ts +++ b/js/tests/records-v2.test.ts @@ -22,22 +22,55 @@ jest.setTimeout(50_000); const connection = new Connection(process.env.RPC_URL!); test("Records V2 des/ser", () => { - let content = "this is a test"; - let ser = serializeRecordV2Content(content, Record.TXT); - let des = deserializeRecordV2Content(Buffer.from(ser), Record.TXT); - expect(des).toBe(content); - - content = Keypair.generate().publicKey.toBase58(); - ser = serializeRecordV2Content(content, Record.SOL); - des = deserializeRecordV2Content(Buffer.from(ser), Record.SOL); - expect(des).toBe(content); - expect(ser.length).toBe(32); - - content = "inj13glcnaum2xqv5a0n0hdsmv0f6nfacjsfvrh5j9"; - ser = serializeRecordV2Content(content, Record.Injective); - expect(ser.length).toBe(20); - des = deserializeRecordV2Content(ser, Record.Injective); - expect(des).toBe(content); + const items = [ + { content: "this is a test", record: Record.TXT }, + { + content: Keypair.generate().publicKey.toBase58(), + record: Record.SOL, + length: 32, + }, + { + content: "inj13glcnaum2xqv5a0n0hdsmv0f6nfacjsfvrh5j9", + record: Record.Injective, + length: 20, + }, + { + content: "example.com", + record: Record.CNAME, + }, + { + content: "example.com", + record: Record.CNAME, + }, + { + content: "0xc0ffee254729296a45a3885639ac7e10f9d54979", + record: Record.ETH, + length: 20, + }, + { + content: "1.1.1.4", + record: Record.A, + length: 4, + }, + { + content: "2345:425:2ca1::567:5673:23b5", + record: Record.AAAA, + length: 16, + }, + { + content: "username", + record: Record.Discord, + }, + ]; + + items.forEach((e) => { + const ser = serializeRecordV2Content(e.content, e.record); + const des = deserializeRecordV2Content(ser, e.record); + expect(des).toBe(e.content); + if (e.length) { + expect(ser.length).toBe(e.length); + } + }); }); test("Create record", async () => { diff --git a/js/tests/records.test.ts b/js/tests/records.test.ts index 5f9245a4..b92e5d34 100644 --- a/js/tests/records.test.ts +++ b/js/tests/records.test.ts @@ -1,10 +1,11 @@ require("dotenv").config(); import { test, jest, expect } from "@jest/globals"; import * as record from "../src/record"; -import { Connection, PublicKey, Transaction } from "@solana/web3.js"; +import { Connection, Keypair, PublicKey, Transaction } from "@solana/web3.js"; import { Record } from "../src/types/record"; import { createRecordInstruction } from "../src/bindings"; import { resolveSolRecordV1 } from "../src/resolve"; +import { NameRegistryState } from "../src/state"; jest.setTimeout(20_000); @@ -115,3 +116,49 @@ test("Check sol record", async () => { "Hf4daCT4tC2Vy9RCe9q8avT68yAsNJ1dQe6xiQqyGuqZ", ); }); + +test("Des/ser", () => { + const items = [ + { content: "this is a test", record: Record.TXT }, + { + content: "inj13glcnaum2xqv5a0n0hdsmv0f6nfacjsfvrh5j9", + record: Record.Injective, + }, + { + content: "example.com", + record: Record.CNAME, + }, + { + content: "example.com", + record: Record.CNAME, + }, + { + content: "0xc0ffee254729296a45a3885639ac7e10f9d54979", + record: Record.ETH, + }, + { + content: "1.1.1.4", + record: Record.A, + }, + { + content: "2345:425:2ca1::567:5673:23b5", + record: Record.AAAA, + }, + { + content: "username", + record: Record.Discord, + }, + ]; + + items.forEach((e) => { + const ser = record.serializeRecord(e.content, e.record); + const registry: NameRegistryState = { + data: ser, + parentName: PublicKey.default, + class: PublicKey.default, + owner: PublicKey.default, + }; + const des = record.deserializeRecord(registry, e.record, PublicKey.default); + expect(des).toBe(e.content); + }); +});