From c843d74f6da9cde2aeb21dc4e874721dcc54a7b3 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 2 Apr 2026 04:21:18 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20add=203=20DNS=20resolution=20actions=20?= =?UTF-8?q?bridging=20chain=20=E2=86=92=20sidechain=20=E2=86=92=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit blockchain.dns.resolve — name → A + TXT records via HSD blockchain.dns.names — all aliases → resolved names with addresses blockchain.dns.discover — chain aliases → HNS name list 36 total Core actions. DNS actions use chain aliases for discovery and HSD client for record resolution — the full LNS pipeline as Core actions. Co-Authored-By: Charon --- actions.go | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/actions.go b/actions.go index b394480..233870e 100644 --- a/actions.go +++ b/actions.go @@ -456,3 +456,87 @@ func makeHSDHeight(url, key string) core.ActionHandler { return core.Result{Value: height, OK: true} } } + +// RegisterDNSActions registers DNS resolution actions. +// These bridge go-blockchain (alias discovery) to go-lns (name resolution). +// +// blockchain.RegisterDNSActions(c, chain, hsdURL, hsdKey) +func RegisterDNSActions(c *core.Core, ch *chain.Chain, hsdURL, hsdKey string) { + c.Action("blockchain.dns.resolve", makeDNSResolve(ch, hsdURL, hsdKey)) + c.Action("blockchain.dns.names", makeDNSNames(ch, hsdURL, hsdKey)) + c.Action("blockchain.dns.discover", makeDNSDiscover(ch)) +} + +func makeDNSResolve(ch *chain.Chain, hsdURL, hsdKey string) core.ActionHandler { + return func(ctx context.Context, opts core.Options) core.Result { + name := opts.String("name") + if name == "" { + return core.Result{OK: false} + } + name = core.TrimSuffix(name, ".lthn") + name = core.TrimSuffix(name, ".") + + client := hsdpkg.NewClient(hsdURL, hsdKey) + resource, err := client.GetNameResource(name) + if err != nil || resource == nil { + return core.Result{OK: false} + } + + var addresses []string + var txts []string + for _, r := range resource.Records { + if r.Type == "GLUE4" { addresses = append(addresses, r.Address) } + if r.Type == "TXT" { txts = append(txts, r.TXT...) } + } + + return core.Result{Value: map[string]interface{}{ + "name": name + ".lthn", "a": addresses, "txt": txts, + }, OK: true} + } +} + +func makeDNSNames(ch *chain.Chain, hsdURL, hsdKey string) core.ActionHandler { + return func(ctx context.Context, opts core.Options) core.Result { + aliases := ch.GetAllAliases() + client := hsdpkg.NewClient(hsdURL, hsdKey) + + var names []map[string]interface{} + for _, a := range aliases { + hnsName := a.Name + parsed := parseActionComment(a.Comment) + if h, ok := parsed["hns"]; ok { + hnsName = core.TrimSuffix(h, ".lthn") + } + + resource, err := client.GetNameResource(hnsName) + if err != nil || resource == nil { continue } + + var addrs []string + for _, r := range resource.Records { + if r.Type == "GLUE4" { addrs = append(addrs, r.Address) } + } + if len(addrs) > 0 { + names = append(names, map[string]interface{}{ + "name": hnsName + ".lthn", "addresses": addrs, + }) + } + } + return core.Result{Value: names, OK: true} + } +} + +func makeDNSDiscover(ch *chain.Chain) core.ActionHandler { + return func(ctx context.Context, opts core.Options) core.Result { + aliases := ch.GetAllAliases() + var names []string + for _, a := range aliases { + hnsName := a.Name + parsed := parseActionComment(a.Comment) + if h, ok := parsed["hns"]; ok { + hnsName = core.TrimSuffix(h, ".lthn") + } + names = append(names, hnsName) + } + return core.Result{Value: names, OK: true} + } +}