From a4fe29ab88b70a6edc00de01a2d944efacab5d47 Mon Sep 17 00:00:00 2001 From: vmidyllic <74898029+vmidyllic@users.noreply.github.com> Date: Mon, 2 Sep 2024 16:19:21 +0300 Subject: [PATCH] refactor --- cmd/driver/main.go | 40 ++--- pkg/app/configs/driver.go | 31 +--- pkg/document/proof.go | 2 +- pkg/document/proof_test.go | 2 +- pkg/services/did.go | 138 ++------------- pkg/services/provers.go | 46 +++++ .../provers/EthereumEip712Signature2021.go | 162 ++++++++++++++++++ pkg/services/registry.go | 5 +- pkg/services/signers.go | 46 ----- pkg/services/signers/EIP712Signer.go | 93 ---------- pkg/services/signers/secp256k1.go | 38 ++++ pkg/services/utils/convert.go | 30 ++++ resolvers.settings.yaml | 15 +- 13 files changed, 325 insertions(+), 323 deletions(-) create mode 100644 pkg/services/provers.go create mode 100644 pkg/services/provers/EthereumEip712Signature2021.go delete mode 100644 pkg/services/signers.go delete mode 100644 pkg/services/signers/EIP712Signer.go create mode 100644 pkg/services/signers/secp256k1.go create mode 100644 pkg/services/utils/convert.go diff --git a/cmd/driver/main.go b/cmd/driver/main.go index 7a19b9e..e4063e3 100644 --- a/cmd/driver/main.go +++ b/cmd/driver/main.go @@ -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() { @@ -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{ @@ -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 } diff --git a/pkg/app/configs/driver.go b/pkg/app/configs/driver.go index 9e0f093..c0f88d5 100644 --- a/pkg/app/configs/driver.go +++ b/pkg/app/configs/driver.go @@ -11,7 +11,6 @@ import ( ) const defaultPathToResolverSettings = "./resolvers.settings.yaml" -const defaultPathToSignersSettings = "./signers.settings.yaml" // ResolverSettings represent settings for resolver. type ResolverSettings map[string]map[string]struct { @@ -19,13 +18,10 @@ type ResolverSettings map[string]map[string]struct { 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"` } @@ -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 -} diff --git a/pkg/document/proof.go b/pkg/document/proof.go index bf16b87..3a28daf 100644 --- a/pkg/document/proof.go +++ b/pkg/document/proof.go @@ -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"` diff --git a/pkg/document/proof_test.go b/pkg/document/proof_test.go index 6db2fea..ef73a4d 100644 --- a/pkg/document/proof_test.go +++ b/pkg/document/proof_test.go @@ -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, diff --git a/pkg/services/did.go b/pkg/services/did.go index 6410e66..6cf79b3 100644 --- a/pkg/services/did.go +++ b/pkg/services/did.go @@ -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" @@ -27,7 +22,7 @@ const ( type DidDocumentServices struct { resolvers *ResolverRegistry ens *ens.Registry - signers *EIP712SignerRegistry + provers *DIDResolutionProverRegistry } type ResolverOpts struct { @@ -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 } } @@ -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) diff --git a/pkg/services/provers.go b/pkg/services/provers.go new file mode 100644 index 0000000..d4440de --- /dev/null +++ b/pkg/services/provers.go @@ -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 +} diff --git a/pkg/services/provers/EthereumEip712Signature2021.go b/pkg/services/provers/EthereumEip712Signature2021.go new file mode 100644 index 0000000..dd445ce --- /dev/null +++ b/pkg/services/provers/EthereumEip712Signature2021.go @@ -0,0 +1,162 @@ +package provers + +import ( + "encoding/hex" + "fmt" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/signer/core/apitypes" + "github.com/iden3/driver-did-iden3/pkg/document" + "github.com/iden3/driver-did-iden3/pkg/services" + "github.com/iden3/driver-did-iden3/pkg/services/signers" + "github.com/iden3/driver-did-iden3/pkg/services/utils" + core "github.com/iden3/go-iden3-core/v2" + "github.com/iden3/go-iden3-core/v2/w3c" + "github.com/pkg/errors" +) + +type EIP712Prover struct { + signer *signers.Secp256k1Signer + address common.Address +} + +func NewEIP712Prover(walletKey string) (*EIP712Prover, error) { + + s, err := signers.NewSecp256k1Signer(walletKey) // eip712 provers uses ecdsa signer + if err != nil { + return nil, err + } + addr, err := utils.PrivateKeyToAddress(walletKey) + if err != nil { + return nil, err + } + globalStateSigner := &EIP712Prover{ + signer: s, + address: addr, + } + + return globalStateSigner, nil +} + +func (p *EIP712Prover) Prove(did w3c.DID, state services.IdentityState, stateType services.StateType) (document.DidResolutionProof, error) { + + typedData, err := p.getTypedData(did, state, stateType) + if err != nil { + return nil, err + } + domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map()) + if err != nil { + return nil, errors.New("error hashing EIP712Domain for signing") + } + typedDataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message) + if err != nil { + return nil, errors.New("error hashing PrimaryType message for signing") + } + rawData := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash))) + dataHash := crypto.Keccak256(rawData) + + signature, err := p.signer.Sign(dataHash) + if err != nil { + return nil, err + } + + messageSignature := "0x" + hex.EncodeToString(signature) + + eip712Proof := &document.EthereumEip712SignatureProof2021{ + Type: document.EthereumEip712SignatureProof2021Type, + ProofPurpose: "assertionMethod", + ProofValue: messageSignature, + VerificationMethod: fmt.Sprintf("did:pkh:eip155:0:%s#blockchainAccountId", p.address), + Eip712: typedData, + Created: time.Now(), + } + + return eip712Proof, nil +} + +func (p *EIP712Prover) getTypedData(did w3c.DID, identityState services.IdentityState, stateType services.StateType) (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 := utils.TimeStamp() + + var apiTypes apitypes.Types + var message apitypes.TypedDataMessage + var primaryType string + + switch stateType { + case services.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 services.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("type of state info %d is not supportede", stateType) + } + + 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 +} diff --git a/pkg/services/registry.go b/pkg/services/registry.go index c4c688d..80eed33 100644 --- a/pkg/services/registry.go +++ b/pkg/services/registry.go @@ -12,7 +12,9 @@ import ( ) var ( - ErrNetworkIsNotSupported = errors.New("network is not supported") + ErrNetworkIsNotSupported = errors.New("network is not supported") + ErrProofTypeIsNotSupported = errors.New("proof is not supported") + ErrResolverAlreadyExists = errors.New("resolver already exists") ErrNotFound = errors.New("not found") @@ -21,7 +23,6 @@ var ( type IdentityState struct { StateInfo *StateInfo GistInfo *GistInfo - Signature string } type StateInfo struct { diff --git a/pkg/services/signers.go b/pkg/services/signers.go deleted file mode 100644 index 813f794..0000000 --- a/pkg/services/signers.go +++ /dev/null @@ -1,46 +0,0 @@ -package services - -import ( - "github.com/ethereum/go-ethereum/signer/core/apitypes" - "github.com/iden3/driver-did-iden3/pkg/document" -) - -type TypedDataType int32 - -const ( - IdentityStateType TypedDataType = 0 - GlobalStateType TypedDataType = 1 -) - -type EIP712Signer interface { - Sign(typedData apitypes.TypedData) (*document.EthereumEip712SignatureProof2021, error) -} - -type EIP712SignerRegistry map[string]EIP712Signer - -func NewChainEIP712Signers() *EIP712SignerRegistry { - return &EIP712SignerRegistry{} -} - -func (ch *EIP712SignerRegistry) Add(prefix string, signer EIP712Signer) { - (*ch)[prefix] = signer -} - -func (ch *EIP712SignerRegistry) Append(prefix string, signer EIP712Signer) error { - _, ok := (*ch)[prefix] - if ok { - return ErrResolverAlreadyExists - } - (*ch)[prefix] = signer - return nil -} - -func (ch *EIP712SignerRegistry) GetEIP712SignerByNetwork(chain, networkID string) (EIP712Signer, error) { - p := resolverPrefix(chain, networkID) - signer, ok := (*ch)[p] - if !ok { - return nil, ErrNetworkIsNotSupported - } - - return signer, nil -} diff --git a/pkg/services/signers/EIP712Signer.go b/pkg/services/signers/EIP712Signer.go deleted file mode 100644 index 4f0b179..0000000 --- a/pkg/services/signers/EIP712Signer.go +++ /dev/null @@ -1,93 +0,0 @@ -package signers - -import ( - "crypto/ecdsa" - "encoding/hex" - "errors" - "fmt" - "time" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/signer/core/apitypes" - "github.com/iden3/driver-did-iden3/pkg/document" -) - -const ( - secp256k1VValue = 27 -) - -type EIP712Signer struct { - walletKey string -} - -func NewEIP712Signer(walletKey string) (*EIP712Signer, error) { - globalStateSigner := &EIP712Signer{ - walletKey: walletKey, - } - - return globalStateSigner, nil -} - -func (s *EIP712Signer) getWalletAddress() (string, error) { - if s.walletKey == "" { - return "", errors.New("wallet key is not set") - } - - privateKey, err := crypto.HexToECDSA(s.walletKey) - if err != nil { - return "", err - } - - publicKey := privateKey.Public() - publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) - if !ok { - return "", errors.New("error casting public key to ECDSA") - } - - walletAddress := crypto.PubkeyToAddress(*publicKeyECDSA) - - return walletAddress.String(), nil -} - -func (s *EIP712Signer) Sign(typedData apitypes.TypedData) (*document.EthereumEip712SignatureProof2021, error) { - privateKey, err := crypto.HexToECDSA(s.walletKey) - if err != nil { - return nil, err - } - walletAddress, err := s.getWalletAddress() - if err != nil { - return nil, err - } - domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map()) - if err != nil { - return nil, errors.New("error hashing EIP712Domain for signing") - } - typedDataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message) - if err != nil { - return nil, errors.New("error hashing PrimaryType message for signing") - } - rawData := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash))) - dataHash := crypto.Keccak256(rawData) - - signature, err := crypto.Sign(dataHash, privateKey) - if err != nil { - return nil, err - } - - if signature[64] < secp256k1VValue { // Invalid Ethereum signature (V is not 27 or 28) - signature[64] += secp256k1VValue // Transform yellow paper V from 0/1 to 27/28 - } - - messageSignature := "0x" + hex.EncodeToString(signature) - - eip712Proof := &document.EthereumEip712SignatureProof2021{ - Type: document.EthereumEip712SignatureProof2021Type, - ProofPursopose: "assertionMethod", - ProofValue: messageSignature, - VerificationMethod: fmt.Sprintf("did:pkh:eip155:0:%s#blockchainAccountId", walletAddress), - Eip712: typedData, - Created: time.Now(), - } - - return eip712Proof, nil -} diff --git a/pkg/services/signers/secp256k1.go b/pkg/services/signers/secp256k1.go new file mode 100644 index 0000000..ebf6ef8 --- /dev/null +++ b/pkg/services/signers/secp256k1.go @@ -0,0 +1,38 @@ +package signers + +import ( + "github.com/ethereum/go-ethereum/crypto" +) + +const ( + secp256k1VValue = 27 +) + +type Secp256k1Signer struct { + walletKey string +} + +func NewSecp256k1Signer(walletKey string) (*Secp256k1Signer, error) { + globalStateSigner := &Secp256k1Signer{ + walletKey: walletKey, + } + + return globalStateSigner, nil +} + +func (s *Secp256k1Signer) Sign(payload []byte) ([]byte, error) { + privateKey, err := crypto.HexToECDSA(s.walletKey) + if err != nil { + return nil, err + } + + signature, err := crypto.Sign(payload, privateKey) + if err != nil { + return nil, err + } + + if signature[64] < secp256k1VValue { // Invalid Ethereum signature (V is not 27 or 28) + signature[64] += secp256k1VValue // Transform yellow paper V from 0/1 to 27/28 + } + return signature, nil +} diff --git a/pkg/services/utils/convert.go b/pkg/services/utils/convert.go new file mode 100644 index 0000000..275f21e --- /dev/null +++ b/pkg/services/utils/convert.go @@ -0,0 +1,30 @@ +package utils + +import ( + "crypto/ecdsa" + "strconv" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/pkg/errors" +) + +func PrivateKeyToAddress(key string) (common.Address, error) { + privateKey, err := crypto.HexToECDSA(key) + if err != nil { + return common.Address{}, err + } + + publicKey := privateKey.Public() + publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) + if !ok { + return common.Address{}, errors.New("error casting public key to ECDSA") + } + return crypto.PubkeyToAddress(*publicKeyECDSA), nil +} + +func TimeStamp() string { + timestamp := strconv.FormatInt(time.Now().UTC().Unix(), 10) + return timestamp +} diff --git a/resolvers.settings.yaml b/resolvers.settings.yaml index 54837f5..935c3b4 100644 --- a/resolvers.settings.yaml +++ b/resolvers.settings.yaml @@ -1,7 +1,8 @@ -iden3: - amoy: - contractAddress: 0x1a4cC30f2aA0377b0c3bc9848766D90cb4404124 - networkURL: https://polygon-amoy.g.alchemy.com/v2/nQxE0N6UyGmmiurh735CVn4hZVLkTu0v - main: - contractAddress: 0x624ce98D2d27b20b8f8d521723Df8fC4db71D79D - networkURL: https://polygon-mainnet.g.alchemy.com/v2/4RsuBJrPQLIInqj6-PH5b4NQa3nIZUxa +resolvers: + iden3: + amoy: + contractAddress: 0x1a4cC30f2aA0377b0c3bc9848766D90cb4404124 + networkURL: https://polygon-amoy.g.alchemy.com/v2/nQxE0N6UyGmmiurh735CVn4hZVLkTu0v + main: + contractAddress: 0x624ce98D2d27b20b8f8d521723Df8fC4db71D79D + networkURL: https://polygon-mainnet.g.alchemy.com/v2/4RsuBJrPQLIInqj6-PH5b4NQa3nIZUxa