change url separator to semicolon

This commit is contained in:
Alain Brenzikofer
2026-06-11 09:11:01 +02:00
parent 4b835bcef7
commit 1aec2eb638
2 changed files with 34 additions and 27 deletions
+14 -8
View File
@@ -19,7 +19,7 @@ and returns a flat JSON document with these fields:
`simplexContact` and `simplexChannel` are arrays so a name can advertise
multiple SMP servers for redundancy. Clients SHOULD try the URLs in the
order returned. The on-chain text record stores them as a single
comma-separated string; this resolver splits and trims into a list.
`LINK_SEPARATOR` (`;`)-joined string; this resolver splits and trims into a list.
All keys are valid Haskell record-field identifiers (lowercase initial,
no dots), so consumers can derive aeson FromJSON instances directly
@@ -372,16 +372,22 @@ TEXT_KEYS = [
]
def split_csv(value: str) -> list:
"""Split a comma-separated text record into an ordered list of entries.
# Separator that joins the SMP-server URL list inside a simplex.contact /
# simplex.channel text record. MUST match SIMPLEX_LINK_SEPARATOR in the dApp
# (ens-app-v3 src/constants/simplex.ts) — the two sides decode the same record.
LINK_SEPARATOR = ";"
def split_links(value: str) -> list:
"""Split a separator-joined text record into an ordered list of entries.
Trims whitespace around each element and drops empties so trailing
commas, doubled commas, and all-whitespace inputs all yield clean
separators, doubled separators, and all-whitespace inputs all yield clean
output. Single-value records yield a 1-element list; empty inputs
yield `[]`. Used for `simplex.contact` / `simplex.channel`, which
store one-or-more SMP-server URLs as a single comma-joined string.
store one-or-more SMP-server URLs as a single `LINK_SEPARATOR`-joined string.
"""
return [item.strip() for item in value.split(",") if item.strip()]
return [item.strip() for item in value.split(LINK_SEPARATOR) if item.strip()]
def resolve(name: str):
@@ -429,8 +435,8 @@ def resolve(name: str):
"nickname": nickname,
"website": texts.get("url", ""),
"location": texts.get("location", ""),
"simplexContact": split_csv(texts.get("simplex.contact", "")),
"simplexChannel": split_csv(texts.get("simplex.channel", "")),
"simplexContact": split_links(texts.get("simplex.contact", "")),
"simplexChannel": split_links(texts.get("simplex.channel", "")),
"eth": addr_multicoin(resolver_addr, node, COIN_ETH),
"btc": addr_multicoin(resolver_addr, node, COIN_BTC),
"xmr": addr_multicoin(resolver_addr, node, COIN_XMR),
+20 -19
View File
@@ -17,28 +17,29 @@ snrc = importlib.util.module_from_spec(_SPEC)
_SPEC.loader.exec_module(snrc)
class SplitCsvTests(unittest.TestCase):
"""`split_csv` decodes the multi-URL convention for simplex.contact /
class SplitLinksTests(unittest.TestCase):
"""`split_links` decodes the multi-URL convention for simplex.contact /
simplex.channel text records. Reuses the same rule the dApp's
`parseSimplexUrls` will use, so the two sides round-trip cleanly."""
`parseSimplexUrls` uses (separator `;`), so the two sides round-trip
cleanly."""
def test_empty_string_yields_empty_list(self):
self.assertEqual(snrc.split_csv(""), [])
self.assertEqual(snrc.split_links(""), [])
def test_whitespace_only_yields_empty_list(self):
self.assertEqual(snrc.split_csv(" "), [])
self.assertEqual(snrc.split_csv(" , , "), [])
self.assertEqual(snrc.split_links(" "), [])
self.assertEqual(snrc.split_links(" ; ; "), [])
def test_single_url_yields_singleton_list(self):
self.assertEqual(
snrc.split_csv("https://smp16.simplex.im/a#H1"),
snrc.split_links("https://smp16.simplex.im/a#H1"),
["https://smp16.simplex.im/a#H1"],
)
def test_two_urls_split_on_comma(self):
def test_two_urls_split_on_separator(self):
self.assertEqual(
snrc.split_csv(
"https://smp16.simplex.im/a#H1,https://smp19.simplex.im/a#H1"
snrc.split_links(
"https://smp16.simplex.im/a#H1;https://smp19.simplex.im/a#H1"
),
[
"https://smp16.simplex.im/a#H1",
@@ -46,10 +47,10 @@ class SplitCsvTests(unittest.TestCase):
],
)
def test_whitespace_around_commas_is_trimmed(self):
def test_whitespace_around_separators_is_trimmed(self):
self.assertEqual(
snrc.split_csv(
" https://smp16.simplex.im/a#H1 ,\thttps://smp19.simplex.im/a#H1 "
snrc.split_links(
" https://smp16.simplex.im/a#H1 ;\thttps://smp19.simplex.im/a#H1 "
),
[
"https://smp16.simplex.im/a#H1",
@@ -57,16 +58,16 @@ class SplitCsvTests(unittest.TestCase):
],
)
def test_trailing_comma_does_not_produce_empty_entry(self):
def test_trailing_separator_does_not_produce_empty_entry(self):
self.assertEqual(
snrc.split_csv("https://smp16.simplex.im/a#H1,"),
snrc.split_links("https://smp16.simplex.im/a#H1;"),
["https://smp16.simplex.im/a#H1"],
)
def test_doubled_comma_does_not_produce_empty_entry(self):
def test_doubled_separator_does_not_produce_empty_entry(self):
self.assertEqual(
snrc.split_csv(
"https://smp16.simplex.im/a#H1,,https://smp19.simplex.im/a#H1"
snrc.split_links(
"https://smp16.simplex.im/a#H1;;https://smp19.simplex.im/a#H1"
),
[
"https://smp16.simplex.im/a#H1",
@@ -76,7 +77,7 @@ class SplitCsvTests(unittest.TestCase):
def test_order_is_preserved(self):
self.assertEqual(
snrc.split_csv("c,a,b"),
snrc.split_links("c;a;b"),
["c", "a", "b"],
)