Skip to content

Commit

Permalink
Merge pull request #31 from iden3/feat/did-pkh
Browse files Browse the repository at this point in the history
add PKH resolver
  • Loading branch information
vmidyllic authored Dec 12, 2024
2 parents 28d9896 + 654bb4b commit 821b417
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 28 deletions.
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
}

0 comments on commit 821b417

Please sign in to comment.