Skip to content

Commit

Permalink
chore: add support for multiples queries (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
martinsaporiti authored Jan 23, 2024
1 parent 399c2fd commit 8b47bb1
Show file tree
Hide file tree
Showing 4 changed files with 575 additions and 209 deletions.
110 changes: 69 additions & 41 deletions api/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,40 +55,43 @@ paths:
value:
{
"chainID": "80001",
"circuitID": "credentialAtomicQuerySigV2",
"reason": "test flow",
"to": null,
"query": {
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld",
"allowedIssuers": [
"*"
],
"type": "KYCAgeCredential",
"credentialSubject": {
"birthday": {
"$lt": 20200424
"skipClaimRevocationCheck": false,
"scope": [
{
"circuitID": "credentialAtomicQuerySigV2",
"query": {
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld",
"allowedIssuers": [ "*" ],
"type": "KYCAgeCredential",
"credentialSubject": {
"birthday": {
"$eq": 19960424
}
}
}
}
}
]
}
OnChain:
value:
{
"circuitID": "credentialAtomicQuerySigV2OnChain",
"reason": "test flow",
"to": null,
"query": {
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld",
"allowedIssuers": [
"*"
],
"type": "KYCAgeCredential",
"credentialSubject": {
"birthday": {
"$lt": 20020101
"chainID": "80001",
"skipClaimRevocationCheck": false,
"scope": [
{
"circuitID": "credentialAtomicQuerySigV2",
"query": {
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld",
"allowedIssuers": [ "*" ],
"type": "KYCAgeCredential",
"credentialSubject": {
"birthday": {
"$eq": 19960424
}
}
}
}
},
],
"transactionData": {
"contractAddress": "0xE826f870852D7eeeB79B2C030298f9B5DAA8C8a3",
"methodID": "b68967e2",
Expand Down Expand Up @@ -345,26 +348,39 @@ components:
example: 'credentialAtomicQuerySigV2'
query:
$ref: '#/components/schemas/Query'
example:
{
"circuitID": "credentialAtomicQuerySigV2",
"query": {
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld",
"allowedIssuers": [ "*" ],
"type": "KYCAgeCredential",
"credentialSubject": {
"birthday": {
"$eq": 19960424
}
}
}
}

Query:
type: object
example:
{
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld",
"allowedIssuers": ["*"],
"type": "KYCAgeCredential",
"credentialSubject": {
"birthday": {
"$lt": 20200424
}
}
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld",
"allowedIssuers": ["*"],
"type": "KYCAgeCredential",
"credentialSubject": {
"birthday": {
"$lt": 20200424
}
}
}

SignInRequest:
type: object
required:
- query
- circuitID
- scope
properties:
chainID:
type: string
Expand All @@ -373,20 +389,32 @@ components:
`80001`: `mumbai`
`137` : `mainnet`
example: '80001'
circuitID:
type: string
example: 'credentialAtomicQuerySigV2'
reason:
type: string
example: 'test flow'
to:
type: string
example: null
query:
$ref : '#/components/schemas/Query'
scope:
type: array
items:
$ref: '#/components/schemas/ScopeRequest'
transactionData:
$ref : '#/components/schemas/TransactionData'

ScopeRequest:
type: object
required:
- circuitId
- query
properties:
circuitId:
type: string
example: 'credentialAtomicQuerySigV2'
query:
$ref: '#/components/schemas/Query'


TransactionDataResponse:
type: object
description: |
Expand Down
15 changes: 10 additions & 5 deletions internal/api/api.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

89 changes: 59 additions & 30 deletions internal/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,12 @@ func (s *Server) QRStore(ctx context.Context, request QRStoreRequestObject) (QRS
func (s *Server) SignIn(_ context.Context, request SignInRequestObject) (SignInResponseObject, error) {
sessionID := uuid.New()

switch request.Body.CircuitID {
if len(request.Body.Scope) == 0 {
log.Error("field scope is empty")
return SignIn400JSONResponse{N400JSONResponse{Message: "field scope is empty"}}, nil
}

switch request.Body.Scope[0].CircuitId {
case "credentialAtomicQuerySigV2", "credentialAtomicQueryMTPV2", "credentialAtomicQueryV3-beta.0":
authReq, err := getAuthRequestOffChain(request, s.cfg, sessionID)
if err != nil {
Expand All @@ -243,7 +248,7 @@ func (s *Server) SignIn(_ context.Context, request SignInRequestObject) (SignInR
SessionID: sessionID,
}, nil
default:
log.Errorf("invalid circuitID: %s", request.Body.CircuitID)
log.Errorf("invalid circuitID: %s", request.Body.Scope[0].CircuitId)
return SignIn400JSONResponse{N400JSONResponse{Message: "invalid circuitID"}}, nil
}
}
Expand Down Expand Up @@ -410,32 +415,50 @@ func validateOffChainRequest(request SignInRequestObject) error {
return fmt.Errorf("field chainId value is wrong, got %s, expected %s or %s", *request.Body.ChainID, mumbaiNetwork, mainnetNetwork)
}

if err := validateRequestQuery(request.Body.Query); err != nil {
if err := validateRequestQuery(true, request.Body.Scope); err != nil {
return err
}

return nil
}

func validateRequestQuery(query map[string]interface{}) error {
if query == nil {
return errors.New("field query is empty")
}
func validateRequestQuery(offChainRequest bool, scope []ScopeRequest) error {
for _, scope := range scope {
if scope.CircuitId == "" {
return errors.New("field circuitId is empty")
}

if query["context"] == nil || query["context"] == "" {
return errors.New("context cannot be empty")
}
if offChainRequest {
if scope.CircuitId != "credentialAtomicQuerySigV2" && scope.CircuitId != "credentialAtomicQueryMTPV2" && scope.CircuitId != "credentialAtomicQueryV3-beta.0" {
return fmt.Errorf("field circuitId value is wrong, got %s, expected credentialAtomicQuerySigV2 or credentialAtomicQueryMTPV2 or credentialAtomicQueryV3-beta.0", scope.CircuitId)
}
}

if query["type"] == nil || query["type"] == "" {
return errors.New("type cannot be empty")
}
if !offChainRequest {
if scope.CircuitId != "credentialAtomicQuerySigV2OnChain" && scope.CircuitId != "credentialAtomicQueryMTPV2OnChain" {
return fmt.Errorf("field circuitId value is wrong, got %s, expected credentialAtomicQuerySigV2OnChain or credentialAtomicQueryMTPV2OnChain", scope.CircuitId)
}
}

if query["allowedIssuers"] == nil {
return errors.New("allowedIssuers cannot be empty")
}
if scope.Query == nil {
return errors.New("field query is empty")
}

if scope.Query["context"] == nil || scope.Query["context"] == "" {
return errors.New("context cannot be empty")
}

if query["credentialSubject"] == nil {
return errors.New("credentialSubject cannot be empty")
if scope.Query["type"] == nil || scope.Query["type"] == "" {
return errors.New("type cannot be empty")
}

if scope.Query["allowedIssuers"] == nil {
return errors.New("allowedIssuers cannot be empty")
}

if scope.Query["credentialSubject"] == nil {
return errors.New("credentialSubject cannot be empty")
}
}

return nil
Expand All @@ -455,18 +478,19 @@ func getAuthRequestOffChain(req SignInRequestObject, cfg config.Config, sessionI
authReq.To = *req.Body.To
}

mtpProofRequest := protocol.ZeroKnowledgeProofRequest{
ID: uint32(1),
CircuitID: req.Body.CircuitID,
Query: req.Body.Query,
for i, scope := range req.Body.Scope {
mtpProofRequest := protocol.ZeroKnowledgeProofRequest{
ID: uint32(i),
CircuitID: scope.CircuitId,
Query: scope.Query,
}
authReq.Body.Scope = append(authReq.Body.Scope, mtpProofRequest)
}
authReq.Body.Scope = append(authReq.Body.Scope, mtpProofRequest)

return authReq, nil
}

func checkOnChainRequest(req SignInRequestObject) error {
if err := validateRequestQuery(req.Body.Query); err != nil {
if err := validateRequestQuery(false, req.Body.Scope); err != nil {
return err
}

Expand Down Expand Up @@ -498,19 +522,24 @@ func getContractInvokeRequestOnChain(req SignInRequestObject, cfg config.Config)
return protocol.ContractInvokeRequestMessage{}, err
}

mtpProofRequest := protocol.ZeroKnowledgeProofRequest{
ID: uint32(1),
CircuitID: req.Body.CircuitID,
Query: req.Body.Query,
mtpProofRequests := make([]protocol.ZeroKnowledgeProofRequest, len(req.Body.Scope))
for i, scope := range req.Body.Scope {
mtpProofRequest := protocol.ZeroKnowledgeProofRequest{
ID: uint32(i),
CircuitID: scope.CircuitId,
Query: scope.Query,
}
mtpProofRequests[i] = mtpProofRequest
}

transactionData := protocol.TransactionData{
ContractAddress: req.Body.TransactionData.ContractAddress,
MethodID: req.Body.TransactionData.MethodID,
ChainID: req.Body.TransactionData.ChainID,
Network: req.Body.TransactionData.Network,
}
id := uuid.NewString()
authReq := auth.CreateContractInvokeRequest(getReason(req.Body.Reason), getSenderID(strconv.Itoa(transactionData.ChainID), cfg), transactionData, mtpProofRequest)
authReq := auth.CreateContractInvokeRequest(getReason(req.Body.Reason), getSenderID(strconv.Itoa(transactionData.ChainID), cfg), transactionData, mtpProofRequests...)
authReq.ID = id
authReq.ThreadID = id
authReq.To = ""
Expand Down
Loading

0 comments on commit 8b47bb1

Please sign in to comment.