From e82c5e63d36752f43e2e489b369570655e03928e Mon Sep 17 00:00:00 2001 From: volodymyr-basiuk <31999965+volodymyr-basiuk@users.noreply.github.com> Date: Thu, 23 Jan 2025 14:33:31 +0200 Subject: [PATCH] refactor payment-rails signature generation (#904) * refactor payment-rails signature generation --- cmd/platform/main.go | 6 +- internal/api/main_test.go | 4 +- internal/core/domain/schema.go | 3 + internal/core/services/payment.go | 109 +++++++++++------------------- 4 files changed, 51 insertions(+), 71 deletions(-) diff --git a/cmd/platform/main.go b/cmd/platform/main.go index 0193638a..60f71f9f 100644 --- a/cmd/platform/main.go +++ b/cmd/platform/main.go @@ -161,7 +161,11 @@ func main() { displayMethodService := services.NewDisplayMethod(repositories.NewDisplayMethod(*storage)) schemaService := services.NewSchema(schemaRepository, schemaLoader, displayMethodService) linkService := services.NewLinkService(storage, claimsService, qrService, claimsRepository, linkRepository, schemaRepository, schemaLoader, sessionRepository, ps, identityService, *networkResolver, cfg.UniversalLinks) - paymentService := services.NewPaymentService(paymentsRepo, *networkResolver, schemaService, paymentSettings, keyStore) + paymentService, err := services.NewPaymentService(paymentsRepo, *networkResolver, schemaService, paymentSettings, keyStore) + if err != nil { + log.Error(ctx, "error creating payment service", "err", err) + return + } keyService := services.NewKey(keyStore, claimsService, keyRepository) transactionService, err := gateways.NewTransaction(*networkResolver) if err != nil { diff --git a/internal/api/main_test.go b/internal/api/main_test.go index 84f8adc2..648f7471 100644 --- a/internal/api/main_test.go +++ b/internal/api/main_test.go @@ -353,8 +353,8 @@ func newTestServer(t *testing.T, st *db.Storage) *testServer { connectionService := services.NewConnection(repos.connection, repos.claims, st) displayMethodService := services.NewDisplayMethod(repos.displayMethod) schemaService := services.NewSchema(repos.schemas, schemaLoader, displayMethodService) - paymentService := services.NewPaymentService(repos.payments, *networkResolver, schemaService, paymentSettings, keyStore) - + paymentService, err := services.NewPaymentService(repos.payments, *networkResolver, schemaService, paymentSettings, keyStore) + require.NoError(t, err) mediaTypeManager := services.NewMediaTypeManager( map[iden3comm.ProtocolMessage][]string{ protocol.CredentialFetchRequestMessageType: {string(packers.MediaTypeZKPMessage)}, diff --git a/internal/core/domain/schema.go b/internal/core/domain/schema.go index ed8fa83b..faa1c732 100644 --- a/internal/core/domain/schema.go +++ b/internal/core/domain/schema.go @@ -18,6 +18,9 @@ const ( AuthBJJCredentialJSONLDContext = "https://schema.iden3.io/core/jsonld/auth.jsonld" AuthBJJCredentialTypeID = "https://schema.iden3.io/core/jsonld/auth.jsonld#AuthBJJCredential" + + Iden3PaymentRailsRequestV1SchemaJSON = `{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Iden3PaymentRailsRequestV1":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"},{"name":"expirationDate","type":"uint256"},{"name":"nonce","type":"uint256"},{"name":"metadata","type":"bytes"}]}` + Iden3PaymentRailsERC20RequestV1SchemaJSON = `{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Iden3PaymentRailsERC20RequestV1":[{"name":"tokenAddress","type":"address"},{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"},{"name":"expirationDate","type":"uint256"},{"name":"nonce","type":"uint256"},{"name":"metadata","type":"bytes"}]}` ) // SchemaFormat type diff --git a/internal/core/services/payment.go b/internal/core/services/payment.go index a2411e3d..63e6f676 100644 --- a/internal/core/services/payment.go +++ b/internal/core/services/payment.go @@ -6,6 +6,7 @@ import ( "crypto/rand" b64 "encoding/base64" "encoding/hex" + "encoding/json" "fmt" "math/big" "strconv" @@ -33,22 +34,38 @@ import ( ) type payment struct { - networkResolver network.Resolver - settings payments.Config - schemaService ports.SchemaService - paymentsStore ports.PaymentRepository - kms kms.KMSType + networkResolver network.Resolver + settings payments.Config + schemaService ports.SchemaService + paymentsStore ports.PaymentRepository + kms kms.KMSType + iden3PaymentRailsRequestV1Types apitypes.Types + iden3PaymentRailsERC20RequestV1Types apitypes.Types } // NewPaymentService creates a new payment service -func NewPaymentService(payOptsRepo ports.PaymentRepository, resolver network.Resolver, schemaSrv ports.SchemaService, settings *payments.Config, kms kms.KMSType) ports.PaymentService { - return &payment{ - networkResolver: resolver, - settings: *settings, - schemaService: schemaSrv, - paymentsStore: payOptsRepo, - kms: kms, +func NewPaymentService(payOptsRepo ports.PaymentRepository, resolver network.Resolver, schemaSrv ports.SchemaService, settings *payments.Config, kms kms.KMSType) (ports.PaymentService, error) { + iden3PaymentRailsRequestV1Types := apitypes.Types{} + iden3PaymentRailsERC20RequestV1Types := apitypes.Types{} + err := json.Unmarshal([]byte(domain.Iden3PaymentRailsRequestV1SchemaJSON), &iden3PaymentRailsRequestV1Types) + if err != nil { + log.Error(context.Background(), "failed to unmarshal Iden3PaymentRailsRequestV1 schema", "err", err) + return nil, err + } + err = json.Unmarshal([]byte(domain.Iden3PaymentRailsERC20RequestV1SchemaJSON), &iden3PaymentRailsERC20RequestV1Types) + if err != nil { + log.Error(context.Background(), "failed to unmarshal Iden3PaymentRailsERC20RequestV1 schema", "err", err) + return nil, err } + return &payment{ + networkResolver: resolver, + settings: *settings, + schemaService: schemaSrv, + paymentsStore: payOptsRepo, + kms: kms, + iden3PaymentRailsRequestV1Types: iden3PaymentRailsRequestV1Types, + iden3PaymentRailsERC20RequestV1Types: iden3PaymentRailsERC20RequestV1Types, + }, nil } // CreatePaymentOption creates a payment option for a specific issuer @@ -440,37 +457,19 @@ func (p *payment) paymentRequestSignature( ID: string(decodedKeyID), } + var types apitypes.Types + switch paymentType { + case string(protocol.Iden3PaymentRailsRequestV1Type): + types = p.iden3PaymentRailsRequestV1Types + case string(protocol.Iden3PaymentRailsERC20RequestV1Type): + types = p.iden3PaymentRailsERC20RequestV1Types + default: + log.Error(ctx, fmt.Sprintf("unsupported payment type '%s'", paymentType), "err", err) + return nil, fmt.Errorf("unsupported payment type '%s:'", paymentType) + } + typedData := apitypes.TypedData{ - Types: apitypes.Types{ - "EIP712Domain": []apitypes.Type{ - {Name: "name", Type: "string"}, - {Name: "version", Type: "string"}, - {Name: "chainId", Type: "uint256"}, - {Name: "verifyingContract", Type: "address"}, - }, - paymentType: []apitypes.Type{ - { - Name: "recipient", - Type: "address", - }, - { - Name: "amount", - Type: "uint256", - }, - { - Name: "expirationDate", - Type: "uint256", - }, - { - Name: "nonce", - Type: "uint256", - }, - { - Name: "metadata", - Type: "bytes", - }, - }, - }, + Types: types, PrimaryType: paymentType, Domain: apitypes.TypedDataDomain{ Name: "MCPayment", @@ -487,32 +486,6 @@ func (p *payment) paymentRequestSignature( }, } if paymentType == string(protocol.Iden3PaymentRailsERC20RequestV1Type) { - typedData.Types[paymentType] = []apitypes.Type{ - { - Name: "tokenAddress", - Type: "address", - }, - { - Name: "recipient", - Type: "address", - }, - { - Name: "amount", - Type: "uint256", - }, - { - Name: "expirationDate", - Type: "uint256", - }, - { - Name: "nonce", - Type: "uint256", - }, - { - Name: "metadata", - Type: "bytes", - }, - } typedData.Message["tokenAddress"] = setting.PaymentOption.ContractAddress.String() } typedDataBytes, _, err := apitypes.TypedDataAndHash(typedData)