From 8f268e8389a8d3554a0169ef137063c78e2a39f2 Mon Sep 17 00:00:00 2001 From: Yasushi Takahashi Date: Fri, 6 Aug 2021 00:48:27 +0900 Subject: [PATCH] fix(example): send http request to discounted-cartrade Signed-off-by: Yasushi Takahashi --- examples/discounted-cartrade/README.md | 187 +++-- .../req_discounted_cartrade.py | 664 ++++++++++++++++++ .../register-indy-data/sample_Userside.py | 586 ---------------- 3 files changed, 796 insertions(+), 641 deletions(-) create mode 100644 examples/register-indy-data/req_discounted_cartrade.py delete mode 100644 examples/register-indy-data/sample_Userside.py diff --git a/examples/discounted-cartrade/README.md b/examples/discounted-cartrade/README.md index e24fd4434b..c971d91381 100644 --- a/examples/discounted-cartrade/README.md +++ b/examples/discounted-cartrade/README.md @@ -105,39 +105,29 @@ Assume the following two directories exist in the same directory: - please check indy_pool, nginx and valipy are booting -3. Please exec "sample_Userside.py" at every "docker-compose up" - - 3-1) please copy "sample_Userside.py" to "indy-sdk/samples/python" - - - $ cd cactus/examples/register-indy-data - - $ cp -frp sample_Userside.py ../../../indy-sdk/samples/python/src - - 3-2) please exec "sample_Userside.py" in valipy - - - $ docker ps | grep valipy - - - please check ID - - $ sudo docker exec -it validator bash - - $ cd /root/indy-sdk/samples/python - - $ TEST_POOL_IP=172.16.0.2 python -m src.sample_Userside > sample_Userside.log 2>&1 - -4. Please exec INDY validator (in velipy) +3. Please exec INDY validator + + $docker exec -it validator bash $ cd /root/validator $ TEST_POOL_IP=172.16.0.2 python -m main -5. Please exec test driver (in host server) +4. Please exec test driver (in host server) - $ cd cactus/packages-python/cactus_validator_socketio/testcli + $ cp -frp cactus/examples/register-indy-data/req_discounted_cartrade.py indy-sdk/samples/python/src - $ npm install + $ cd indy-sdk/samples/python - $ cp -frp ../../../../indy-sdk/samples/python/sample_Userside.log ./ + $ TEST_POOL_IP=172.16.0.2 python -m src.req_discounted_cartrade - $ tail -1 < sample_Userside.log | sed -e 's%INFO:__main__:%%' > myproof.json + - The log exits with an error, but if myproof.json is generated, it is OK. + + $ cd ../../../cactus/packages-python/cactus_validator_socketio/testcli + + $ npm install + + $ cp -frp ../../../../indy-sdk/samples/python/myproof.json ./ $ node testsock.js @@ -152,24 +142,34 @@ Assume the following two directories exist in the same directory: ## How to use: discounted-cartrade ### Preparations -- The above commands is executed. -- Starting one Validator - -- "validatorUrl": "https://172.16.0.4:8000" +- Please exec 3 validators (ethereum, fabric, indy). + + - "validatorUrl": "https://localhost:5050" + - "validatorUrl": "https://localhost:5040" + - "validatorUrl": "https://172.16.0.4:8000" + - The following drivers work properly: - -- testcli/testsock.js -- "sample_Userside.py" is executed in "How to execute INDY validator". -### Creating BLP container -1. Please get branch "master" -2. $ cd cactus/examples/discounted-cartrade/BLP_container -3. $ docker-compose -f docker-compose.yaml up + - unit_test/validatorDriver_getNumericBalance.js + + - unit_test/queryCar.js + + ​ unit_test/validatorDriver_signTransactionOffline.js + + - testcli/testsock.js + + - Please refer "How to execute INDY validator: 4. Please exec test driver (in host server)" + +- This procedure assumes the following two directories exist in the same directory: - - Executing the above command will not return to the console. When "Attaching to blp_container" is displayed, startup is completed. The following steps should be performed on a separate console. + - cactus ($ git clone https://github.com/hyperledger/cactus.git) + - indy-sdk ($ git clone https://github.com/hyperledger/indy-sdk.git) -### Booting (in blp_container) -1. $ docker exec -it blp_container bash -2. $ cd ~/cactus/packages +### How to boot +1. Please get branch "main" +2. $ cd cactus/packages 3. $ npm install + 4. If you modify the URL of the server for "cactus/packages/config/default.json", create and modify "cactus/examples/discounted-cartrade/config/usersetting.json". - applicationHostInfo.hostName - this is URL of the host returned in the Location header @@ -197,28 +197,105 @@ Assume the following two directories exist in the same directory: 11. $ npm run start - if you do this, discounted-cartrade starts to exec on 5034 port. -### Preparations before executing -Assume there exist "sample_Userside.log" which is a result file of "sample_Userside.py" -1. Go to the directory one level above cactus -2. tail -1 myproof.json -3. Replace all " in myproof.json with \" and save -4. Replace all \\" in myproof.json with \\\" and save -5. Remove a line break on the last line of myproof.json. -6. Creates a new file "discounted-cartrade_request_body.json" -7. Please write the following content in "discounted-cartrade_request_body.json" - - {"businessLogicID":"guks32pf","tradeParams":["0xec709e1774f0ce4aba47b52a499f9abaaa159f71", "0x9d624f7995e8bd70251f8265f2f9f2b49f169c55", "fuser01", "fuser02", "CAR1", "<>"],"authParams":["<>"]} +### How to execute +- a.) Transaction Execution + - Please run Python script instead of curl (script that runs from data registration with indy to HTTP requests to BLP) + + - To modify the transaction parameters, please modify the "http_req_params = {...}" part of the script "sample _ Userside.py". + + - please run the following command in an environment where discounted-cartrade is running and python can be run. We have confirmed that the following can be executed in the environment where "python3-indy==1.16.0" and "requests==2.26.0" are installed by the pip command. + + - $ cp -frp cactus/examples/register-indy-data/req_discounted_cartrade.py indy-sdk/samples/python/src + + $ cd indy-sdk/samples/python + + $ TEST_POOL_IP=172.16.0.2 python -m src.req_discounted_cartrade + + - A log similar to the following is output to the console: + + - [2021-07-26T10:15:27.664] [DEBUG] BusinessLogicCartrade - ##isPreferredCustomer result : true + + - If "##isPreferredCustomer result : true" is output, employee certification part is completed. + + - [2020-08-21T19:55:24.207] [INFO] TransactionManagement - tradeID: 20200821195524-001 + + [2020-08-21T19:55:24.282] [INFO] BusinessLogicCartrade - firstTransaction txId : 0xafe7c812ab55c02feb691d2133bbba2c38abaf7f221794c3ca833a29708f4653 + + [2020-08-21T19:56:20.005] [INFO] BusinessLogicCartrade - ##INFO: underEscrow -> underTransfer, businessLogicID: guks32pf, tradeID: 20200821195524-001 + + [2020-08-21T19:56:20.608] [INFO] BusinessLogicCartrade - secondTransaction txId : 17c7577f73560ea5955f3151ed678833aa45d1252b34c6f933a7123757e82969 + + [2020-08-21T19:56:23.691] [INFO] BusinessLogicCartrade - ##INFO: underTransfer -> underSettlement, businessLogicID: guks32pf, tradeID: 20200821195524-001 + + [2020-08-21T19:56:23.703] [INFO] BusinessLogicCartrade - thirdTransaction txId : 0x61acb066349e24319afdf272b35429d198046e10f8fca3972f17a9e9a4dca75d + + [2020-08-21T19:56:31.518] [INFO] BusinessLogicCartrade - ##INFO: completed cartrade, businessLogicID: guks32pf, tradeID: 20200821195524-001 + + - If "##INFO: completed cartrade," is output, cartrade part is completed. + +- b.) Transaction Reference + + - $ curl localhost:5034/api/v1/bl/trades/XXXXXXXXXXXXXX-XXX -XGET + +- c.) Login + + - $ curl localhost:5034/api/v1/bl/login/ -XPOST -H "Content-Type: application/json" -d '{"userid":"user01","pwd":"hoge"}' + +- d.) Balance Confirmation + + - $ curl localhost:5034/api/v1/bl/balance/9d624f7995e8bd70251f8265f2f9f2b49f169c55 + - At the end of the URL, specify the account + +- e.) QueryCar + + - $ curl localhost:5034/api/v1/bl/cars/CAR1 -XGET + +- f.) QueryAllCars + + - $ curl localhost:5034/api/v1/bl/cars/ -XGET + +- g.) GetAsset ("contractInfo.json" must be replaced) + + - "contractInfo.json" is still a sample file and should be replaced when confirming operation. + - $ curl localhost:5034/api/v1/bl/asset/ -XGET + +- h.) AddAsset ("contractInfo.json" must be replaced) + + - "contractInfo.json" is still a sample file and should be replaced when confirming operation. + - $ curl localhost:5034/api/v1/bl/asset/ -XPOST -H "Content-Type: application/json" -d '{"amount":100}' + +- i.) Executing Template Functions (execSyncFunction) + + - $ curl localhost:5034/api/v1/bl/template-trade/execSyncFunction/ -XPOST -H "Content-Type: application/json" -d '{"template": "name", "args": {"tokenID": "token-12345", "contractID": "contract-123456"}}' + + $ curl localhost:5034/api/v1/bl/template-trade/execSyncFunction/ -XPOST -H "Content-Type: application/json" -d '{"template": "symbol", "args": {"tokenID": "token-12345", "contractID": "contract-123456"}}' + + $ curl localhost:5034/api/v1/bl/template-trade/execSyncFunction/ -XPOST -H "Content-Type: application/json" -d '{"template": "decimals", "args": {"tokenID": "token-12345", "contractID": "contract-123456"}}' + + $ curl localhost:5034/api/v1/bl/template-trade/execSyncFunction/ -XPOST -H "Content-Type: application/json" -d '{"template": "totalSupply", "args": {"tokenID": "token-12345", "contractID": "contract-123456"}}' -### How to exec this app (in host) -1. Go to the directory one level above cactus + $ curl localhost:5034/api/v1/bl/template-trade/execSyncFunction/ -XPOST -H "Content-Type: application/json" -d '{"template": "balanceOf", "args": {"tokenID": "token-12345", "contractID": "contract-123456"}}' -2. $ curl localhost:5034/api/v1/bl/trades/ -XPOST -H "Content-Type: application/json" -d @discounted-cartrade_request_body.json +- j.) Executing Template Functions (sendSignedTransaction) -3. you can see the following logs: + - $ curl localhost:5034/api/v1/bl/template-trade/sendSignedTransaction/ -XPOST -H "Content-Type: application/json" -d '{"template": "transfer", "args": {"_from": "account001", "_to": "account002", "value": 1000, "tokenID": "token-12345", "contractID": "contract-123456"}}' - - [2021-07-26T10:15:27.420] [DEBUG] TransactionIndy - ##getDataFromIndy: result: [object Object] +- k.) nop-sample - [2021-07-26T10:15:27.420] [DEBUG] BusinessLogicCartrade - finish get Data from indy + - $ curl localhost:5034/api/v1/bl/nop-sample/ -XGET - [2021-07-26T10:15:27.664] [DEBUG] BusinessLogicCartrade - verify proof: ok +- l.) how to check - [2021-07-26T10:15:27.664] [DEBUG] BusinessLogicCartrade - ##isPreferredCustomer result : true + - How to check account balance + - unit_test/validatorDriver_getNumericBalance.js + - ex.) $ node validatorDriver_getNumericBalance.js + - The balance for the account appears in the Validator console as follows: + - [2020-08-18T17:06:15.795] [INFO] connector_main[6710] - Response :{"status":200,"amount":1900} + - How to check the car owner + - unit_test/queryCar.js + - ex.) $ node queryCar.js CAR1 + - The Car owner appears in the Validator console as follows: + - ##queryCar Params: CAR1 + - Transaction has been evaluated, result is: {"colour":"red","make":"Ford","model":"Mustang","owner":"fuser02"} + - How to change car ownership + - unit_test/validatorDriver_signTransactionOffline.js diff --git a/examples/register-indy-data/req_discounted_cartrade.py b/examples/register-indy-data/req_discounted_cartrade.py new file mode 100644 index 0000000000..c55a3dfe9a --- /dev/null +++ b/examples/register-indy-data/req_discounted_cartrade.py @@ -0,0 +1,664 @@ +import time + +from indy import anoncreds, did, ledger, pool, wallet, blob_storage + +import json +import logging + +import argparse +import sys +from ctypes import * +from os.path import dirname + +from indy.error import ErrorCode, IndyError + +from src.utils import get_pool_genesis_txn_path, run_coroutine, PROTOCOL_VERSION, ensure_previous_request_applied + +#use Requests +import requests + + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + +# http request parameters +# http_req_params = { +# "url": "http://localhost:5034/api/v1/bl/trades/", +# "businessLogicID": "guks32pf", +# "tradeParams": ["0xec709e1774f0ce4aba47b52a499f9abaaa159f71", +# "0x9d624f7995e8bd70251f8265f2f9f2b49f169c55", +# "fuser01", "fuser02", 50, "CAR1"], +# "authParams": ["<>"] +# } +http_req_params = { + "url": "http://localhost:5034/api/v1/bl/trades/", + "businessLogicID": "guks32pf", + "tradeParams": ["0xec709e1774f0ce4aba47b52a499f9abaaa159f71", + "0x9d624f7995e8bd70251f8265f2f9f2b49f169c55", + "fuser01", "fuser02", "CAR1"], + "authParams": ["<>"] +} + +file_name = "myproof.json" + +#parser = argparse.ArgumentParser(description='Run python getting-started scenario (Alice/Faber)') +parser = argparse.ArgumentParser(description='Run python getting-started scenario (Alice/Acme/Thrift)') +parser.add_argument('-t', '--storage_type', help='load custom wallet storage plug-in') +parser.add_argument('-l', '--library', help='dynamic library to load for plug-in') +parser.add_argument('-e', '--entrypoint', help='entry point for dynamic library') +parser.add_argument('-c', '--config', help='entry point for dynamic library') +parser.add_argument('-s', '--creds', help='entry point for dynamic library') +parser.add_argument('-m', '--mode', help='mode of send http request') + +args = parser.parse_args() + +# check if we need to dyna-load a custom wallet storage plug-in +if args.storage_type: + if not (args.library and args.entrypoint): + parser.print_help() + sys.exit(0) + stg_lib = CDLL(args.library) + result = stg_lib[args.entrypoint]() + if result != 0: + print("Error unable to load wallet storage", result) + parser.print_help() + sys.exit(0) + + # for postgres storage, also call the storage init (non-standard) + if args.storage_type == "postgres_storage": + try: + print("Calling init_storagetype() for postgres:", args.config, args.creds) + init_storagetype = stg_lib["init_storagetype"] + c_config = c_char_p(args.config.encode('utf-8')) + c_credentials = c_char_p(args.creds.encode('utf-8')) + result = init_storagetype(c_config, c_credentials) + print(" ... returns ", result) + except RuntimeError as e: + print("Error initializing storage, ignoring ...", e) + + print("Success, loaded wallet storage", args.storage_type) + + +async def run(): + logger.info("Getting started -> started") + + if not(args.mode == "http"): + pool_ = { + 'name': 'pool1' + } + logger.info("Open Pool Ledger: {}".format(pool_['name'])) + pool_['genesis_txn_path'] = get_pool_genesis_txn_path(pool_['name']) + pool_['config'] = json.dumps({"genesis_txn": str(pool_['genesis_txn_path'])}) + + # Set protocol version 2 to work with Indy Node 1.4 + await pool.set_protocol_version(PROTOCOL_VERSION) + + try: + await pool.create_pool_ledger_config(pool_['name'], pool_['config']) + except IndyError as ex: + if ex.error_code == ErrorCode.PoolLedgerConfigAlreadyExistsError: + pass + pool_['handle'] = await pool.open_pool_ledger(pool_['name'], None) + + logger.info("==============================") + #logger.info("=== Getting Trust Anchor credentials for Faber, Acme, Thrift and Government ==") + logger.info("=== Getting Trust Anchor credentials for Acme ==") + logger.info("------------------------------") + + steward = { + 'name': "Sovrin Steward", + 'wallet_config': json.dumps({'id': 'sovrin_steward_wallet'}), + 'wallet_credentials': json.dumps({'key': 'steward_wallet_key'}), + 'pool': pool_['handle'], + 'seed': '000000000000000000000000Steward1' + } + + await create_wallet(steward) + + logger.info("\"Sovrin Steward\" -> Create and store in Wallet DID from seed") + steward['did_info'] = json.dumps({'seed': steward['seed']}) + steward['did'], steward['key'] = await did.create_and_store_my_did(steward['wallet'], steward['did_info']) + + logger.info("==============================") + logger.info("== Getting Trust Anchor credentials - Government getting Verinym ==") + logger.info("------------------------------") + + government = { + 'name': 'Government', + 'wallet_config': json.dumps({'id': 'government_wallet'}), + 'wallet_credentials': json.dumps({'key': 'government_wallet_key'}), + 'pool': pool_['handle'], + 'role': 'TRUST_ANCHOR' + } + + await getting_verinym(steward, government) + + logger.info("==============================") + logger.info("== Getting Trust Anchor credentials - Acme getting Verinym ==") + logger.info("------------------------------") + + acme = { + 'name': 'Acme', + 'wallet_config': json.dumps({'id': 'acme_wallet'}), + 'wallet_credentials': json.dumps({'key': 'acme_wallet_key'}), + 'pool': pool_['handle'], + 'role': 'TRUST_ANCHOR' + } + + await getting_verinym(steward, acme) + + logger.info("==============================") + logger.info("== Getting Trust Anchor credentials - Thrift getting Verinym ==") + logger.info("------------------------------") + + thrift = { + 'name': 'Thrift', + 'wallet_config': json.dumps({'id': 'thrift_wallet'}), + 'wallet_credentials': json.dumps({'key': 'thrift_wallet_key'}), + 'pool': pool_['handle'], + 'role': 'TRUST_ANCHOR' + } + + await getting_verinym(steward, thrift) + + logger.info("==============================") + logger.info("=== Credential Schemas Setup ==") + logger.info("------------------------------") + + logger.info("\"Government\" -> Create \"Job-Certificate\" Schema") + job_certificate = { + 'name': 'Job-Certificate', + 'version': '0.2', + 'attributes': ['first_name', 'last_name', 'salary', 'employee_status', 'experience'] + } + (government['job_certificate_schema_id'], government['job_certificate_schema']) = \ + await anoncreds.issuer_create_schema(government['did'], job_certificate['name'], job_certificate['version'], + json.dumps(job_certificate['attributes'])) + job_certificate_schema_id = government['job_certificate_schema_id'] + + logger.info("\"Government\" -> Send \"Job-Certificate\" Schema to Ledger") + await send_schema(government['pool'], government['wallet'], government['did'], government['job_certificate_schema']) + + + time.sleep(1) # sleep 1 second before getting schema + + + logger.info("==============================") + logger.info("=== Acme Credential Definition Setup ==") + logger.info("------------------------------") + + logger.info("\"Acme\" -> Get from Ledger \"Job-Certificate\" Schema") + (acme['job_certificate_schema_id'], acme['job_certificate_schema']) = \ + await get_schema(acme['pool'], acme['did'], job_certificate_schema_id) + + logger.info("\"Acme\" -> Create and store in Wallet \"Acme Job-Certificate\" Credential Definition") + job_certificate_cred_def = { + 'tag': 'TAG1', + 'type': 'CL', + 'config': {"support_revocation": False} + } + (acme['job_certificate_cred_def_id'], acme['job_certificate_cred_def']) = \ + await anoncreds.issuer_create_and_store_credential_def(acme['wallet'], acme['did'], + acme['job_certificate_schema'], + job_certificate_cred_def['tag'], + job_certificate_cred_def['type'], + json.dumps(job_certificate_cred_def['config'])) + + logger.info("\"Acme\" -> Send \"Acme Job-Certificate\" Credential Definition to Ledger") + await send_cred_def(acme['pool'], acme['wallet'], acme['did'], acme['job_certificate_cred_def']) + + logger.info("\"Acme\" -> Creates Revocation Registry") + acme['tails_writer_config'] = json.dumps({'base_dir': "/tmp/indy_acme_tails", 'uri_pattern': ''}) + tails_writer = await blob_storage.open_writer('default', acme['tails_writer_config']) + acme['revoc_reg_id'] = None + #(acme['revoc_reg_id'], acme['revoc_reg_def'], acme['revoc_reg_entry']) = \ + # await anoncreds.issuer_create_and_store_revoc_reg(acme['wallet'], acme['did'], 'CL_ACCUM', 'TAG1', + # acme['job_certificate_cred_def_id'], + # json.dumps({'max_cred_num': 5, + # 'issuance_type': 'ISSUANCE_ON_DEMAND'}), + # tails_writer) + + #logger.info("\"Acme\" -> Post Revocation Registry Definition to Ledger") + #acme['revoc_reg_def_request'] = await ledger.build_revoc_reg_def_request(acme['did'], acme['revoc_reg_def']) + #await ledger.sign_and_submit_request(acme['pool'], acme['wallet'], acme['did'], acme['revoc_reg_def_request']) + + #logger.info("\"Acme\" -> Post Revocation Registry Entry to Ledger") + #acme['revoc_reg_entry_request'] = \ + # await ledger.build_revoc_reg_entry_request(acme['did'], acme['revoc_reg_id'], 'CL_ACCUM', + # acme['revoc_reg_entry']) + #await ledger.sign_and_submit_request(acme['pool'], acme['wallet'], acme['did'], acme['revoc_reg_entry_request']) + + + logger.info("==============================") + logger.info("== Alice setup ==") + logger.info("------------------------------") + + alice = { + 'name': 'Alice', + 'wallet_config': json.dumps({'id': 'alice_wallet'}), + 'wallet_credentials': json.dumps({'key': 'alice_wallet_key'}), + 'pool': pool_['handle'], + } + await create_wallet(alice) + (alice['did'], alice['key']) = await did.create_and_store_my_did(alice['wallet'], "{}") + + logger.info("\"Alice\" -> Create and store \"Alice\" Master Secret in Wallet") + alice['master_secret_id'] = await anoncreds.prover_create_master_secret(alice['wallet'], None) + + + logger.info("==============================") + logger.info("== Apply for the job with Acme - Getting Job-Certificate Credential ==") + logger.info("------------------------------") + + logger.info("\"Acme\" -> Create \"Job-Certificate\" Credential Offer for Alice") + acme['job_certificate_cred_offer'] = \ + await anoncreds.issuer_create_credential_offer(acme['wallet'], acme['job_certificate_cred_def_id']) + + logger.info("\"Acme\" -> Send \"Job-Certificate\" Credential Offer to Alice") + alice['job_certificate_cred_offer'] = acme['job_certificate_cred_offer'] + + job_certificate_cred_offer_object = json.loads(alice['job_certificate_cred_offer']) + + logger.info("\"Alice\" -> Get \"Acme Job-Certificate\" Credential Definition from Ledger") + (alice['acme_job_certificate_cred_def_id'], alice['acme_job_certificate_cred_def']) = \ + await get_cred_def(alice['pool'], alice['did'], job_certificate_cred_offer_object['cred_def_id']) + + logger.info("\"Alice\" -> Create and store in Wallet \"Job-Certificate\" Credential Request for Acme") + (alice['job_certificate_cred_request'], alice['job_certificate_cred_request_metadata']) = \ + await anoncreds.prover_create_credential_req(alice['wallet'], alice['did'], + alice['job_certificate_cred_offer'], + alice['acme_job_certificate_cred_def'], alice['master_secret_id']) + + logger.info("\"Alice\" -> Send \"Job-Certificate\" Credential Request to Acme") + alice['job_certificate_cred_values'] = json.dumps({ + "first_name": {"raw": "Alice", "encoded": "245712572474217942457235975012103335"}, + "last_name": {"raw": "Garcia", "encoded": "312643218496194691632153761283356127"}, + "employee_status": {"raw": "Permanent", "encoded": "2143135425425143112321314321"}, + "salary": {"raw": "2400", "encoded": "2400"}, + "experience": {"raw": "10", "encoded": "10"} + }) + acme['job_certificate_cred_request'] = alice['job_certificate_cred_request'] + acme['job_certificate_cred_values'] = alice['job_certificate_cred_values'] + + logger.info("\"Acme\" -> Create \"Job-Certificate\" Credential for Alice") + acme['blob_storage_reader_cfg_handle'] = await blob_storage.open_reader('default', acme['tails_writer_config']) + acme['job_certificate_cred'], acme['job_certificate_cred_rev_id'], acme['alice_cert_rev_reg_delta'] = \ + await anoncreds.issuer_create_credential(acme['wallet'], acme['job_certificate_cred_offer'], + acme['job_certificate_cred_request'], + acme['job_certificate_cred_values'], + acme['revoc_reg_id'], + acme['blob_storage_reader_cfg_handle']) + + #logger.info("\"Acme\" -> Post Revocation Registry Delta to Ledger") + #acme['revoc_reg_entry_req'] = \ + # await ledger.build_revoc_reg_entry_request(acme['did'], acme['revoc_reg_id'], 'CL_ACCUM', + # acme['alice_cert_rev_reg_delta']) + #await ledger.sign_and_submit_request(acme['pool'], acme['wallet'], acme['did'], acme['revoc_reg_entry_req']) + + logger.info("\"Acme\" -> Send \"Job-Certificate\" Credential to Alice") + alice['job_certificate_cred'] = acme['job_certificate_cred'] + job_certificate_cred_object = json.loads(alice['job_certificate_cred']) + + #logger.info("\"Alice\" -> Gets RevocationRegistryDefinition for \"Job-Certificate\" Credential from Acme") + #alice['acme_revoc_reg_des_req'] = \ + # await ledger.build_get_revoc_reg_def_request(alice['did'], + # job_certificate_cred_object['rev_reg_id']) + #alice['acme_revoc_reg_des_resp'] = \ + # await ensure_previous_request_applied(alice['pool'], alice['acme_revoc_reg_des_req'], + # lambda response: response['result']['data'] is not None) + #(alice['acme_revoc_reg_def_id'], alice['acme_revoc_reg_def_json']) = \ + # await ledger.parse_get_revoc_reg_def_response(alice['acme_revoc_reg_des_resp']) + alice['acme_revoc_reg_def_json'] = None + + logger.info("\"Alice\" -> Store \"Job-Certificate\" Credential") + await anoncreds.prover_store_credential(alice['wallet'], None, alice['job_certificate_cred_request_metadata'], + alice['job_certificate_cred'], + alice['acme_job_certificate_cred_def'], alice['acme_revoc_reg_def_json']) + + logger.info("Creating Credential in Getting started -> done") + + logger.info("==============================") + logger.info("=== Apply for the loan with Thrift ==") + logger.info("==============================") + + async def apply_loan_basic(): + # This method will be called twice: once with a valid Job-Certificate and + # the second time after the Job-Certificate has been revoked. + logger.info("==============================") + logger.info("== Apply for the loan with Thrift - Job-Certificate proving ==") + logger.info("------------------------------") + + #logger.info("\"Thrift\" -> Create \"Loan-Application-Basic\" Proof Request") + logger.info("\"Alice\" -> Create \"Loan-Application-Basic\" Proof Request") + nonce = await anoncreds.generate_nonce() + #thrift['apply_loan_proof_request'] = json.dumps({ + alice['apply_loan_proof_request'] = json.dumps({ + 'nonce': nonce, + 'name': 'Loan-Application-Basic', + 'version': '0.1', + 'requested_attributes': { + 'attr1_referent': { + 'name': 'employee_status', + 'restrictions': [{'cred_def_id': acme['job_certificate_cred_def_id']}] + } + }, + 'requested_predicates': { + 'predicate1_referent': { + 'name': 'salary', + 'p_type': '>=', + 'p_value': 2000, + 'restrictions': [{'cred_def_id': acme['job_certificate_cred_def_id']}] + }, + 'predicate2_referent': { + 'name': 'experience', + 'p_type': '>=', + 'p_value': 1, + 'restrictions': [{'cred_def_id': acme['job_certificate_cred_def_id']}] + } + }#, + # 'non_revoked': {'to': int(time.time())} + }) + + #logger.info("\"Thrift\" -> Send \"Loan-Application-Basic\" Proof Request to Alice") + #alice['apply_loan_proof_request'] = thrift_apply_loan_proof_request + logger.info("Creating Proof Request in Getting started -> done") + + logger.info("\"Alice\" -> Get credentials for \"Loan-Application-Basic\" Proof Request") + + search_for_apply_loan_proof_request = \ + await anoncreds.prover_search_credentials_for_proof_req(alice['wallet'], + alice['apply_loan_proof_request'], None) + + cred_for_attr1 = await get_credential_for_referent(search_for_apply_loan_proof_request, 'attr1_referent') + cred_for_predicate1 = await get_credential_for_referent(search_for_apply_loan_proof_request, + 'predicate1_referent') + cred_for_predicate2 = await get_credential_for_referent(search_for_apply_loan_proof_request, + 'predicate2_referent') + + await anoncreds.prover_close_credentials_search_for_proof_req(search_for_apply_loan_proof_request) + + alice['creds_for_apply_loan_proof'] = {cred_for_attr1['referent']: cred_for_attr1, + cred_for_predicate1['referent']: cred_for_predicate1, + cred_for_predicate2['referent']: cred_for_predicate2} + + # requested_timestamp = int(json.loads(alice['apply_loan_proof_request'])['non_revoked']['to']) + requested_timestamp = None + alice['schemas_for_loan_app'], alice['cred_defs_for_loan_app'], alice['revoc_states_for_loan_app'] = \ + await prover_get_entities_from_ledger(alice['pool'], alice['did'], + alice['creds_for_apply_loan_proof'], + alice['name'], None, requested_timestamp) + + logger.info("\"Alice\" -> Create \"Loan-Application-Basic\" Proof") + revoc_states_for_loan_app = json.loads(alice['revoc_states_for_loan_app']) + timestamp_for_attr1 = get_timestamp_for_attribute(cred_for_attr1, revoc_states_for_loan_app) + timestamp_for_predicate1 = get_timestamp_for_attribute(cred_for_predicate1, revoc_states_for_loan_app) + timestamp_for_predicate2 = get_timestamp_for_attribute(cred_for_predicate2, revoc_states_for_loan_app) + alice['apply_loan_requested_creds'] = json.dumps({ + 'self_attested_attributes': {}, + 'requested_attributes': { + 'attr1_referent': {'cred_id': cred_for_attr1['referent'], 'revealed': True, + 'timestamp': timestamp_for_attr1} + }, + 'requested_predicates': { + 'predicate1_referent': {'cred_id': cred_for_predicate1['referent'], + 'timestamp': timestamp_for_predicate1}, + 'predicate2_referent': {'cred_id': cred_for_predicate2['referent'], + 'timestamp': timestamp_for_predicate2} + } + }) + alice['apply_loan_proof'] = \ + await anoncreds.prover_create_proof(alice['wallet'], alice['apply_loan_proof_request'], + alice['apply_loan_requested_creds'], alice['master_secret_id'], + alice['schemas_for_loan_app'], alice['cred_defs_for_loan_app'], + alice['revoc_states_for_loan_app']) + + logger.info("Creating Proof in Getting started -> done") + + logger.info("\"Alice\" -> Send \"Loan-Application-Basic\" Proof to Thrift") + logger.info(json.dumps(alice['apply_loan_proof'])) + # logger.info("USER_PROOF_REQUEST: " + json.dumps(alice['apply_loan_proof_request'])) + # logger.info("USER_PROOF: " + json.dumps(alice['apply_loan_proof'])) + # logger.info('{ "proof_request": ' + json.dumps(alice['apply_loan_proof_request']) + ', "proof": ' + json.dumps(alice['apply_loan_proof']) + ' }') + + # request_str = '{ "proof_request": ' + json.dumps(alice['apply_loan_proof_request']) + ', "proof": ' + json.dumps(alice['apply_loan_proof']) + ' }' + # logger.info(request_str) + + ##request_json = { "proof_request": json.dumps(alice['apply_loan_proof_request']), "proof": json.dumps(alice['apply_loan_proof'])} + request_json = { "proof_request": alice['apply_loan_proof_request'], "proof": alice['apply_loan_proof']} + logger.info(json.dumps(request_json)) + + # create_user_proof_file(file_name, json.dumps(request_str)) + create_user_proof_file(file_name, json.dumps(request_json)) + + await apply_loan_basic() + + request_discounted_cartrade(file_name) + + +def wallet_config(operation, wallet_config_str): + if not args.storage_type: + return wallet_config_str + wallet_config_json = json.loads(wallet_config_str) + wallet_config_json['storage_type'] = args.storage_type + if args.config: + wallet_config_json['storage_config'] = json.loads(args.config) + # print(operation, json.dumps(wallet_config_json)) + return json.dumps(wallet_config_json) + + +def wallet_credentials(operation, wallet_credentials_str): + if not args.storage_type: + return wallet_credentials_str + wallet_credentials_json = json.loads(wallet_credentials_str) + if args.creds: + wallet_credentials_json['storage_credentials'] = json.loads(args.creds) + # print(operation, json.dumps(wallet_credentials_json)) + return json.dumps(wallet_credentials_json) + + +async def create_wallet(identity): + logger.info("\"{}\" -> Create wallet".format(identity['name'])) + try: + await wallet.create_wallet(wallet_config("create", identity['wallet_config']), + wallet_credentials("create", identity['wallet_credentials'])) + except IndyError as ex: + if ex.error_code == ErrorCode.PoolLedgerConfigAlreadyExistsError: + pass + identity['wallet'] = await wallet.open_wallet(wallet_config("open", identity['wallet_config']), + wallet_credentials("open", identity['wallet_credentials'])) + + +async def getting_verinym(from_, to): + await create_wallet(to) + + (to['did'], to['key']) = await did.create_and_store_my_did(to['wallet'], "{}") + + from_['info'] = { + 'did': to['did'], + 'verkey': to['key'], + 'role': to['role'] or None + } + + await send_nym(from_['pool'], from_['wallet'], from_['did'], from_['info']['did'], + from_['info']['verkey'], from_['info']['role']) + + +async def send_nym(pool_handle, wallet_handle, _did, new_did, new_key, role): + nym_request = await ledger.build_nym_request(_did, new_did, new_key, None, role) + await ledger.sign_and_submit_request(pool_handle, wallet_handle, _did, nym_request) + + +async def send_schema(pool_handle, wallet_handle, _did, schema): + schema_request = await ledger.build_schema_request(_did, schema) + await ledger.sign_and_submit_request(pool_handle, wallet_handle, _did, schema_request) + + +async def send_cred_def(pool_handle, wallet_handle, _did, cred_def_json): + cred_def_request = await ledger.build_cred_def_request(_did, cred_def_json) + await ledger.sign_and_submit_request(pool_handle, wallet_handle, _did, cred_def_request) + + +async def get_schema(pool_handle, _did, schema_id): + get_schema_request = await ledger.build_get_schema_request(_did, schema_id) + get_schema_response = await ensure_previous_request_applied( + pool_handle, get_schema_request, lambda response: response['result']['data'] is not None) + return await ledger.parse_get_schema_response(get_schema_response) + + +async def get_cred_def(pool_handle, _did, cred_def_id): + get_cred_def_request = await ledger.build_get_cred_def_request(_did, cred_def_id) + get_cred_def_response = \ + await ensure_previous_request_applied(pool_handle, get_cred_def_request, + lambda response: response['result']['data'] is not None) + return await ledger.parse_get_cred_def_response(get_cred_def_response) + + +async def get_credential_for_referent(search_handle, referent): + credentials = json.loads( + await anoncreds.prover_fetch_credentials_for_proof_req(search_handle, referent, 10)) + return credentials[0]['cred_info'] + + +def get_timestamp_for_attribute(cred_for_attribute, revoc_states): + if cred_for_attribute['rev_reg_id'] in revoc_states: + return int(next(iter(revoc_states[cred_for_attribute['rev_reg_id']]))) + else: + return None + + +async def prover_get_entities_from_ledger(pool_handle, _did, identifiers, actor, timestamp_from=None, + timestamp_to=None): + schemas = {} + cred_defs = {} + rev_states = {} + for item in identifiers.values(): + logger.info("\"{}\" -> Get Schema from Ledger".format(actor)) + (received_schema_id, received_schema) = await get_schema(pool_handle, _did, item['schema_id']) + schemas[received_schema_id] = json.loads(received_schema) + + logger.info("\"{}\" -> Get Claim Definition from Ledger".format(actor)) + (received_cred_def_id, received_cred_def) = await get_cred_def(pool_handle, _did, item['cred_def_id']) + cred_defs[received_cred_def_id] = json.loads(received_cred_def) + + if 'rev_reg_id' in item and item['rev_reg_id'] is not None: + # Create Revocations States + logger.info("\"{}\" -> Get Revocation Registry Definition from Ledger".format(actor)) + get_revoc_reg_def_request = await ledger.build_get_revoc_reg_def_request(_did, item['rev_reg_id']) + + get_revoc_reg_def_response = \ + await ensure_previous_request_applied(pool_handle, get_revoc_reg_def_request, + lambda response: response['result']['data'] is not None) + (rev_reg_id, revoc_reg_def_json) = await ledger.parse_get_revoc_reg_def_response(get_revoc_reg_def_response) + + logger.info("\"{}\" -> Get Revocation Registry Delta from Ledger".format(actor)) + if not timestamp_to: timestamp_to = int(time.time()) + get_revoc_reg_delta_request = \ + await ledger.build_get_revoc_reg_delta_request(_did, item['rev_reg_id'], timestamp_from, timestamp_to) + get_revoc_reg_delta_response = \ + await ensure_previous_request_applied(pool_handle, get_revoc_reg_delta_request, + lambda response: response['result']['data'] is not None) + (rev_reg_id, revoc_reg_delta_json, t) = \ + await ledger.parse_get_revoc_reg_delta_response(get_revoc_reg_delta_response) + + tails_reader_config = json.dumps( + {'base_dir': dirname(json.loads(revoc_reg_def_json)['value']['tailsLocation']), + 'uri_pattern': ''}) + blob_storage_reader_cfg_handle = await blob_storage.open_reader('default', tails_reader_config) + + logger.info('%s - Create Revocation State', actor) + rev_state_json = \ + await anoncreds.create_revocation_state(blob_storage_reader_cfg_handle, revoc_reg_def_json, + revoc_reg_delta_json, t, item['cred_rev_id']) + rev_states[rev_reg_id] = {t: json.loads(rev_state_json)} + + return json.dumps(schemas), json.dumps(cred_defs), json.dumps(rev_states) + + +async def verifier_get_entities_from_ledger(pool_handle, _did, identifiers, actor, timestamp=None): + schemas = {} + cred_defs = {} + rev_reg_defs = {} + rev_regs = {} + for item in identifiers: + logger.info("\"{}\" -> Get Schema from Ledger".format(actor)) + (received_schema_id, received_schema) = await get_schema(pool_handle, _did, item['schema_id']) + schemas[received_schema_id] = json.loads(received_schema) + + logger.info("\"{}\" -> Get Claim Definition from Ledger".format(actor)) + (received_cred_def_id, received_cred_def) = await get_cred_def(pool_handle, _did, item['cred_def_id']) + cred_defs[received_cred_def_id] = json.loads(received_cred_def) + + if 'rev_reg_id' in item and item['rev_reg_id'] is not None: + # Get Revocation Definitions and Revocation Registries + logger.info("\"{}\" -> Get Revocation Definition from Ledger".format(actor)) + get_revoc_reg_def_request = await ledger.build_get_revoc_reg_def_request(_did, item['rev_reg_id']) + + get_revoc_reg_def_response = \ + await ensure_previous_request_applied(pool_handle, get_revoc_reg_def_request, + lambda response: response['result']['data'] is not None) + (rev_reg_id, revoc_reg_def_json) = await ledger.parse_get_revoc_reg_def_response(get_revoc_reg_def_response) + + logger.info("\"{}\" -> Get Revocation Registry from Ledger".format(actor)) + if not timestamp: timestamp = item['timestamp'] + get_revoc_reg_request = \ + await ledger.build_get_revoc_reg_request(_did, item['rev_reg_id'], timestamp) + get_revoc_reg_response = \ + await ensure_previous_request_applied(pool_handle, get_revoc_reg_request, + lambda response: response['result']['data'] is not None) + (rev_reg_id, rev_reg_json, timestamp2) = await ledger.parse_get_revoc_reg_response(get_revoc_reg_response) + + rev_regs[rev_reg_id] = {timestamp2: json.loads(rev_reg_json)} + rev_reg_defs[rev_reg_id] = json.loads(revoc_reg_def_json) + + return json.dumps(schemas), json.dumps(cred_defs), json.dumps(rev_reg_defs), json.dumps(rev_regs) + +def create_user_proof_file(json_file, user_proof): + logger.info(f"called create_user_proof_file()") + with open(json_file, 'w') as file: + file.write(user_proof) + +def request_discounted_cartrade(json_file): + # read json file + json_str = "" + with open(json_file, 'r') as file: + data = json.load(file) + json_str = json.dumps(data) + + # append data of json file to http req param + http_req_params["tradeParams"].append(json_str) + + # logger.info(f"http_params: url: {http_req_params['url']}") + # logger.info(f"http_params: businessLogicID: {http_req_params['businessLogicID']}") + # logger.info(f"http_params: tradeParams: {http_req_params['tradeParams']}") + # logger.info(f"http_params: authParams: {http_req_params['authParams']}") + + logger.info(f"http_params") + + req_url = http_req_params["url"] + req_header = {'Content-Type': 'application/json'} + req_body = {'businessLogicID': http_req_params["businessLogicID"], + 'tradeParams': http_req_params["tradeParams"], + 'authParams': http_req_params["authParams"]} + + logger.info(f"req_body: {req_body}") + + + # response = requests.post( + # http_req_params["url"], + # json.dumps({'businessLogicID': http_req_params["businessLogicID"], + # 'tradeParams': http_req_params["tradeParams"], + # 'authParams': http_req_params["authParams"]}), + # headers={'Content-Type': 'application/json'}) + + # send request + response = requests.post(req_url, headers=req_header, data=json.dumps(req_body)) + logger.info("return requests.post()") + logger.info("http_params: authParams: {}".format(http_req_params["authParams"])) + print(f"return requests.post()") + print(f"resp: {response}") + print(f"resp.text: {response.text}") + print(f"##----") + +if __name__ == '__main__': + run_coroutine(run) + time.sleep(1) # FIXME waiting for libindy thread complete diff --git a/examples/register-indy-data/sample_Userside.py b/examples/register-indy-data/sample_Userside.py deleted file mode 100644 index a3d41b36fe..0000000000 --- a/examples/register-indy-data/sample_Userside.py +++ /dev/null @@ -1,586 +0,0 @@ -import time - -from indy import anoncreds, did, ledger, pool, wallet, blob_storage - -import json -import logging - -import argparse -import sys -from ctypes import * -from os.path import dirname - -from indy.error import ErrorCode, IndyError - -from src.utils import get_pool_genesis_txn_path, run_coroutine, PROTOCOL_VERSION, ensure_previous_request_applied - -#use Requests -import requests - - -logger = logging.getLogger(__name__) -logging.basicConfig(level=logging.INFO) - -#parser = argparse.ArgumentParser(description='Run python getting-started scenario (Alice/Faber)') -parser = argparse.ArgumentParser(description='Run python getting-started scenario (Alice/Acme/Thrift)') -parser.add_argument('-t', '--storage_type', help='load custom wallet storage plug-in') -parser.add_argument('-l', '--library', help='dynamic library to load for plug-in') -parser.add_argument('-e', '--entrypoint', help='entry point for dynamic library') -parser.add_argument('-c', '--config', help='entry point for dynamic library') -parser.add_argument('-s', '--creds', help='entry point for dynamic library') - -args = parser.parse_args() - -# check if we need to dyna-load a custom wallet storage plug-in -if args.storage_type: - if not (args.library and args.entrypoint): - parser.print_help() - sys.exit(0) - stg_lib = CDLL(args.library) - result = stg_lib[args.entrypoint]() - if result != 0: - print("Error unable to load wallet storage", result) - parser.print_help() - sys.exit(0) - - # for postgres storage, also call the storage init (non-standard) - if args.storage_type == "postgres_storage": - try: - print("Calling init_storagetype() for postgres:", args.config, args.creds) - init_storagetype = stg_lib["init_storagetype"] - c_config = c_char_p(args.config.encode('utf-8')) - c_credentials = c_char_p(args.creds.encode('utf-8')) - result = init_storagetype(c_config, c_credentials) - print(" ... returns ", result) - except RuntimeError as e: - print("Error initializing storage, ignoring ...", e) - - print("Success, loaded wallet storage", args.storage_type) - - -async def run(): - logger.info("Getting started -> started") - - pool_ = { - 'name': 'pool1' - } - logger.info("Open Pool Ledger: {}".format(pool_['name'])) - pool_['genesis_txn_path'] = get_pool_genesis_txn_path(pool_['name']) - pool_['config'] = json.dumps({"genesis_txn": str(pool_['genesis_txn_path'])}) - - # Set protocol version 2 to work with Indy Node 1.4 - await pool.set_protocol_version(PROTOCOL_VERSION) - - try: - await pool.create_pool_ledger_config(pool_['name'], pool_['config']) - except IndyError as ex: - if ex.error_code == ErrorCode.PoolLedgerConfigAlreadyExistsError: - pass - pool_['handle'] = await pool.open_pool_ledger(pool_['name'], None) - - logger.info("==============================") - #logger.info("=== Getting Trust Anchor credentials for Faber, Acme, Thrift and Government ==") - logger.info("=== Getting Trust Anchor credentials for Acme ==") - logger.info("------------------------------") - - steward = { - 'name': "Sovrin Steward", - 'wallet_config': json.dumps({'id': 'sovrin_steward_wallet'}), - 'wallet_credentials': json.dumps({'key': 'steward_wallet_key'}), - 'pool': pool_['handle'], - 'seed': '000000000000000000000000Steward1' - } - - await create_wallet(steward) - - logger.info("\"Sovrin Steward\" -> Create and store in Wallet DID from seed") - steward['did_info'] = json.dumps({'seed': steward['seed']}) - steward['did'], steward['key'] = await did.create_and_store_my_did(steward['wallet'], steward['did_info']) - - logger.info("==============================") - logger.info("== Getting Trust Anchor credentials - Government getting Verinym ==") - logger.info("------------------------------") - - government = { - 'name': 'Government', - 'wallet_config': json.dumps({'id': 'government_wallet'}), - 'wallet_credentials': json.dumps({'key': 'government_wallet_key'}), - 'pool': pool_['handle'], - 'role': 'TRUST_ANCHOR' - } - - await getting_verinym(steward, government) - - logger.info("==============================") - logger.info("== Getting Trust Anchor credentials - Acme getting Verinym ==") - logger.info("------------------------------") - - acme = { - 'name': 'Acme', - 'wallet_config': json.dumps({'id': 'acme_wallet'}), - 'wallet_credentials': json.dumps({'key': 'acme_wallet_key'}), - 'pool': pool_['handle'], - 'role': 'TRUST_ANCHOR' - } - - await getting_verinym(steward, acme) - - logger.info("==============================") - logger.info("== Getting Trust Anchor credentials - Thrift getting Verinym ==") - logger.info("------------------------------") - - thrift = { - 'name': 'Thrift', - 'wallet_config': json.dumps({'id': 'thrift_wallet'}), - 'wallet_credentials': json.dumps({'key': 'thrift_wallet_key'}), - 'pool': pool_['handle'], - 'role': 'TRUST_ANCHOR' - } - - await getting_verinym(steward, thrift) - - logger.info("==============================") - logger.info("=== Credential Schemas Setup ==") - logger.info("------------------------------") - - logger.info("\"Government\" -> Create \"Job-Certificate\" Schema") - job_certificate = { - 'name': 'Job-Certificate', - 'version': '0.2', - 'attributes': ['first_name', 'last_name', 'salary', 'employee_status', 'experience'] - } - (government['job_certificate_schema_id'], government['job_certificate_schema']) = \ - await anoncreds.issuer_create_schema(government['did'], job_certificate['name'], job_certificate['version'], - json.dumps(job_certificate['attributes'])) - job_certificate_schema_id = government['job_certificate_schema_id'] - - logger.info("\"Government\" -> Send \"Job-Certificate\" Schema to Ledger") - await send_schema(government['pool'], government['wallet'], government['did'], government['job_certificate_schema']) - - - time.sleep(1) # sleep 1 second before getting schema - - - logger.info("==============================") - logger.info("=== Acme Credential Definition Setup ==") - logger.info("------------------------------") - - logger.info("\"Acme\" -> Get from Ledger \"Job-Certificate\" Schema") - (acme['job_certificate_schema_id'], acme['job_certificate_schema']) = \ - await get_schema(acme['pool'], acme['did'], job_certificate_schema_id) - - logger.info("\"Acme\" -> Create and store in Wallet \"Acme Job-Certificate\" Credential Definition") - job_certificate_cred_def = { - 'tag': 'TAG1', - 'type': 'CL', - 'config': {"support_revocation": False} - } - (acme['job_certificate_cred_def_id'], acme['job_certificate_cred_def']) = \ - await anoncreds.issuer_create_and_store_credential_def(acme['wallet'], acme['did'], - acme['job_certificate_schema'], - job_certificate_cred_def['tag'], - job_certificate_cred_def['type'], - json.dumps(job_certificate_cred_def['config'])) - - logger.info("\"Acme\" -> Send \"Acme Job-Certificate\" Credential Definition to Ledger") - await send_cred_def(acme['pool'], acme['wallet'], acme['did'], acme['job_certificate_cred_def']) - - logger.info("\"Acme\" -> Creates Revocation Registry") - acme['tails_writer_config'] = json.dumps({'base_dir': "/tmp/indy_acme_tails", 'uri_pattern': ''}) - tails_writer = await blob_storage.open_writer('default', acme['tails_writer_config']) - acme['revoc_reg_id'] = None - #(acme['revoc_reg_id'], acme['revoc_reg_def'], acme['revoc_reg_entry']) = \ - # await anoncreds.issuer_create_and_store_revoc_reg(acme['wallet'], acme['did'], 'CL_ACCUM', 'TAG1', - # acme['job_certificate_cred_def_id'], - # json.dumps({'max_cred_num': 5, - # 'issuance_type': 'ISSUANCE_ON_DEMAND'}), - # tails_writer) - - #logger.info("\"Acme\" -> Post Revocation Registry Definition to Ledger") - #acme['revoc_reg_def_request'] = await ledger.build_revoc_reg_def_request(acme['did'], acme['revoc_reg_def']) - #await ledger.sign_and_submit_request(acme['pool'], acme['wallet'], acme['did'], acme['revoc_reg_def_request']) - - #logger.info("\"Acme\" -> Post Revocation Registry Entry to Ledger") - #acme['revoc_reg_entry_request'] = \ - # await ledger.build_revoc_reg_entry_request(acme['did'], acme['revoc_reg_id'], 'CL_ACCUM', - # acme['revoc_reg_entry']) - #await ledger.sign_and_submit_request(acme['pool'], acme['wallet'], acme['did'], acme['revoc_reg_entry_request']) - - - logger.info("==============================") - logger.info("== Alice setup ==") - logger.info("------------------------------") - - alice = { - 'name': 'Alice', - 'wallet_config': json.dumps({'id': 'alice_wallet'}), - 'wallet_credentials': json.dumps({'key': 'alice_wallet_key'}), - 'pool': pool_['handle'], - } - await create_wallet(alice) - (alice['did'], alice['key']) = await did.create_and_store_my_did(alice['wallet'], "{}") - - logger.info("\"Alice\" -> Create and store \"Alice\" Master Secret in Wallet") - alice['master_secret_id'] = await anoncreds.prover_create_master_secret(alice['wallet'], None) - - - logger.info("==============================") - logger.info("== Apply for the job with Acme - Getting Job-Certificate Credential ==") - logger.info("------------------------------") - - logger.info("\"Acme\" -> Create \"Job-Certificate\" Credential Offer for Alice") - acme['job_certificate_cred_offer'] = \ - await anoncreds.issuer_create_credential_offer(acme['wallet'], acme['job_certificate_cred_def_id']) - - logger.info("\"Acme\" -> Send \"Job-Certificate\" Credential Offer to Alice") - alice['job_certificate_cred_offer'] = acme['job_certificate_cred_offer'] - - job_certificate_cred_offer_object = json.loads(alice['job_certificate_cred_offer']) - - logger.info("\"Alice\" -> Get \"Acme Job-Certificate\" Credential Definition from Ledger") - (alice['acme_job_certificate_cred_def_id'], alice['acme_job_certificate_cred_def']) = \ - await get_cred_def(alice['pool'], alice['did'], job_certificate_cred_offer_object['cred_def_id']) - - logger.info("\"Alice\" -> Create and store in Wallet \"Job-Certificate\" Credential Request for Acme") - (alice['job_certificate_cred_request'], alice['job_certificate_cred_request_metadata']) = \ - await anoncreds.prover_create_credential_req(alice['wallet'], alice['did'], - alice['job_certificate_cred_offer'], - alice['acme_job_certificate_cred_def'], alice['master_secret_id']) - - logger.info("\"Alice\" -> Send \"Job-Certificate\" Credential Request to Acme") - alice['job_certificate_cred_values'] = json.dumps({ - "first_name": {"raw": "Alice", "encoded": "245712572474217942457235975012103335"}, - "last_name": {"raw": "Garcia", "encoded": "312643218496194691632153761283356127"}, - "employee_status": {"raw": "Permanent", "encoded": "2143135425425143112321314321"}, - "salary": {"raw": "2400", "encoded": "2400"}, - "experience": {"raw": "10", "encoded": "10"} - }) - acme['job_certificate_cred_request'] = alice['job_certificate_cred_request'] - acme['job_certificate_cred_values'] = alice['job_certificate_cred_values'] - - logger.info("\"Acme\" -> Create \"Job-Certificate\" Credential for Alice") - acme['blob_storage_reader_cfg_handle'] = await blob_storage.open_reader('default', acme['tails_writer_config']) - acme['job_certificate_cred'], acme['job_certificate_cred_rev_id'], acme['alice_cert_rev_reg_delta'] = \ - await anoncreds.issuer_create_credential(acme['wallet'], acme['job_certificate_cred_offer'], - acme['job_certificate_cred_request'], - acme['job_certificate_cred_values'], - acme['revoc_reg_id'], - acme['blob_storage_reader_cfg_handle']) - - #logger.info("\"Acme\" -> Post Revocation Registry Delta to Ledger") - #acme['revoc_reg_entry_req'] = \ - # await ledger.build_revoc_reg_entry_request(acme['did'], acme['revoc_reg_id'], 'CL_ACCUM', - # acme['alice_cert_rev_reg_delta']) - #await ledger.sign_and_submit_request(acme['pool'], acme['wallet'], acme['did'], acme['revoc_reg_entry_req']) - - logger.info("\"Acme\" -> Send \"Job-Certificate\" Credential to Alice") - alice['job_certificate_cred'] = acme['job_certificate_cred'] - job_certificate_cred_object = json.loads(alice['job_certificate_cred']) - - #logger.info("\"Alice\" -> Gets RevocationRegistryDefinition for \"Job-Certificate\" Credential from Acme") - #alice['acme_revoc_reg_des_req'] = \ - # await ledger.build_get_revoc_reg_def_request(alice['did'], - # job_certificate_cred_object['rev_reg_id']) - #alice['acme_revoc_reg_des_resp'] = \ - # await ensure_previous_request_applied(alice['pool'], alice['acme_revoc_reg_des_req'], - # lambda response: response['result']['data'] is not None) - #(alice['acme_revoc_reg_def_id'], alice['acme_revoc_reg_def_json']) = \ - # await ledger.parse_get_revoc_reg_def_response(alice['acme_revoc_reg_des_resp']) - alice['acme_revoc_reg_def_json'] = None - - logger.info("\"Alice\" -> Store \"Job-Certificate\" Credential") - await anoncreds.prover_store_credential(alice['wallet'], None, alice['job_certificate_cred_request_metadata'], - alice['job_certificate_cred'], - alice['acme_job_certificate_cred_def'], alice['acme_revoc_reg_def_json']) - - logger.info("Creating Credential in Getting started -> done") - - logger.info("==============================") - logger.info("=== Apply for the loan with Thrift ==") - logger.info("==============================") - - async def apply_loan_basic(): - # This method will be called twice: once with a valid Job-Certificate and - # the second time after the Job-Certificate has been revoked. - logger.info("==============================") - logger.info("== Apply for the loan with Thrift - Job-Certificate proving ==") - logger.info("------------------------------") - - #logger.info("\"Thrift\" -> Create \"Loan-Application-Basic\" Proof Request") - logger.info("\"Alice\" -> Create \"Loan-Application-Basic\" Proof Request") - nonce = await anoncreds.generate_nonce() - #thrift['apply_loan_proof_request'] = json.dumps({ - alice['apply_loan_proof_request'] = json.dumps({ - 'nonce': nonce, - 'name': 'Loan-Application-Basic', - 'version': '0.1', - 'requested_attributes': { - 'attr1_referent': { - 'name': 'employee_status', - 'restrictions': [{'cred_def_id': acme['job_certificate_cred_def_id']}] - } - }, - 'requested_predicates': { - 'predicate1_referent': { - 'name': 'salary', - 'p_type': '>=', - 'p_value': 2000, - 'restrictions': [{'cred_def_id': acme['job_certificate_cred_def_id']}] - }, - 'predicate2_referent': { - 'name': 'experience', - 'p_type': '>=', - 'p_value': 1, - 'restrictions': [{'cred_def_id': acme['job_certificate_cred_def_id']}] - } - }#, - # 'non_revoked': {'to': int(time.time())} - }) - - #logger.info("\"Thrift\" -> Send \"Loan-Application-Basic\" Proof Request to Alice") - #alice['apply_loan_proof_request'] = thrift_apply_loan_proof_request - logger.info("Creating Proof Request in Getting started -> done") - - logger.info("\"Alice\" -> Get credentials for \"Loan-Application-Basic\" Proof Request") - - search_for_apply_loan_proof_request = \ - await anoncreds.prover_search_credentials_for_proof_req(alice['wallet'], - alice['apply_loan_proof_request'], None) - - cred_for_attr1 = await get_credential_for_referent(search_for_apply_loan_proof_request, 'attr1_referent') - cred_for_predicate1 = await get_credential_for_referent(search_for_apply_loan_proof_request, - 'predicate1_referent') - cred_for_predicate2 = await get_credential_for_referent(search_for_apply_loan_proof_request, - 'predicate2_referent') - - await anoncreds.prover_close_credentials_search_for_proof_req(search_for_apply_loan_proof_request) - - alice['creds_for_apply_loan_proof'] = {cred_for_attr1['referent']: cred_for_attr1, - cred_for_predicate1['referent']: cred_for_predicate1, - cred_for_predicate2['referent']: cred_for_predicate2} - - # requested_timestamp = int(json.loads(alice['apply_loan_proof_request'])['non_revoked']['to']) - requested_timestamp = None - alice['schemas_for_loan_app'], alice['cred_defs_for_loan_app'], alice['revoc_states_for_loan_app'] = \ - await prover_get_entities_from_ledger(alice['pool'], alice['did'], - alice['creds_for_apply_loan_proof'], - alice['name'], None, requested_timestamp) - - logger.info("\"Alice\" -> Create \"Loan-Application-Basic\" Proof") - revoc_states_for_loan_app = json.loads(alice['revoc_states_for_loan_app']) - timestamp_for_attr1 = get_timestamp_for_attribute(cred_for_attr1, revoc_states_for_loan_app) - timestamp_for_predicate1 = get_timestamp_for_attribute(cred_for_predicate1, revoc_states_for_loan_app) - timestamp_for_predicate2 = get_timestamp_for_attribute(cred_for_predicate2, revoc_states_for_loan_app) - alice['apply_loan_requested_creds'] = json.dumps({ - 'self_attested_attributes': {}, - 'requested_attributes': { - 'attr1_referent': {'cred_id': cred_for_attr1['referent'], 'revealed': True, - 'timestamp': timestamp_for_attr1} - }, - 'requested_predicates': { - 'predicate1_referent': {'cred_id': cred_for_predicate1['referent'], - 'timestamp': timestamp_for_predicate1}, - 'predicate2_referent': {'cred_id': cred_for_predicate2['referent'], - 'timestamp': timestamp_for_predicate2} - } - }) - alice['apply_loan_proof'] = \ - await anoncreds.prover_create_proof(alice['wallet'], alice['apply_loan_proof_request'], - alice['apply_loan_requested_creds'], alice['master_secret_id'], - alice['schemas_for_loan_app'], alice['cred_defs_for_loan_app'], - alice['revoc_states_for_loan_app']) - - logger.info("Creating Proof in Getting started -> done") - - logger.info("\"Alice\" -> Send \"Loan-Application-Basic\" Proof to Thrift") - logger.info(json.dumps(alice['apply_loan_proof'])) - # logger.info("USER_PROOF_REQUEST: " + json.dumps(alice['apply_loan_proof_request'])) - # logger.info("USER_PROOF: " + json.dumps(alice['apply_loan_proof'])) - logger.info('{ "proof_request": ' + json.dumps(alice['apply_loan_proof_request']) + ', "proof": ' + json.dumps(alice['apply_loan_proof']) + ' }') - - - - await apply_loan_basic() - - -def wallet_config(operation, wallet_config_str): - if not args.storage_type: - return wallet_config_str - wallet_config_json = json.loads(wallet_config_str) - wallet_config_json['storage_type'] = args.storage_type - if args.config: - wallet_config_json['storage_config'] = json.loads(args.config) - # print(operation, json.dumps(wallet_config_json)) - return json.dumps(wallet_config_json) - - -def wallet_credentials(operation, wallet_credentials_str): - if not args.storage_type: - return wallet_credentials_str - wallet_credentials_json = json.loads(wallet_credentials_str) - if args.creds: - wallet_credentials_json['storage_credentials'] = json.loads(args.creds) - # print(operation, json.dumps(wallet_credentials_json)) - return json.dumps(wallet_credentials_json) - - -async def create_wallet(identity): - logger.info("\"{}\" -> Create wallet".format(identity['name'])) - try: - await wallet.create_wallet(wallet_config("create", identity['wallet_config']), - wallet_credentials("create", identity['wallet_credentials'])) - except IndyError as ex: - if ex.error_code == ErrorCode.PoolLedgerConfigAlreadyExistsError: - pass - identity['wallet'] = await wallet.open_wallet(wallet_config("open", identity['wallet_config']), - wallet_credentials("open", identity['wallet_credentials'])) - - -async def getting_verinym(from_, to): - await create_wallet(to) - - (to['did'], to['key']) = await did.create_and_store_my_did(to['wallet'], "{}") - - from_['info'] = { - 'did': to['did'], - 'verkey': to['key'], - 'role': to['role'] or None - } - - await send_nym(from_['pool'], from_['wallet'], from_['did'], from_['info']['did'], - from_['info']['verkey'], from_['info']['role']) - - -async def send_nym(pool_handle, wallet_handle, _did, new_did, new_key, role): - nym_request = await ledger.build_nym_request(_did, new_did, new_key, None, role) - await ledger.sign_and_submit_request(pool_handle, wallet_handle, _did, nym_request) - - -async def send_schema(pool_handle, wallet_handle, _did, schema): - schema_request = await ledger.build_schema_request(_did, schema) - await ledger.sign_and_submit_request(pool_handle, wallet_handle, _did, schema_request) - - -async def send_cred_def(pool_handle, wallet_handle, _did, cred_def_json): - cred_def_request = await ledger.build_cred_def_request(_did, cred_def_json) - await ledger.sign_and_submit_request(pool_handle, wallet_handle, _did, cred_def_request) - - -async def get_schema(pool_handle, _did, schema_id): - get_schema_request = await ledger.build_get_schema_request(_did, schema_id) - get_schema_response = await ensure_previous_request_applied( - pool_handle, get_schema_request, lambda response: response['result']['data'] is not None) - return await ledger.parse_get_schema_response(get_schema_response) - - -async def get_cred_def(pool_handle, _did, cred_def_id): - get_cred_def_request = await ledger.build_get_cred_def_request(_did, cred_def_id) - get_cred_def_response = \ - await ensure_previous_request_applied(pool_handle, get_cred_def_request, - lambda response: response['result']['data'] is not None) - return await ledger.parse_get_cred_def_response(get_cred_def_response) - - -async def get_credential_for_referent(search_handle, referent): - credentials = json.loads( - await anoncreds.prover_fetch_credentials_for_proof_req(search_handle, referent, 10)) - return credentials[0]['cred_info'] - - -def get_timestamp_for_attribute(cred_for_attribute, revoc_states): - if cred_for_attribute['rev_reg_id'] in revoc_states: - return int(next(iter(revoc_states[cred_for_attribute['rev_reg_id']]))) - else: - return None - - -async def prover_get_entities_from_ledger(pool_handle, _did, identifiers, actor, timestamp_from=None, - timestamp_to=None): - schemas = {} - cred_defs = {} - rev_states = {} - for item in identifiers.values(): - logger.info("\"{}\" -> Get Schema from Ledger".format(actor)) - (received_schema_id, received_schema) = await get_schema(pool_handle, _did, item['schema_id']) - schemas[received_schema_id] = json.loads(received_schema) - - logger.info("\"{}\" -> Get Claim Definition from Ledger".format(actor)) - (received_cred_def_id, received_cred_def) = await get_cred_def(pool_handle, _did, item['cred_def_id']) - cred_defs[received_cred_def_id] = json.loads(received_cred_def) - - if 'rev_reg_id' in item and item['rev_reg_id'] is not None: - # Create Revocations States - logger.info("\"{}\" -> Get Revocation Registry Definition from Ledger".format(actor)) - get_revoc_reg_def_request = await ledger.build_get_revoc_reg_def_request(_did, item['rev_reg_id']) - - get_revoc_reg_def_response = \ - await ensure_previous_request_applied(pool_handle, get_revoc_reg_def_request, - lambda response: response['result']['data'] is not None) - (rev_reg_id, revoc_reg_def_json) = await ledger.parse_get_revoc_reg_def_response(get_revoc_reg_def_response) - - logger.info("\"{}\" -> Get Revocation Registry Delta from Ledger".format(actor)) - if not timestamp_to: timestamp_to = int(time.time()) - get_revoc_reg_delta_request = \ - await ledger.build_get_revoc_reg_delta_request(_did, item['rev_reg_id'], timestamp_from, timestamp_to) - get_revoc_reg_delta_response = \ - await ensure_previous_request_applied(pool_handle, get_revoc_reg_delta_request, - lambda response: response['result']['data'] is not None) - (rev_reg_id, revoc_reg_delta_json, t) = \ - await ledger.parse_get_revoc_reg_delta_response(get_revoc_reg_delta_response) - - tails_reader_config = json.dumps( - {'base_dir': dirname(json.loads(revoc_reg_def_json)['value']['tailsLocation']), - 'uri_pattern': ''}) - blob_storage_reader_cfg_handle = await blob_storage.open_reader('default', tails_reader_config) - - logger.info('%s - Create Revocation State', actor) - rev_state_json = \ - await anoncreds.create_revocation_state(blob_storage_reader_cfg_handle, revoc_reg_def_json, - revoc_reg_delta_json, t, item['cred_rev_id']) - rev_states[rev_reg_id] = {t: json.loads(rev_state_json)} - - return json.dumps(schemas), json.dumps(cred_defs), json.dumps(rev_states) - - -async def verifier_get_entities_from_ledger(pool_handle, _did, identifiers, actor, timestamp=None): - schemas = {} - cred_defs = {} - rev_reg_defs = {} - rev_regs = {} - for item in identifiers: - logger.info("\"{}\" -> Get Schema from Ledger".format(actor)) - (received_schema_id, received_schema) = await get_schema(pool_handle, _did, item['schema_id']) - schemas[received_schema_id] = json.loads(received_schema) - - logger.info("\"{}\" -> Get Claim Definition from Ledger".format(actor)) - (received_cred_def_id, received_cred_def) = await get_cred_def(pool_handle, _did, item['cred_def_id']) - cred_defs[received_cred_def_id] = json.loads(received_cred_def) - - if 'rev_reg_id' in item and item['rev_reg_id'] is not None: - # Get Revocation Definitions and Revocation Registries - logger.info("\"{}\" -> Get Revocation Definition from Ledger".format(actor)) - get_revoc_reg_def_request = await ledger.build_get_revoc_reg_def_request(_did, item['rev_reg_id']) - - get_revoc_reg_def_response = \ - await ensure_previous_request_applied(pool_handle, get_revoc_reg_def_request, - lambda response: response['result']['data'] is not None) - (rev_reg_id, revoc_reg_def_json) = await ledger.parse_get_revoc_reg_def_response(get_revoc_reg_def_response) - - logger.info("\"{}\" -> Get Revocation Registry from Ledger".format(actor)) - if not timestamp: timestamp = item['timestamp'] - get_revoc_reg_request = \ - await ledger.build_get_revoc_reg_request(_did, item['rev_reg_id'], timestamp) - get_revoc_reg_response = \ - await ensure_previous_request_applied(pool_handle, get_revoc_reg_request, - lambda response: response['result']['data'] is not None) - (rev_reg_id, rev_reg_json, timestamp2) = await ledger.parse_get_revoc_reg_response(get_revoc_reg_response) - - rev_regs[rev_reg_id] = {timestamp2: json.loads(rev_reg_json)} - rev_reg_defs[rev_reg_id] = json.loads(revoc_reg_def_json) - - return json.dumps(schemas), json.dumps(cred_defs), json.dumps(rev_reg_defs), json.dumps(rev_regs) - - -if __name__ == '__main__': - run_coroutine(run) - time.sleep(1) # FIXME waiting for libindy thread complete