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

refactor #21

Merged
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
40 changes: 18 additions & 22 deletions cmd/driver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import (
"github.com/ethereum/go-ethereum/ethclient"
"github.com/iden3/driver-did-iden3/pkg/app"
"github.com/iden3/driver-did-iden3/pkg/app/configs"
"github.com/iden3/driver-did-iden3/pkg/document"
"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/signers"
"github.com/iden3/driver-did-iden3/pkg/services/provers"
)

func main() {
Expand All @@ -33,10 +34,16 @@ func main() {
log.Fatal("can't create registry:", err)
}
}
var proverRegistry *services.DIDResolutionProverRegistry
if cfg.WalletKey != "" {
proverRegistry, err = initDIDResolutionProverRegistry(*cfg)
if err != nil {
log.Fatal("can't create registry:", err)
}
}

mux := app.Handlers{DidDocumentHandler: &app.DidDocumentHandler{
DidDocumentService: services.NewDidDocumentServices(initResolvers(), r, services.WithSigners(initEIP712Signers())),
},
DidDocumentService: services.NewDidDocumentServices(initResolvers(), r, services.WithProvers(proverRegistry))},
}

server := http.Server{
Expand Down Expand Up @@ -75,26 +82,15 @@ func initResolvers() *services.ResolverRegistry {
return resolvers
}

func initEIP712Signers() *services.EIP712SignerRegistry {
var path string
if len(os.Args) > 3 {
path = os.Args[2]
}
rs, err := configs.ParseSignersSettings(path)
func initDIDResolutionProverRegistry(cfg configs.Config) (*services.DIDResolutionProverRegistry, error) {

proverRegistry := services.NewDIDResolutionProverRegistry()

prover, err := provers.NewEIP712Prover(cfg.WalletKey)
if err != nil {
log.Fatal("can't read signers settings:", err)
}
chainSigners := services.NewChainEIP712Signers()
for chainName, chainSettings := range rs {
for networkName, networkSettings := range chainSettings {
prefix := fmt.Sprintf("%s:%s", chainName, networkName)
signer, err := signers.NewEIP712Signer(networkSettings.WalletKey)
if err != nil {
log.Fatalf("failed configure signer for network '%s': %v", prefix, err)
}
chainSigners.Add(prefix, signer)
}
return nil, err
}
proverRegistry.Add(document.EthereumEip712SignatureProof2021Type, prover)

return chainSigners
return proverRegistry, nil
}
31 changes: 2 additions & 29 deletions pkg/app/configs/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,17 @@ import (
)

const defaultPathToResolverSettings = "./resolvers.settings.yaml"
const defaultPathToSignersSettings = "./signers.settings.yaml"

// ResolverSettings represent settings for resolver.
type ResolverSettings map[string]map[string]struct {
ContractAddress string `yaml:"contractAddress"`
NetworkURL string `yaml:"networkURL"`
}

type SignersSettings map[string]map[string]struct {
WalletKey string `yaml:"walletKey"`
}

// Config structure represent yaml config for did driver.
type Config struct {
Server struct {
WalletKey string `envconfig:"WALLET_KEY" default:""`
Server struct {
Port int `envconfig:"PORT" default:"8080"`
Host string `envconfig:"HOST" default:"localhost"`
}
Expand Down Expand Up @@ -65,26 +61,3 @@ func ParseResolversSettings(path string) (ResolverSettings, error) {

return settings, nil
}

// ParseSignersSettings parse yaml file with signers settings.
func ParseSignersSettings(path string) (SignersSettings, error) {
if path == "" {
path = defaultPathToSignersSettings
}
f, err := os.Open(filepath.Clean(path))
if err != nil {
return nil, err
}
defer func() {
if err := f.Close(); err != nil {
log.Println("failed to close setting file:", err)
}
}()

settings := SignersSettings{}
if err := yaml.NewDecoder(f).Decode(&settings); err != nil {
return nil, errors.Errorf("invalid yaml file: %v", settings)
}

return settings, nil
}
2 changes: 1 addition & 1 deletion pkg/document/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type DidResolutionProofs []DidResolutionProof

type EthereumEip712SignatureProof2021 struct {
Type verifiable.ProofType `json:"type"`
ProofPursopose string `json:"proofPurpose"`
ProofPurpose string `json:"proofPurpose"`
ProofValue string `json:"proofValue"`
VerificationMethod string `json:"verificationMethod"`
Created time.Time `json:"created"`
Expand Down
2 changes: 1 addition & 1 deletion pkg/document/proof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func TestEthereumEip712SignatureProof2021_JSONUnmarshal(t *testing.T) {

wantProof := EthereumEip712SignatureProof2021{
Type: "EthereumEip712Signature2021",
ProofPursopose: "assertionMethod",
ProofPurpose: "assertionMethod",
ProofValue: "0xd5e5ffe290a258116a0f7acb4c9a5bbfdd842516061c6a794892b6db05fbd14706de7e189d965bead2ffb23e30d2f6b02ecf764e6fe24be788721049b7e331481c",
VerificationMethod: "did:pkh:eip155:1:0x5b18eF56aA61eeAE0E3434e3c3d8AEB19b141fe7#blockchainAccountId",
Created: timeParsed,
Expand Down
138 changes: 16 additions & 122 deletions pkg/services/did.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,8 @@ import (
"fmt"
"math/big"
"net"
"strconv"
"strings"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/signer/core/apitypes"
"github.com/iden3/driver-did-iden3/pkg/document"
"github.com/iden3/driver-did-iden3/pkg/services/ens"
core "github.com/iden3/go-iden3-core/v2"
Expand All @@ -27,7 +22,7 @@ const (
type DidDocumentServices struct {
resolvers *ResolverRegistry
ens *ens.Registry
signers *EIP712SignerRegistry
provers *DIDResolutionProverRegistry
}

type ResolverOpts struct {
Expand All @@ -38,9 +33,9 @@ type ResolverOpts struct {

type DidDocumentOption func(*DidDocumentServices)

func WithSigners(signers *EIP712SignerRegistry) DidDocumentOption {
func WithProvers(provers *DIDResolutionProverRegistry) DidDocumentOption {
return func(d *DidDocumentServices) {
d.signers = signers
d.provers = provers
}
}

Expand Down Expand Up @@ -151,134 +146,33 @@ func (d *DidDocumentServices) GetDidDocument(ctx context.Context, did string, op
},
},
)

errResolution, err = expectedError(err)
if err != nil {
return errResolution, err
}
if opts.Signature != "" {
if d.signers == nil {
return nil, errors.New("signers not initialized")
}
signer, err := d.signers.GetEIP712SignerByNetwork(string(b), string(n))
if err != nil {
return nil, fmt.Errorf("invalid signer: %v", err)
if d.provers == nil {
return nil, errors.New("provers are not initialized")
}
errResolution, err = expectedError(err)
prover, err := d.provers.GetDIDResolutionProverByProofType(verifiable.ProofType(opts.Signature))
if err != nil {
return errResolution, err
return nil, err
}

var eip712TypedData *apitypes.TypedData
stateType := IdentityStateType
if opts.GistRoot != nil {
typedData, err := getTypedData(GlobalStateType, *userDID, identityState)
if err != nil {
return nil, fmt.Errorf("invalid typed data for global state: %v", err)
}
eip712TypedData = &typedData
} else {
typedData, err := getTypedData(IdentityStateType, *userDID, identityState)
if err != nil {
return nil, fmt.Errorf("invalid typed data for identity state: %v", err)
}
eip712TypedData = &typedData
stateType = GlobalStateType
}
eip712Proof, err := signer.Sign(*eip712TypedData)
didResolutionProof, err := prover.Prove(*userDID, identityState, stateType)
if err != nil {
return nil, fmt.Errorf("invalid eip712 typed data: %v", err)
return nil, err
}

didResolution.DidResolutionMetadata.Context = document.DidResolutionMetadataSigContext()
didResolution.DidResolutionMetadata.Proof = append(didResolution.DidResolutionMetadata.Proof, eip712Proof)
didResolution.DidResolutionMetadata.Proof = append(didResolution.DidResolutionMetadata.Proof, didResolutionProof)
}
return didResolution, nil
}

func getTypedData(typedDataType TypedDataType, did w3c.DID, identityState IdentityState) (apitypes.TypedData, error) {
id, err := core.IDFromDID(did)
if err != nil {
return apitypes.TypedData{},
fmt.Errorf("invalid did format for did '%s': %v", did, err)
}

timestamp := timeStamp()

var apiTypes apitypes.Types
var message apitypes.TypedDataMessage
var primaryType string

switch typedDataType {
case IdentityStateType:
primaryType = "IdentityState"
apiTypes = apitypes.Types{
"IdentityState": []apitypes.Type{
{Name: "timestamp", Type: "uint256"},
{Name: "id", Type: "uint256"},
{Name: "state", Type: "uint256"},
{Name: "replacedAtTimestamp", Type: "uint256"},
},
"EIP712Domain": []apitypes.Type{
{Name: "name", Type: "string"},
{Name: "version", Type: "string"},
{Name: "chainId", Type: "uint256"},
{Name: "verifyingContract", Type: "address"},
},
}
ID := id.BigInt().String()
state := identityState.StateInfo.State.String()
replacedAtTimestamp := identityState.StateInfo.ReplacedAtTimestamp.String()
message = apitypes.TypedDataMessage{
"timestamp": timestamp,
"id": ID,
"state": state,
"replacedAtTimestamp": replacedAtTimestamp,
}

case GlobalStateType:
primaryType = "GlobalState"
apiTypes = apitypes.Types{
"GlobalState": []apitypes.Type{
{Name: "timestamp", Type: "uint256"},
{Name: "idType", Type: "bytes2"},
{Name: "root", Type: "uint256"},
{Name: "replacedAtTimestamp", Type: "uint256"},
},
"EIP712Domain": []apitypes.Type{
{Name: "name", Type: "string"},
{Name: "version", Type: "string"},
{Name: "chainId", Type: "uint256"},
{Name: "verifyingContract", Type: "address"},
},
}
idType := fmt.Sprintf("0x%X", id.Type())
root := identityState.GistInfo.Root.String()
replacedAtTimestamp := identityState.GistInfo.ReplacedAtTimestamp.String()
message = apitypes.TypedDataMessage{
"timestamp": timestamp,
"idType": idType,
"root": root,
"replacedAtTimestamp": replacedAtTimestamp,
}
default:
return apitypes.TypedData{}, fmt.Errorf("typedDataType %d not defined", typedDataType)
}

typedData := apitypes.TypedData{
Types: apiTypes,
PrimaryType: primaryType,
Domain: apitypes.TypedDataDomain{
Name: "StateInfo",
Version: "1",
ChainId: math.NewHexOrDecimal256(int64(0)),
VerifyingContract: common.Address{}.String(),
},
Message: message,
}

return typedData, nil
}

func timeStamp() string {
timestamp := strconv.FormatInt(time.Now().UTC().Unix(), 10)
return timestamp
}

// ResolveDNSDomain return did document by domain via DNS.
func (d *DidDocumentServices) ResolveDNSDomain(ctx context.Context, domain string) (*document.DidResolution, error) {
domain = fmt.Sprintf("_did.%s", domain)
Expand Down
46 changes: 46 additions & 0 deletions pkg/services/provers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package services

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

type StateType int32

const (
IdentityStateType StateType = 0
GlobalStateType StateType = 1
)

type DIDResolutionProver interface {
Prove(did w3c.DID, info IdentityState, dataType StateType) (document.DidResolutionProof, error)
}

type DIDResolutionProverRegistry map[verifiable.ProofType]DIDResolutionProver

func NewDIDResolutionProverRegistry() *DIDResolutionProverRegistry {
return &DIDResolutionProverRegistry{}
}

func (ch *DIDResolutionProverRegistry) Add(proofType verifiable.ProofType, prover DIDResolutionProver) {
(*ch)[proofType] = prover
}

func (ch *DIDResolutionProverRegistry) Append(proofType verifiable.ProofType, prover DIDResolutionProver) error {
_, ok := (*ch)[proofType]
if ok {
return ErrResolverAlreadyExists
}
(*ch)[proofType] = prover
return nil
}

func (ch *DIDResolutionProverRegistry) GetDIDResolutionProverByProofType(proofType verifiable.ProofType) (DIDResolutionProver, error) {
signer, ok := (*ch)[proofType]
if !ok {
return nil, ErrProofTypeIsNotSupported
}

return signer, nil
}
Loading
Loading