Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add PKH resolver #31

Merged
merged 10 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
name: e2e driver-did-iden3

on:
pull_request:
workflow_dispatch:

jobs:
Expand Down
10 changes: 9 additions & 1 deletion cmd/driver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/iden3/driver-did-iden3/pkg/services"
"github.com/iden3/driver-did-iden3/pkg/services/blockchain/eth"
"github.com/iden3/driver-did-iden3/pkg/services/ens"
"github.com/iden3/driver-did-iden3/pkg/services/pkh"
"github.com/iden3/driver-did-iden3/pkg/services/provers"
core "github.com/iden3/go-iden3-core/v2"
revocationReolver "github.com/iden3/merkletree-proof/resolvers"
Expand Down Expand Up @@ -46,8 +47,15 @@ func main() {
}

resolvers, revocationResolvers := initResolvers()
pkhResolver, err := pkh.NewResolver()
if err != nil {
log.Fatalf("failed configure PKH resolver %v", err)
}

thirdPartyDidResolvers := services.ThirdPartyDidResolvers{}
thirdPartyDidResolvers["did:pkh"] = pkhResolver
mux := app.Handlers{DidDocumentHandler: &app.DidDocumentHandler{
DidDocumentService: services.NewDidDocumentServices(resolvers, r, revocationResolvers, services.WithProvers(proverRegistry))},
DidDocumentService: services.NewDidDocumentServices(resolvers, r, revocationResolvers, services.WithProvers(proverRegistry), services.WithThirdPartyDIDResolvers(thirdPartyDidResolvers))},
}

server := http.Server{
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/golang/mock v1.6.0
github.com/iden3/contracts-abi/state/go/abi v1.0.1
github.com/iden3/go-iden3-core/v2 v2.3.1
github.com/iden3/go-schema-processor/v2 v2.5.2
github.com/iden3/merkletree-proof v0.3.0
github.com/kelseyhightower/envconfig v1.4.0
github.com/pkg/errors v0.9.1
Expand All @@ -23,7 +24,6 @@ require (
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/holiman/uint256 v1.2.3 // indirect
github.com/iden3/contracts-abi/onchain-credential-status-resolver/go/abi v0.0.0-20230911113809-c58b7e7a69b0 // indirect
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241118132742-9f041ef05b49 // indirect
github.com/piprate/json-gold v0.5.1-0.20230111113000-6ddbe6e6f19f // indirect
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
golang.org/x/exp v0.0.0-20230810033253-352e893a4cad // indirect
Expand Down
24 changes: 2 additions & 22 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -84,28 +84,8 @@ github.com/iden3/go-iden3-crypto v0.0.17 h1:NdkceRLJo/pI4UpcjVah4lN/a3yzxRUGXqxb
github.com/iden3/go-iden3-crypto v0.0.17/go.mod h1:dLpM4vEPJ3nDHzhWFXDjzkn1qHoBeOT/3UEhXsEsP3E=
github.com/iden3/go-merkletree-sql/v2 v2.0.4 h1:Dp089P3YNX1BE8+T1tKQHWTtnk84Y/Kr7ZAGTqwscoY=
github.com/iden3/go-merkletree-sql/v2 v2.0.4/go.mod h1:kRhHKYpui5DUsry5RpveP6IC4XMe6iApdV9VChRYuEk=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241113162104-5dbe5dad6b88 h1:N3rYFMBeRZODJfL4lrhfXTBuu2P+umTD1Zw5bEMDh3c=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241113162104-5dbe5dad6b88/go.mod h1:hMqYi4lKOzEGkmCRks/r4Crj8H4G8YaTt8H4jZHzX9Y=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241115111117-74adfd680389 h1:pZWnB0J9h3mCKclqMtNG4MS1Ce+1++ezqAIzPZS/4Kw=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241115111117-74adfd680389/go.mod h1:hMqYi4lKOzEGkmCRks/r4Crj8H4G8YaTt8H4jZHzX9Y=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241115135152-f7aba5c8ea0f h1:ocJvFD7WANhjLjnUiu7ct7eWKCev+JAcfYVi5BqLBRs=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241115135152-f7aba5c8ea0f/go.mod h1:hMqYi4lKOzEGkmCRks/r4Crj8H4G8YaTt8H4jZHzX9Y=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241115140032-3c6d00e10e39 h1:nyV5fyKBWudE/QVTOOo9W0Iy85btAw4/KQpDoRGVLYE=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241115140032-3c6d00e10e39/go.mod h1:hMqYi4lKOzEGkmCRks/r4Crj8H4G8YaTt8H4jZHzX9Y=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241115142927-28e0b310c9f1 h1:horz6KSKZ8K2AY4DABIhxdj54Fnj8nbk14u8mHRxUoM=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241115142927-28e0b310c9f1/go.mod h1:hMqYi4lKOzEGkmCRks/r4Crj8H4G8YaTt8H4jZHzX9Y=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241115144905-4b99f46f2c93 h1:4ajyeSLl1Xb6v582dYqaF+isi5Nv/+rMjPncffBhJ1Y=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241115144905-4b99f46f2c93/go.mod h1:hMqYi4lKOzEGkmCRks/r4Crj8H4G8YaTt8H4jZHzX9Y=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241115154532-958b682f9a82 h1:A06SGanhVTsVfaPk9mTb/hEugzfBsMBnIBFnAf9Xb5U=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241115154532-958b682f9a82/go.mod h1:hMqYi4lKOzEGkmCRks/r4Crj8H4G8YaTt8H4jZHzX9Y=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241118104325-cad1ed670f2f h1:v/MvoN0TKeu/+tM8xbB9Lnyz63yVX/AFVZFosa4amYQ=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241118104325-cad1ed670f2f/go.mod h1:hMqYi4lKOzEGkmCRks/r4Crj8H4G8YaTt8H4jZHzX9Y=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241118112226-85f13b328a6d h1:8eeAhV54Ra2I40W3fFPd46OYtEWkhMAdV5dfJaQ2J8w=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241118112226-85f13b328a6d/go.mod h1:hMqYi4lKOzEGkmCRks/r4Crj8H4G8YaTt8H4jZHzX9Y=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241118112443-0657c0326876 h1:1TglvlfYclTk8tHUc6b6/lgIJjzSGo6wayhmjH5YJP0=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241118112443-0657c0326876/go.mod h1:hMqYi4lKOzEGkmCRks/r4Crj8H4G8YaTt8H4jZHzX9Y=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241118132742-9f041ef05b49 h1:uAZmYb22761RwpD4Yeqb2dMJq4y3kJoPi42hVe45R7w=
github.com/iden3/go-schema-processor/v2 v2.5.1-0.20241118132742-9f041ef05b49/go.mod h1:hMqYi4lKOzEGkmCRks/r4Crj8H4G8YaTt8H4jZHzX9Y=
github.com/iden3/go-schema-processor/v2 v2.5.2 h1:my41uq5Sq2DKMZaF8bTUIQYmUifNpEPG3BCg3JiMbcc=
github.com/iden3/go-schema-processor/v2 v2.5.2/go.mod h1:hMqYi4lKOzEGkmCRks/r4Crj8H4G8YaTt8H4jZHzX9Y=
github.com/iden3/merkletree-proof v0.3.0 h1:NVlvtUBEgn4Etxxn+RsOmXP/qlI+85BdN8oUDTf3mxI=
github.com/iden3/merkletree-proof v0.3.0/go.mod h1:+E2sBxMqhcn/fcu0LDGjmk3us+Vr+fxQUiZMxdpbgUE=
github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc=
Expand Down
9 changes: 7 additions & 2 deletions pkg/document/did.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,16 @@ const (
StateType = "Iden3StateInfo2023"
Iden3ResolutionMetadataType = "Iden3ResolutionMetadata"
EcdsaSecp256k1RecoveryMethod2020Type = "EcdsaSecp256k1RecoveryMethod2020"
TezosMethod2021Type = "TezosMethod2021"

DefaultDidDocContext = "https://www.w3.org/ns/did/v1"
BlockchainAccountIDContext = "https://w3id.org/security#blockchainAccountId"
EcdsaSecp256k1RecoveryMethod2020Context = "https://identity.foundation/EcdsaSecp256k1RecoverySignature2020#EcdsaSecp256k1RecoveryMethod2020"
TezosMethod2021Context = "https://w3id.org/security#TezosMethod2021"
)

const (
defaultContext = "https://w3id.org/did-resolution/v1"
defaultDidDocContext = "https://www.w3.org/ns/did/v1"
iden3Context = "https://schema.iden3.io/core/jsonld/auth.jsonld"
Iden3proofsContext = "https://schema.iden3.io/core/jsonld/iden3proofs.jsonld"
EcdsaSecp256k1RecoveryContext = "https://identity.foundation/EcdsaSecp256k1RecoverySignature2020/lds-ecdsa-secp256k1-recovery2020-2.0.jsonld"
Expand All @@ -45,7 +50,7 @@ func NewDidResolution() *DidResolution {
return &DidResolution{
Context: defaultContext,
DidDocument: &verifiable.DIDDocument{
Context: []string{defaultDidDocContext, iden3Context},
Context: []string{DefaultDidDocContext, iden3Context},
VerificationMethod: []verifiable.CommonVerificationMethod{},
},
DidResolutionMetadata: &DidResolutionMetadata{
Expand Down
22 changes: 21 additions & 1 deletion pkg/services/did.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,18 @@ const (
ensResolverKey = "description"
)

type thirdPartyResolver interface {
Resolve(ctx context.Context, did w3c.DID) (*document.DidResolution, error)
}

type ThirdPartyDidResolvers map[string]thirdPartyResolver

type DidDocumentServices struct {
resolvers *ResolverRegistry
ens *ens.Registry
provers *DIDResolutionProverRegistry
revStatusOnChainResolver *resolvers.OnChainResolver
thirdPartyResolvers ThirdPartyDidResolvers
}

type ResolverOpts struct {
Expand All @@ -41,8 +48,14 @@ func WithProvers(provers *DIDResolutionProverRegistry) DidDocumentOption {
}
}

func WithThirdPartyDIDResolvers(thirdPartyResolvers ThirdPartyDidResolvers) DidDocumentOption {
return func(d *DidDocumentServices) {
d.thirdPartyResolvers = thirdPartyResolvers
}
}

func NewDidDocumentServices(resolverRegistry *ResolverRegistry, registry *ens.Registry, revStatusOnChainResolver *resolvers.OnChainResolver, opts ...DidDocumentOption) *DidDocumentServices {
didDocumentService := &DidDocumentServices{resolverRegistry, registry, nil, revStatusOnChainResolver}
didDocumentService := &DidDocumentServices{resolverRegistry, registry, nil, revStatusOnChainResolver, nil}

for _, opt := range opts {
opt(didDocumentService)
Expand All @@ -62,6 +75,13 @@ func (d *DidDocumentServices) GetDidDocument(ctx context.Context, did string, op
return errResolution, err
}

didParts := strings.Split(userDID.String(), ":")
didPrefix := fmt.Sprintf("%s:%s", didParts[0], didParts[1])
thirdPartyResolver := d.thirdPartyResolvers[didPrefix]
if thirdPartyResolver != nil {
return thirdPartyResolver.Resolve(ctx, *userDID)
}

userID, err := core.IDFromDID(*userDID)
errResolution, err = expectedError(err)
if err != nil {
Expand Down
130 changes: 130 additions & 0 deletions pkg/services/pkh/resolver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package pkh

import (
"context"
"errors"
"fmt"
"strings"

"github.com/iden3/driver-did-iden3/pkg/document"
"github.com/iden3/go-iden3-core/v2/w3c"
"github.com/iden3/go-schema-processor/v2/verifiable"
)

const (
NamespaceTezos = "tezos"
NamespaceEIP155 = "eip155"
NamespaceBIP122 = "bip122"
)

type Resolver struct {
}

type ResolverOption func(*Resolver)

// NewResolver create new pkh resolver.
func NewResolver() (*Resolver, error) {
return &Resolver{}, nil
}

func (r *Resolver) Resolve(
ctx context.Context,
did w3c.DID,
) (*document.DidResolution, error) {
didString := did.String()
parts := strings.Split(didString, ":")
namespace := parts[2]
vmID := didString + "#blockchainAccountId"

didResolution := document.NewDidResolution()
authentication := verifiable.Authentication{}
authentication.ID = vmID
authentication.Type = document.EcdsaSecp256k1RecoveryMethod2020Type
authentication.Controller = didString
blockchainAccountID, err := getBlockchainAccountID(didString)
if err != nil {
return nil, err
}

assertionMethod := verifiable.Authentication{}
err = assertionMethod.UnmarshalJSON([]byte(fmt.Sprintf("%q", vmID)))
if err != nil {
return nil, err
}
didResolution.DidDocument = &verifiable.DIDDocument{
Context: []interface{}{
document.DefaultDidDocContext,
map[string]string{
"blockchainAccountId": document.BlockchainAccountIDContext,
document.EcdsaSecp256k1RecoveryMethod2020Type: document.EcdsaSecp256k1RecoveryMethod2020Context,
},
},
ID: didString,
VerificationMethod: []verifiable.CommonVerificationMethod{},
Authentication: []verifiable.Authentication{authentication},
AssertionMethod: []verifiable.Authentication{assertionMethod},
}

didResolution.DidDocument.VerificationMethod = append(
didResolution.DidDocument.VerificationMethod,
verifiable.CommonVerificationMethod{
ID: vmID,
Type: document.EcdsaSecp256k1RecoveryMethod2020Type,
Controller: didString,
BlockchainAccountID: blockchainAccountID,
},
)

switch namespace {
case NamespaceEIP155:
case NamespaceBIP122:
break
case NamespaceTezos:
didResolution.DidDocument.Context = []interface{}{
document.DefaultDidDocContext,
map[string]string{
"blockchainAccountId": document.BlockchainAccountIDContext,
document.EcdsaSecp256k1RecoveryMethod2020Type: document.EcdsaSecp256k1RecoveryMethod2020Context,
document.TezosMethod2021Type: document.TezosMethod2021Context,
},
}

tzID := fmt.Sprintf("%s#%s", didString, document.TezosMethod2021Type)
didResolution.DidDocument.VerificationMethod = append(
didResolution.DidDocument.VerificationMethod,
verifiable.CommonVerificationMethod{
ID: tzID,
Type: document.TezosMethod2021Type,
Controller: didString,
BlockchainAccountID: blockchainAccountID,
},
)
tzAuthentication := verifiable.Authentication{}
tzAuthentication.ID = tzID
tzAuthentication.Type = document.TezosMethod2021Type
tzAuthentication.Controller = didString

tzAssertionMethod := verifiable.Authentication{}
err = tzAssertionMethod.UnmarshalJSON([]byte(fmt.Sprintf("%q", tzID)))
if err != nil {
return nil, err
}
didResolution.DidDocument.Authentication = append(didResolution.DidDocument.Authentication, tzAuthentication)
didResolution.DidDocument.AssertionMethod = append(didResolution.DidDocument.AssertionMethod, tzAssertionMethod)
default:
return nil, fmt.Errorf("chain namespace not supported: %s", namespace)
}
return didResolution, nil
}

func getBlockchainAccountID(did string) (string, error) {
prefix := "did:pkh:"
if !strings.HasPrefix(did, prefix) {
return "", errors.New("invalid DID format: must start with 'did:pkh:'")
}
blockchainAccountID := strings.TrimPrefix(did, prefix)
if blockchainAccountID == "" {
return "", errors.New("invalid DID format: missing blockchainAccountId")
}
return blockchainAccountID, nil
}
Loading