···11+package main
22+33+import (
44+ "fmt"
55+ "os"
66+77+ //"github.com/bluesky-social/indigo/atproto/identity"
88+ "github.com/bluesky-social/indigo/atproto/syntax"
99+1010+ "github.com/urfave/cli/v2"
1111+)
1212+1313+func main() {
1414+ app := cli.App{
1515+ Name: "atp-id",
1616+ Usage: "informal debugging CLI tool for atproto identities",
1717+ }
1818+ app.Commands = []*cli.Command{
1919+ &cli.Command{
2020+ Name: "resolve-handle",
2121+ Usage: "resolve a handle",
2222+ Action: runResolveHandle,
2323+ },
2424+ &cli.Command{
2525+ Name: "resolve-did",
2626+ Usage: "resolve a DID",
2727+ Action: runResolveDID,
2828+ },
2929+ }
3030+ app.RunAndExitOnError()
3131+}
3232+3333+func runResolveHandle(cctx *cli.Context) error {
3434+ s := cctx.Args().First()
3535+ if s == "" {
3636+ fmt.Println("need to provide handle as an argument")
3737+ os.Exit(-1)
3838+ }
3939+4040+ handle, err := syntax.ParseHandle(s)
4141+ if err != nil {
4242+ fmt.Println(err)
4343+ os.Exit(-1)
4444+ }
4545+ fmt.Printf("valid handle syntax: %s\n", handle)
4646+ return nil
4747+}
4848+4949+func runResolveDID(cctx *cli.Context) error {
5050+ s := cctx.Args().First()
5151+ if s == "" {
5252+ fmt.Println("need to provide DID as an argument")
5353+ os.Exit(-1)
5454+ }
5555+5656+ did, err := syntax.ParseDID(s)
5757+ if err != nil {
5858+ fmt.Println(err)
5959+ os.Exit(-1)
6060+ }
6161+ fmt.Printf("valid DID syntax: %s\n", did)
6262+ return nil
6363+}
+26-18
atproto/identity/did.go
···11package identity
2233+import (
44+ "context"
55+ "errors"
66+ "fmt"
77+88+ "github.com/bluesky-social/indigo/atproto/syntax"
99+)
1010+311type DIDDocument struct {
44- DID syntax.DID `json:"id"`
55- AlsoKnownAs []string `json:"alsoKnownAs,omitempty"`
1212+ DID syntax.DID `json:"id"`
1313+ AlsoKnownAs []string `json:"alsoKnownAs,omitempty"`
614 VerificationMethod []DocVerificationMethod `json:"alsoKnownAs,omitempty"`
77- Service []DocService `json:"alsoKnownAs,omitempty"`
1515+ Service []DocService `json:"alsoKnownAs,omitempty"`
816}
9171018type DocVerificationMethod struct {
1111- ID `json:"id"`
1212- Type `json:"type"`
1313- Controller `json:"controller"`
1414- PublicKeyMultibase `json:"publicKeyMultibase"`
1919+ ID string `json:"id"`
2020+ Type string `json:"type"`
2121+ Controller string `json:"controller"`
2222+ PublicKeyMultibase string `json:"publicKeyMultibase"`
1523}
16241725type DocService struct {
1818- ID `json:"id"`
1919- Type `json:"type"`
2020- ServiceEndpoint `json:"serviceEndpoint"`
2626+ ID string `json:"id"`
2727+ Type string `json:"type"`
2828+ ServiceEndpoint string `json:"serviceEndpoint"`
2129}
22302323-var ErrDIDNotFound = error.New("DID not found")
3131+var ErrDIDNotFound = errors.New("DID not found")
24322533// WARNING: this does *not* bi-directionally verify account metadata; it only implements direct DID-to-DID-document lookup for the supported DID methods, and parses the resulting DID Doc into an Account struct
2626-func ResolveDID(ctx context.Context, did identifier.DID) (*DIDDocument, error) {
3434+func ResolveDID(ctx context.Context, did syntax.DID) (*DIDDocument, error) {
2735 switch did.Method() {
2836 case "web":
2937 panic("NOT IMPLEMENTED")
···3442 }
3543}
36443737-func ResolveDIDWeb(ctx context.Context, did identifier.DID) (*DIDDocument, error) {
3838- // XXX
4545+func ResolveDIDWeb(ctx context.Context, did syntax.DID) (*DIDDocument, error) {
4646+ return nil, fmt.Errorf("XXX UNIMPLEMENTED")
3947}
40484141-func ResolvePLC(ctx context.Context, did identifier.DID) (*DIDDocument, error) {
4242- // XXX
4949+func ResolvePLC(ctx context.Context, did syntax.DID) (*DIDDocument, error) {
5050+ return nil, fmt.Errorf("XXX UNIMPLEMENTED")
4351}
44524553func (d *DIDDocument) Account() Account {
4646- // XXX
5454+ panic("XXX UNIMPLEMENTED")
4755}
48564957// "Renders" a DID Document
5058func (a *Account) DIDDocument() DIDDocument {
5151- // XXX
5959+ panic("XXX UNIMPLEMENTED")
5260}
+3-2
atproto/identity/doc.go
···11-/* Package identity provides types and routines for resolving handles and DIDs from the network
11+/*
22+ Package identity provides types and routines for resolving handles and DIDs from the network
2333-Much of the code in this SDK is based on existing code in indigo:api/extra.go
44+Much of the implementation of this SDK is based on existing code in indigo:api/extra.go
45*/
56package identity
+12-5
atproto/identity/handle.go
···11package identity
2233import (
44+ "context"
55+ "errors"
66+ "fmt"
77+ "io"
48 "net"
55- "context"
99+ "net/http"
1010+ "strings"
1111+1212+ "github.com/bluesky-social/indigo/atproto/syntax"
613)
71488-var ErrHandleNotFound = error.New("handle not found")
1515+var ErrHandleNotFound = errors.New("handle not found")
9161017// Does not cross-verify, just does the handle resolution step.
1111-func ResolveHandleDNS(ctx context.Context, handle identifier.Handle) (identifier.DID, error) {
1818+func ResolveHandleDNS(ctx context.Context, handle syntax.Handle) (syntax.DID, error) {
12191313- res, err := net.LookupTXT("_atproto." + handle)
2020+ res, err := net.LookupTXT("_atproto." + handle.String())
1421 if err != nil {
1522 return "", fmt.Errorf("handle DNS resolution failed: %w", err)
1623 }
···2835 return "", ErrHandleNotFound
2936}
30373131-func ResolveHandleWellKnown(ctx context.Context, handle identifier.Handle) (identifier.DID, error) {
3838+func ResolveHandleWellKnown(ctx context.Context, handle syntax.Handle) (syntax.DID, error) {
3239 // NOTE: could pull a client or transport from context
3340 c := http.DefaultClient
3441
+11-13
atproto/identity/identity.go
···11package identity
2233import (
44- "fmt"
55-64 "github.com/bluesky-social/indigo/atproto/syntax"
75)
86···28262927 // these fields are nullable
3028 AlsoKnownAs []string
3131- Services map[string]Service
3232- Keys map[string]Key
2929+ Services map[string]Service
3030+ Keys map[string]Key
3331}
34323533type Key struct {
3636- Type string
3434+ Type string
3735 PublicKeyMultibase string
3836}
39374038type Service struct {
4139 Type string
4242- URL string
4040+ URL string
4341}
44424543func (a *Account) SigningKey() *Key {
4644 if a.Keys == nil {
4745 return nil
4846 }
4949- atp := a.Keys["atproto"]
5050- if atp == nil {
4747+ atp, ok := a.Keys["atproto"]
4848+ if !ok {
5149 return nil
5250 }
5351 return &atp
···55535654func (a *Account) PDS() string {
5755 if a.Services == nil {
5858- return nil
5656+ return ""
5957 }
6060- atp := a.Services["atproto_pds"]
6161- if atp == nil {
6262- return nil
5858+ atp, ok := a.Services["atproto_pds"]
5959+ if !ok {
6060+ return ""
6361 }
6464- return &atp
6262+ return atp.URL
6563}