Skip to content

Commit

Permalink
Add statesInfo into circuit inputs response. Fix cacheDir handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
olomix committed Jan 10, 2025
1 parent fd0d97b commit 11ecaec
Show file tree
Hide file tree
Showing 10 changed files with 586 additions and 55 deletions.
55 changes: 36 additions & 19 deletions cmd/polygonid/polygonid.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ func maybeCreateStatus(status **C.PLGNStatus, code C.PLGNStatusCode,
*status = s
}

// Deprecated: Use PLGNAGenerateInputs with additional
// `"request": {"circuitId": "authV2"}` in the request json. This function
// does not support `statsInfo` in response and returns inputs
// on top level of response object.
//
//export PLGNAuthV2InputsMarshal
func PLGNAuthV2InputsMarshal(jsonResponse **C.char, in *C.char,
status **C.PLGNStatus) bool {
Expand Down Expand Up @@ -610,6 +615,7 @@ func marshalInputsResponse(
var resp struct {
Inputs json.RawMessage `json:"inputs"`
VerifiablePresentation any `json:"verifiablePresentation,omitempty"`
StatesInfo json.RawMessage `json:"statesInfo,omitempty"`
}
if inputsResponse.VerifiablePresentation != nil {
resp.VerifiablePresentation = inputsResponse.VerifiablePresentation
Expand All @@ -620,6 +626,18 @@ func marshalInputsResponse(
return "", err
}

i, ok := inputsResponse.Inputs.(circuits.StatesInfoProvider)
if ok {
statesInfo, err := i.GetStatesInfo()
if err != nil {
return "", err
}
resp.StatesInfo, err = json.Marshal(statesInfo)
if err != nil {
return "", err
}
}

respBytes, err := json.Marshal(resp)
if err != nil {
return "", err
Expand Down Expand Up @@ -751,17 +769,17 @@ func PLGNALinkedMultiQueryInputs(jsonResponse **C.char, in *C.char,
jsonResponse, in, cfg, status)
}

// PLGNAQueryInputs returns the inputs for the circuit based on the
// PLGNAGenerateInputs returns the inputs for the circuit based on the
// request.circuitId field.
//
//export PLGNAQueryInputs
func PLGNAQueryInputs(jsonResponse **C.char, in *C.char,
//export PLGNAGenerateInputs
func PLGNAGenerateInputs(jsonResponse **C.char, in *C.char,
cfg *C.char, status **C.PLGNStatus) bool {

ctx, cancel := logAPITime()
defer cancel()

return prepareInputs(ctx, c_polygonid.GenericQueryInputsFromJson,
return prepareInputs(ctx, c_polygonid.GenericInputsFromJson,
jsonResponse, in, cfg, status)
}

Expand Down Expand Up @@ -804,7 +822,7 @@ func PLGNCleanCache2(cfg *C.char, status **C.PLGNStatus) bool {
_, cancel := logAPITime()
defer cancel()

envCfg, err := createEnvConfig(cfg)
envCfg, err := c_polygonid.NewEnvConfigFromJSON(cStrToGoSlice(cfg))
if err != nil {
maybeCreateStatus(status, C.PLGNSTATUSCODE_ERROR, "%v", err.Error())
return false
Expand All @@ -829,7 +847,7 @@ func PLGNCacheCredentials(in *C.char, cfg *C.char, status **C.PLGNStatus) bool {

inData := C.GoBytes(unsafe.Pointer(in), C.int(C.strlen(in)))

envCfg, err := createEnvConfig(cfg)
envCfg, err := c_polygonid.NewEnvConfigFromJSON(cStrToGoSlice(cfg))
if err != nil {
maybeCreateStatus(status, C.PLGNSTATUSCODE_ERROR, "%v", err.Error())
return false
Expand Down Expand Up @@ -882,7 +900,7 @@ func PLGNW3CCredentialFromOnchainHex(jsonResponse **C.char, in *C.char,

inData := C.GoBytes(unsafe.Pointer(in), C.int(C.strlen(in)))

envCfg, err := createEnvConfig(cfg)
envCfg, err := c_polygonid.NewEnvConfigFromJSON(cStrToGoSlice(cfg))
if err != nil {
maybeCreateStatus(status, C.PLGNSTATUSCODE_ERROR, "%v", err.Error())
return false
Expand Down Expand Up @@ -939,7 +957,7 @@ func PLGNDescribeID(jsonResponse **C.char, in *C.char, cfg *C.char,
return false
}

envCfg, err := createEnvConfig(cfg)
envCfg, err := c_polygonid.NewEnvConfigFromJSON(cStrToGoSlice(cfg))
if err != nil {
maybeCreateStatus(status, C.PLGNSTATUSCODE_ERROR, "%v", err.Error())
return false
Expand Down Expand Up @@ -1002,15 +1020,6 @@ func PLGNBabyJubJubPublicCompress(jsonResponse **C.char, in *C.char,
in, cfg, status)
}

// createEnvConfig returns empty config if input json is nil.
func createEnvConfig(cfgJson *C.char) (c_polygonid.EnvConfig, error) {
var cfgData []byte
if cfgJson != nil {
cfgData = C.GoBytes(unsafe.Pointer(cfgJson), C.int(C.strlen(cfgJson)))
}
return c_polygonid.NewEnvConfigFromJSON(cfgData)
}

type atomicQueryInputsFn func(ctx context.Context, cfg c_polygonid.EnvConfig,
in []byte) (c_polygonid.AtomicQueryInputsResponse, error)

Expand All @@ -1029,7 +1038,7 @@ func prepareInputs(ctx context.Context, fn atomicQueryInputsFn,

inData := C.GoBytes(unsafe.Pointer(in), C.int(C.strlen(in)))

envCfg, err := createEnvConfig(cfg)
envCfg, err := c_polygonid.NewEnvConfigFromJSON(cStrToGoSlice(cfg))
if err != nil {
maybeCreateStatus(status, C.PLGNSTATUSCODE_ERROR, "%v", err.Error())
return false
Expand Down Expand Up @@ -1108,6 +1117,14 @@ func statusFromError(err error) (C.PLGNStatusCode, string) {
return C.PLGNSTATUSCODE_ERROR, err.Error()
}

func cStrToGoSlice(in *C.char) []byte {
var out []byte
if in != nil {
out = C.GoBytes(unsafe.Pointer(in), C.int(C.strlen(in)))
}
return out
}

func callGenericFn[R any](
fn func(context.Context, c_polygonid.EnvConfig, []byte) (R, error),
jsonResponse **C.char, in *C.char, cfg *C.char,
Expand All @@ -1122,7 +1139,7 @@ func callGenericFn[R any](
return false
}

envCfg, err := createEnvConfig(cfg)
envCfg, err := c_polygonid.NewEnvConfigFromJSON(cStrToGoSlice(cfg))
if err != nil {
maybeCreateStatus(status, C.PLGNSTATUSCODE_ERROR, "%v", err.Error())
return false
Expand Down
87 changes: 87 additions & 0 deletions cmd/polygonid/polygonid_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package main

import (
"context"
"encoding/hex"
"encoding/json"
"math/big"
"math/rand"
"os"
"strings"
"testing"
"time"

c_polygonid "github.com/0xPolygonID/c-polygonid"
httpmock "github.com/0xPolygonID/c-polygonid/testing"
core "github.com/iden3/go-iden3-core/v2"
"github.com/iden3/go-iden3-crypto/poseidon"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -127,3 +131,86 @@ func TestCreateClaimAllFields2(t *testing.T) {

t.Log(string(cBytes))
}

func readFixtureFile(name string) []byte {
fileBytes, err := os.ReadFile("testdata/" + name)
if err != nil {
panic(err)
}
return fileBytes
}

func TestGenrateInputs(t *testing.T) {
type PrepareInputsFn func(
ctx context.Context, cfg c_polygonid.EnvConfig, in []byte) (
c_polygonid.AtomicQueryInputsResponse, error)

cacheDir, err := os.MkdirTemp("", "")
require.NoError(t, err)
t.Cleanup(func() {
err := os.RemoveAll(cacheDir)
require.NoError(t, err)
})

doTest := func(t testing.TB, inFile, wantOutFile string,
fn PrepareInputsFn, wantVR map[string]any, cfg c_polygonid.EnvConfig,
wantErr string) {

err := c_polygonid.CleanCache(cacheDir)
require.NoError(t, err)

ctx := context.Background()
out, err := fn(ctx, cfg, readFixtureFile(inFile))
if wantErr != "" {
require.EqualError(t, err, wantErr)
return
}
require.NoError(t, err)

resp, err := marshalInputsResponse(out)
require.NoError(t, err)

assertEqualWithoutTimestamp(t, wantOutFile, resp)
}

env := c_polygonid.EnvConfig{CacheDir: cacheDir}
t.Run("atomic_query_v3_on_chain_mtp_inputs", func(t *testing.T) {
defer httpmock.MockHTTPClient(t, map[string]string{
"http://localhost:8001/api/v1/identities/did%3Apolygonid%3Apolygon%3Amumbai%3A2qDnyCaxj4zdYmj6LbegYMjWSnkbKAyqtq31YeuyZV/claims/revocation/status/3972757": "../../testdata/httpresp_rev_status_3972757.json",
"https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": "../../testdata/httpresp_kyc-v3.json-ld",
"https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/iden3credential-v2.json-ld": "../../testdata/httpresp_iden3credential_v2.json",
})()

doTest(t, "atomic_query_v3_on_chain_mtp_inputs.json",
"atomic_query_v3_on_chain_mtp_output.json",
c_polygonid.AtomicQueryV3OnChainInputsFromJson, nil, env, "")
})
t.Run("auth_v2_inputs", func(t *testing.T) {
doTest(t, "auth_v2_inputs_in.json", "auth_v2_inputs_out.json",
c_polygonid.AuthV2InputsFromJson, nil, env, "")
})

}

func assertEqualWithoutTimestamp(t testing.TB, wantFName string,
actual string) {

jsonWant := readFixtureFile(wantFName)
var wantObj map[string]any
err := json.Unmarshal(jsonWant, &wantObj)
require.NoError(t, err)

var actualObj map[string]any
err = json.Unmarshal([]byte(actual), &actualObj)
require.NoError(t, err)

actualInputsObj, ok := actualObj["inputs"].(map[string]any)
require.True(t, ok)

if ts, ok := actualInputsObj["timestamp"]; ok {
wantObj["inputs"].(map[string]any)["timestamp"] = ts
}

require.Equal(t, wantObj, actualObj, "file name: %s\nwant: %s\ngot: %s",
wantFName, jsonWant, actual)
}
139 changes: 139 additions & 0 deletions cmd/polygonid/testdata/atomic_query_v3_on_chain_mtp_inputs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
{
"id": "2qNcq2LGHFyikZaWfsif1vjrpKFuTowsRV9U1oEhkB",
"profileNonce": "0",
"claimSubjectProfileNonce": "0",
"authClaim":[
"80551937543569765027552589160822318028",
"0",
"18241173998748741404449730252371072752192413092443487065695081933963692076033",
"1330367256434394070988833218825135639784691088078528177530136343975207856992",
"0","0","0","0"
],
"authClaimIncMtp":{
"existence":true,
"siblings":[
"0",
"16122227591077608214426811451297936630776316583414054146380942393644089006753"
]
},
"authClaimNonRevMtp":{"existence":false,"siblings":[]},
"treeState":{
"state":"3455793648389793511224972913807237799755511487265044435383221641855224272477",
"claimsRoot":"12863526460000963806360638100765589244767101189459134829137262186265339590400",
"revocationRoot":"0",
"rootOfRoots":"0"
},
"gistProof": {
"root": "5005919421435686441886912154983595081356506147906956636160716123399604497694",
"proof": {
"existence": false,
"siblings": [
"9572034982910400342435969278331518000622332242067560582395787734704675688171",
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0",
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0",
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0",
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0",
"0", "0", "0", "0", "0", "0", "0"
]
}
},

"signature": "a373921f2be69febb33730a0ce85864476364317d51df12a4d051da5180a3c02c1051aa3a5405538d26c998d34ed865065d73685bc7e8cf2546f87de2adbf703",
"challenge": "14274525809225776254148766756521966776753328068184040579440171048150881324976",

"verifiableCredentials": {
"id": "http://localhost:8001/api/v1/identities/did:polygonid:polygon:mumbai:2qDnyCaxj4zdYmj6LbegYMjWSnkbKAyqtq31YeuyZV/claims/63d05676-b22b-11ed-b489-e24d9cbdb31c",
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/iden3credential-v2.json-ld",
"https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld"
],
"type": [
"VerifiableCredential",
"KYCAgeCredential"
],
"expirationDate": "2361-03-21T15:14:48-04:00",
"issuanceDate": "2023-02-21T16:04:54.628883-05:00",
"credentialSubject": {
"birthday": 19960424,
"documentType": 2,
"id": "did:polygonid:polygon:mumbai:2qNcq2LGHFyikZaWfsif1vjrpKFuTowsRV9U1oEhkB",
"type": "KYCAgeCredential"
},
"credentialStatus": {
"id": "http://localhost:8001/api/v1/identities/did%3Apolygonid%3Apolygon%3Amumbai%3A2qDnyCaxj4zdYmj6LbegYMjWSnkbKAyqtq31YeuyZV/claims/revocation/status/3972757",
"revocationNonce": 3972757,
"type": "SparseMerkleTreeProof"
},
"issuer": "did:polygonid:polygon:mumbai:2qDnyCaxj4zdYmj6LbegYMjWSnkbKAyqtq31YeuyZV",
"credentialSchema": {
"id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCAgeCredential-v3.json",
"type": "JsonSchemaValidator2018"
},
"proof": [
{
"type": "BJJSignature2021",
"issuerData": {
"id": "did:polygonid:polygon:mumbai:2qDnyCaxj4zdYmj6LbegYMjWSnkbKAyqtq31YeuyZV",
"state": {
"claimsTreeRoot": "4c4eb593366ca7ba87c8c39678324cfc50c088d1714cb2bfb1d4198f3fb48b0c",
"value": "e05968ec751d34825931e5faae3b1946af92386f7a41db02cb6acfd8f12e2029"
},
"authCoreClaim": "cca3371a6cb1b715004407e325bd993c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fe4494aaaef099b11a5cdd64c486d213e389338be963e7858d8ecf6773b8af14ac5981df12305e138b45f3985565852db666e4419ee07487c1a75b447a52ff050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"mtp": {
"existence": true,
"siblings": [
"8492005947035117331601304230085928449440142032894061581492108583460376442873"
]
},
"credentialStatus": {
"id": "http://localhost:8001/api/v1/identities/did%3Apolygonid%3Apolygon%3Amumbai%3A2qDnyCaxj4zdYmj6LbegYMjWSnkbKAyqtq31YeuyZV/claims/revocation/status/0",
"revocationNonce": 0,
"type": "SparseMerkleTreeProof"
}
},
"coreClaim": "c9b2370371b7fa8b3dab2a5ba81b68382a0000000000000000000000000000000212df9ac65c2ec1e545f9fa614fccfaba60435189f3d5a68feee8a307e51000e0209be826b8670e7c970d2eca0632123c9cbb6b5f5a5cf1480ad2b3f62b05180000000000000000000000000000000000000000000000000000000000000000959e3c0000000000281cdcdf0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"signature": "d608a6be79730a6bf873438ff23b31b9e1d3caa5d2a30470ec3b2ff3633e4798262e192336b0b4588cc0c80417b4cd6e89182451f20cfddc77d784022f566300"
},
{
"type": "Iden3SparseMerkleProof",
"issuerData": {
"id": "did:polygonid:polygon:mumbai:2qDnyCaxj4zdYmj6LbegYMjWSnkbKAyqtq31YeuyZV",
"state": {
"txId": "0x51633300d6d5fb013134d4ea48663b7246a6b333c09bfafe4c440226b79ba903",
"blockTimestamp": 1677013536,
"blockNumber": 208660,
"rootOfRoots": "411df2b18d24592fd0730cbdb2425894cb4a24dac85328188f891333a311b315",
"claimsTreeRoot": "57b358eaacc24c2563f003a748a5b7f45b2b9ae1cd83e70085bfe0dcf9e8b918",
"revocationTreeRoot": "0000000000000000000000000000000000000000000000000000000000000000",
"value": "4646aede7443039a4bfd8f069d8f7f74f5075f6b794fb04663ab02fb76ba0c26"
}
},
"coreClaim": "c9b2370371b7fa8b3dab2a5ba81b68382a0000000000000000000000000000000212df9ac65c2ec1e545f9fa614fccfaba60435189f3d5a68feee8a307e51000e0209be826b8670e7c970d2eca0632123c9cbb6b5f5a5cf1480ad2b3f62b05180000000000000000000000000000000000000000000000000000000000000000959e3c0000000000281cdcdf0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"mtp": {
"existence": true,
"siblings": [
"3356738306440460467584170579991940197172182577060925476949151659410412574707",
"0",
"8492005947035117331601304230085928449440142032894061581492108583460376442873"
]
}
}
]
},
"request": {
"id": 84239,
"circuitId": "credentialAtomicQueryV3OnChain-beta.1",
"query": {
"allowedIssuers": "unused",
"context": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld",
"type": "KYCAgeCredential",
"credentialSubject": {
"birthday": {
"$gt": 1
}
},
"proofType": "Iden3SparseMerkleTreeProof"
}
}
}
Loading

0 comments on commit 11ecaec

Please sign in to comment.